Commit Graph
453 Commits
Author SHA1 Message Date
weichenandCursor 89acd16ca5 Refuse a second SQLite service before migration
Why: Two processes opening the same SQLite file both migrate and reconcile, so the second one seals the first one's live runs. The activity lock is taken before open, and durability settings are read back on the application connection.
Evidence: SELF go test ./internal/instanceguard ./internal/store ./internal/app (filtered T8 cases) on feature/u8-sqlite-instance-guard. PG durability readback is NOT_RUN locally; Dev CI test-backend-pg is the GATE.
Impact: SQLite serve and migrate share one non-blocking flock. A replaced database or rebuilt lock file refuses start unless --adopt-instance-guard. PostgreSQL serve refuses when fsync, full_page_writes, or synchronous_commit is off.
Refs: docs/recovery/u8-sqlite-instance-guard.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 13:53:42 +00:00
weichen acabb85e2a Merge pull request 'Publicize identity CLI as pkg/identity for downstream reuse' (#180) from feature/identity-cli-public into main
ci / vet-and-test (push) Successful in 43s
2026-10-12 13:11:27 +00:00
weichen 5623000d51 Publicize identity CLI as pkg/identity for downstream reuse
ci / vet-and-test (pull_request) Successful in 43s
Why: runIdentity lived in cmd/agent-system package main, so downstream
combination binaries (Agent-System-RDM) cannot reuse it and their unknown
subcommands fall into the serve path; the 2026-10-12 rdm1/rdmcand batch
update failures traced back to that capability gap.
Evidence: go test ./pkg/identity/... ok; CGO_ENABLED=0 go build ok;
behavioral probes (usage rc=2, capabilities v1, ensure/verify roundtrip)
recorded in the PR.
Impact: identity semantics unchanged for the base binary; adds
identity capabilities (v1) and usage-on-unknown contract shared by all
products; no storage changes.
Refs: Dev PR #474 (svc.sh candidate gate); user root-cause report
2026-10-12 U1 (shared identity interface).
2026-10-12 13:10:13 +00:00
weichen d1f46c5646 Merge pull request 'Map background card failures to CardFailed with L1 body' (#177) from feature/fast-slow-display-u1 into main
ci / vet-and-test (push) Successful in 49s
Reviewed-on: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/177
2026-10-12 12:16:45 +00:00
weichen 830fea3d3b Merge pull request 'Consult resource-level authorizer on all shared read paths' (#179) from feature/ext8-read-consumption into main
ci / vet-and-test (push) Successful in 47s
2026-10-12 12:09:51 +00:00
weichen 19d4e1ef0d Consult resource-level authorizer on all shared read paths
ci / vet-and-test (pull_request) Successful in 46s
Why: 方案 r1 U9 第二切片——EXT-8b 契约落地后,读面(下载/清单/建会话/SSE 订阅/检索过滤/动作矩阵 read 回落)仍走 V1 owner×project 布尔,资源粒度与受信六要素未消费。
Evidence: 红测(SetResourceAuthorizerV2 未定义编译红,head 见任务收据);绿测三件:六要素查询断言(download=artifact×ID×Owner=alice×ProjectID、list/read=project×pid)、V2 拒绝压过 V1 放行(404 不泄露)、V2 缺席回落 V1(现行兼容);go test ./... 全绿。
Impact: Server 增 ProjectAuthzV2 槽与 SetResourceAuthorizerV2;authorizeSharedResource(六要素受信构造、字段缺失/出错一律 false)替换六处读路径的 V1 直调(artifactContent/getArtifact/sharedArtifactGet=listArtifacts/createConversation/SSE subscribe/检索 allow-fn/authorizeProjectAction read 回落);app.go 组合根注入 authzSlot.AuthorizeResource。V2 未注册时全部回落 V1,RDM 现网行为不变。
Refs: Backend#178;方案 r1 U9/KTD2
2026-10-12 12:08:14 +00:00
weichen 430caa6296 Add red tests for EXT-8b read-path consumption
Why: U9 第二切片——server 读面须按资源级六要素咨询 V2(红:SetResourceAuthorizerV2 未定义)。
Evidence: go vet 编译红(槽位/消费缺失);断言下载/list/建会话三路径查询要素、V2 拒绝压过 V1、V2 缺席回落 V1。
Impact: 仅测试。
Refs: Backend#178;方案 r1 U9
2026-10-12 12:04:43 +00:00
weichen bbe977351d Merge pull request 'Add EXT-8b resource-level authorization contract' (#178) from feature/ext8-resource-authz-v2 into main
ci / vet-and-test (push) Successful in 45s
2026-10-12 11:45:35 +00:00
weichen 0270b40197 Add EXT-8b resource-level authorization contract
ci / vet-and-test (pull_request) Successful in 45s
Why: 方案 r1 U9 首切片——V1(owner×project 布尔)无法表达资源粒度判定,读面(下载/列表/检索/模型上下文)需要执行端按资源咨询下游。
Evidence: 红:resource_authz_v2_test.go 编译红(ResourceAuthzQuery/V2 未定义);绿:pkg/extension surface 棘轮(2.10.0)+ internal/app 槽位测试(V2 咨询/V1 回落/字段缺失拒/error fail-closed/首注册者生效/compiled 拒绝);go test ./... 全绿(收据 /tmp/be-v2-test.txt)。
Impact: 公开面新增 ResourceAuthzQuery/ResourceAuthorizerV2/Registry.RegisterResourceAuthorizerV2;projectAuthz 增 V2 槽(AuthorizeResource:V2 优先、V1 兼容回落、受信字段缺失=拒);compiledRegistry fail-closed 拒绝声明式注册;读路径消费接线(server 5 处 authorizeSharedProject 升级)留待下一切片。
Refs: 方案 r1 U9/KTD2;RDM EXT-8 现有消费者(hostcaps/projectAuthz)
2026-10-12 11:44:00 +00:00
weichenandCursor 4d48abaa8c Map background card failures to CardFailed with L1 body
ci / vet-and-test (pull_request) Successful in 55s
Why: Stop showing raw task text as progress and stop lighting the
done lamp on failed background runs (U1 whitelist).
Evidence: go test ./internal/runmgr/ -count=1
Impact: create/promote/finish card bodies; material queue status text.
Refs: fast-slow-channel-display-u1-plan W2; Core ba289e7

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 07:43:31 +00:00
weichen 5e8ada727c Wait on CardDone and materialActive release in lifecycle test (#176)
ci / vet-and-test (push) Successful in 1m16s
2026-10-12 06:32:43 +00:00
weichenandCursor c963347e52 Wait on CardDone and materialActive release in lifecycle test
ci / vet-and-test (pull_request) Successful in 46s
Why: TestMaterialIntakeAttachmentOnlyLifecycle flaked when waiting on
systemTexts; deliverNotices runs before defer materialKeyRelease, so
done-dedup still saw the in-memory key and returned pending.
Evidence: go test ./internal/runmgr/ -run TestMaterialIntakeAttachmentOnlyLifecycle -count=20
Impact: Aligns the wait with materialExisting gates; no production change.
Refs: fix/material-intake-lifecycle-flake

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 06:31:43 +00:00
weichen dcc180dcad Merge pull request 'Add agent_system_identity DB marker (U1 I3)' (#170) from feature/recovery-u1-db-identity into main
ci / vet-and-test (push) Successful in 48s
Reviewed-on: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/170
2026-10-12 05:35:11 +00:00
weichenandCursor e7b70c24f8 Renumber agent_system_identity to v27 after login_keys took v26
ci / vet-and-test (pull_request) Successful in 42s
Why: main #171 claimed migration v26; rebase conflict required
bumping the U1 I3 table and completing copyOrder for both new tables.
Evidence: go test ./internal/store/ ./cmd/storage-migrate/ -run
'SystemIdentity|CopyOrder'
Impact: migrate v27; copyOrder += login_keys + agent_system_identity.
Refs: Backend PR #170; conflict with main 1d9e8f4

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 05:04:16 +00:00
weichenandCursor dcd5445d61 Include agent_system_identity in storage-migrate copyOrder
Why: TestCopyOrderCoversAllFixtureTables fails when new schema tables
are omitted from the migrate tool inventory.
Evidence: go test ./cmd/storage-migrate/ -run CopyOrder
Impact: copyOrder gains agent_system_identity (no FK deps).
Refs: U1 I3; Backend PR #170

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 05:03:45 +00:00
weichenandCursor e046bbd15c Add agent_system_identity marker with ensure/verify CLI
Why: U1 I3 needs a DB-side instance identity anchor matching
manifest.instance_id so wrong/missing DB blocks startup (I4).
Evidence: go test ./internal/store/ ./internal/app/; CLI smoke
ensure/verify on SQLite temp dir.
Impact: migration v26; store Ensure/Verify; identity subcommand;
serve checks AGENT_SYSTEM_INSTANCE_ID when set.
Refs: docs/recovery/u1-identity-manifest.md §5.2; Dev feature/recovery-u1-db-identity

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 05:03:45 +00:00
weichen 1d9e8f4a79 Merge pull request 'Add one-time login keys, restricted sessions, and OpenExisting' (#171) from feature/svc-deploy-u4-login-key into main
ci / vet-and-test (push) Failing after 43s
Reviewed-on: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/171
2026-10-12 05:00:47 +00:00
weichen 52d75fd931 Merge pull request 'Flatten surface action data into command params' (#174) from fix/surface-action-flatten-data into main
ci / vet-and-test (push) Successful in 47s
2026-10-12 04:16:41 +00:00
weichenandCursor ed443ed3f6 Flatten surface action data into command params
ci / vet-and-test (pull_request) Successful in 47s
Why: system.intent ParamsSchema requires top-level text, but
SubmitAction only nested values under data, so button intent always
rejected missing text during prod acceptance.
Evidence: go test ./internal/surfacesvc/ -run TestSubmitActionFlattensDataIntoParams
Impact: B-class intent and other schema-required params work via actions;
submit still receives nested data.
Refs: GenUI prod deploy acceptance; fix track

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 04:16:34 +00:00
weichen c7b30d2109 Merge pull request 'Guard nil confirm card in surface action dispatcher' (#173) from fix/surface-action-nil-card into main
ci / vet-and-test (push) Successful in 43s
2026-10-12 04:08:58 +00:00
weichenandCursor 4352f368cb Guard nil confirm card in surface action dispatcher
ci / vet-and-test (pull_request) Successful in 44s
Why: Committed button actions with no HITL card panicked on
resp.Card.ID during prod acceptance (nil pointer).
Evidence: go test ./internal/app/ ./internal/surfacesvc/; prod panic stack
Impact: B-class help/intent and C-class submit return without crash.
Refs: GenUI prod deploy acceptance

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 04:08:47 +00:00
weichen cb386023d0 Merge pull request 'Keep auto-present reminders synchronous to avoid run races' (#172) from feature/genui-auto-trigger-optin into main
ci / vet-and-test (push) Failing after 58s
2026-10-12 03:57:11 +00:00
weichenandCursor 9bd0aae9d8 Keep auto-present reminders synchronous to avoid run races
ci / vet-and-test (pull_request) Successful in 56s
Why: Async notice-run delivery raced with test teardown and in-flight
conversation runs (database closed / material lifecycle flakes).
Evidence: go test ./internal/runmgr/ -run Material
Impact: Reminders append as system messages only; material path still
inlines into startNoticeRun.
Refs: Dev PR #425 CI test-pg failure

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:56:59 +00:00
weichenandCursor 47463a9623 Align admin account e2e with must-change password gate
ci / vet-and-test (pull_request) Failing after 1m25s
Why: U4 middleware restricts must_change sessions to me/password/logout;
the legacy e2e expected admin create before first password change.
Evidence: go test ./internal/store/ ./internal/server/ ./internal/app/
Impact: TestAdminAccountFlow matches set-password + reloginRequired.
Refs: docs/svc-deploy/u4-one-time-login-key.md §5–6

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:54:59 +00:00
weichen b6ea1a5910 Merge pull request 'Drop runmgr import of genui to satisfy package boundaries' (#169) from feature/genui-auto-trigger-optin into main
ci / vet-and-test (push) Successful in 1m1s
2026-10-12 03:48:28 +00:00
weichenandCursor 41df7ae56f Drop runmgr import of genui to satisfy package boundaries
ci / vet-and-test (pull_request) Successful in 1m10s
Why: lint-boundaries forbids backend/runmgr -> backend/genui; keep the
auto trigger as an injected interface with local reminder text.
Evidence: bash scripts/lint-boundaries.sh
Impact: No behavior change; wiring still via app.SetGenUIAuto(genui.NewAuto).
Refs: architecture boundaries

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:48:10 +00:00
weichen 9b69117bea Merge pull request 'Add Generative UI auto-present opt-in with budget and cooldown' (#168) from feature/genui-auto-trigger-optin into main
ci / vet-and-test (push) Failing after 1m4s
2026-10-12 03:45:03 +00:00
weichenandCursor 6ff7fa9bd7 Add Generative UI auto-present opt-in with budget and cooldown
ci / vet-and-test (pull_request) Successful in 1m4s
Why: Known-boundary follow-up: owner opt-in auto page suggestions on
semantic task events without self-trigger from surface revisions.
Evidence: go test ./internal/genui/ ./internal/runmgr/ ./internal/settings/ ./internal/app/
Impact: Default-off settings key; material/plan/todo/document hooks nudge present.
Refs: docs/proposals/2026-10-12-generative-ui-auto-trigger.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:44:47 +00:00
weichenandCursor 1ba7225e83 Add one-time login keys, restricted sessions, and OpenExisting
ci / vet-and-test (pull_request) Failing after 56s
Why: passwordless activation/recovery must redeem only into a
set-password session; account ops must not create empty stores.
Evidence: SELF go test store/server login-key and OpenExisting cases.
Impact: auth middleware gates; CLI user create defaults to activate key.
Refs: docs/svc-deploy/u4-one-time-login-key.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:44:16 +00:00
weichen d1b5a94d15 Merge pull request 'Whitelist B-class surface actions for help and intent' (#167) from feature/genui-bclass-help-intent into main
ci / vet-and-test (push) Successful in 1m3s
2026-10-12 03:23:57 +00:00
weichen ba619747c5 Merge authoritative main into the B-class branch
ci / vet-and-test (pull_request) Successful in 1m12s
2026-10-12 03:23:43 +00:00
weichenandCursor 5e0077dc11 Whitelist B-class surface actions for help and intent
ci / vet-and-test (pull_request) Successful in 48s
Why: Generative UI U5 left the B-class action allowlist empty; owner
authorized first entries builtin.help and system.intent.
Evidence: go test ./internal/genui/ ./internal/surfacesvc/ ./internal/server/
Impact: Surface buttons may bind help/intent; button-entrance intent
matches only and does not nest-dispatch write commands.
Refs: docs/proposals/2026-10-12-generative-ui-bclass-help-intent.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 03:18:57 +00:00
weichen b160515905 Merge pull request 'Unwrap item-style spec wrappers, pair bare table cells, let subagents present pages' (#166) from feature/genui-spec-repair into main
ci / vet-and-test (push) Successful in 55s
Reviewed-on: https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/166
2026-10-12 03:09:35 +00:00
weichen 9ec9f9a010 Merge pull request 'Harden cross-instance HITL/cancel command paths and add disk-full rejection tests (U7)' (#164) from feature/u7-load-fault-release into main
ci / vet-and-test (push) Successful in 59s
2026-10-12 03:09:03 +00:00
weichen 58598df095 Merge remote-tracking branch 'origin/main' into feature/u7-load-fault-release
ci / vet-and-test (pull_request) Successful in 51s
2026-10-12 03:07:33 +00:00
weichen 3d850a282f Unwrap item-style spec wrappers, pair bare table cells, let subagents present pages
ci / vet-and-test (pull_request) Successful in 1m4s
Why: MiniMax-M3 emits XML-RPC-style {"item": ...} single-key wrappers on
array fields (kv/cells/items), bare scalar table cells, and page
submission delegated to the general sub-agent had no generative-ui
tool - observed live on dev (events seq 1395/1396/2171) where every
present with kv/table/list nodes failed invalid-spec and the delegated
retry reported the tool missing.

Evidence: red test reproducing the exact production error
(.nodes.1.kv of type [][2]string) goes green after the repair; full
genui/prompts/runtime/runmgr suites pass (SELF); mismatched-length
cells stay untouched by a dedicated guard test.

Impact: generative-ui pages with kv/table/list nodes save successfully
again; the general sub-agent can submit pages (tool resolves only when
the plugin exposes it, so absent plugins are unaffected).

Refs: dev task card feature/genui-spec-repair; dev conversation
激活验证-1012.
2026-10-12 03:03:26 +00:00
weichen a80d3c3359 Merge pull request 'Declare admin-zone sections from compiled plugins (surface 2.9.0, WP3-I3)' (#165) from feature/adminzone-plugin-sections into main
ci / vet-and-test (push) Successful in 46s
2026-10-12 02:39:56 +00:00
weichen 1719b5f668 Merge authoritative main into the admin-zone branch
ci / vet-and-test (pull_request) Successful in 49s
2026-10-12 02:37:57 +00:00
weichen 62bfc6068a Declare admin-zone sections from compiled plugins (surface 2.9.0)
ci / vet-and-test (pull_request) Successful in 46s
Why: the admin zone could not host plugin-declared partitions - KTD4
requires the RDM audit partition to be reachable by RDM domain admins and
base superadmins without hardcoding RDM into the base AdminZone.
Evidence: go test ./internal/app ./internal/server ./pkg/extension green
incl. new admin-zone recording/endpoint tests; surface snapshot test
green after surface.txt update; CI (Dev composite) is authoritative.
Impact: extension surface 2.8.0 -> 2.9.0 (Registry.AddAdminZone +
AdminZoneSpec, fail-closed on invalid specs); applyCompiled records
declarations into the plugin summary; new authenticated GET
/api/admin-zone/sections returns the flattened, ordered declaration list.
Entry visibility stays metadata-only - data capability remains enforced
by each section's own command surface (fail-closed).
Refs: WP3-I3/KTD4; task card feature-adminzone-plugin-sections.
2026-10-12 02:28:51 +00:00
weichen 0a7413903d Harden cross-instance HITL/cancel command paths and add disk-full rejection tests (U7)
ci / vet-and-test (pull_request) Successful in 48s
Why: two-process HTTP acceptance (Dev tests/integration/multi-instance, added in
the matching Dev-side change) exposed three real cross-instance defects that the
U5 library-level tests bypassed via direct Manager calls, plus the U7 fault
matrix needs explicit disk-full rejection evidence.
Evidence: go test ./... green on SQLite and real PG (AGENT_PG_TEST_DSN);
new regressions TestCrossInstanceResolveDoesNotSettleCard (runmgr, PG-gated),
TestUploadRejectsCleanlyWhenObjectDirUnwritable and
TestArtifactOverwriteRejectsCleanlyWhenObjectDirUnwritable (server).
Impact: ResolveHITL no longer settles the card when the run executes on another
instance (command-bus fallback stays available); cancelRun enqueues the command
with the real conversation id and no longer reports a false local success;
object-store failures now provably leave zero DB/object residue.
Refs: collaboration storage proposal U7 (sections 3/5/7); task card
feature/u7-load-fault-release.
2026-10-12 02:28:48 +00:00
weichen 696ef15168 Merge pull request 'Add project-level surface aggregation and task-phase guidance (U6)' (#163) from feature/generative-ui-u6 into main
ci / vet-and-test (push) Successful in 53s
2026-10-12 02:12:59 +00:00
weichen add1fbb045 Add project-level surface aggregation and task-phase guidance (U6)
ci / vet-and-test (pull_request) Successful in 54s
Why: U6 extends pages from conversations into the task/project
workspace - surfaces aggregate across conversations under the owner's
project scope (project resolved authoritatively from the conversation
row, never self-reported by the model), and the catalog guidance now
organizes pages by task phase (requirements/execution/acceptance)
while stating that task facts come only from real task records.

Evidence: build/vet clean; surfacesvc suite green incl. the new
project-aggregation test (owner isolation, cross-owner zero, history
retained post-disable); genui/store suites green.

Impact: New endpoint GET /api/projects/{id}/surfaces; Submit resolves
project from conversation; catalog text guidance. Existing endpoints
unchanged.

Refs: proposal r2 U6; Dev task feature/generative-ui-u6
2026-10-12 02:12:42 +00:00
weichen d835ad7466 Merge pull request 'List compiled plugins in /api/plugins (WP3-I4)' (#162) from feature/plugins-compiled-listing into main
ci / vet-and-test (push) Successful in 45s
2026-10-12 01:59:21 +00:00
weichen 9aa51e5250 List compiled plugins in /api/plugins
ci / vet-and-test (pull_request) Successful in 47s
Why: compiled-in plugins (generative-ui, rdm) never appeared in the admin
plugins list: GET /api/plugins only scanned the directory host, so binary-
level capabilities were invisible to operators (user-reported gap).
Evidence: go test ./internal/app/ ./internal/server/ green locally incl.
new TestApplyCompiledRecordsSummary and TestListPluginsMergesCompiled;
CI (make test) is authoritative.
Impact: applyCompiled records each plugin's registered commands/intents/
skills into a summary handed to the server; /api/plugins merges synthesized
inproc entries (backend.mode=inproc, apiVersion=extension surface version,
provides from the registration record). Directory entries win on id
collision. No public extension-surface change.
Refs: WP3-I4; task card feature-plugins-compiled-listing.
2026-10-12 01:44:56 +00:00
weichen e49f165d0b Merge pull request 'Material-intake guaranteed loop: deterministic spawn, choice chain, queue, cardflow on (Dev task feature/material-intake-flow)' (#161) from feature/material-intake-flow into main
ci / vet-and-test (push) Successful in 42s
2026-10-11 17:47:56 +00:00
weichen 409390fff1 Merge authoritative main into the task branch
ci / vet-and-test (pull_request) Successful in 42s
2026-10-11 17:37:51 +00:00
weichen 4c637d4071 Merge pull request 'Repair object-shaped children maps into arrays in page specs' (#160) from fix/genui-children-repair into main
ci / vet-and-test (push) Successful in 49s
2026-10-11 16:57:51 +00:00
weichen 432b916cba Repair object-shaped children maps into arrays in page specs
ci / vet-and-test (pull_request) Successful in 52s
Why: Live E2E on the dev instance - the model keyed section children
as an object map (children.item.*), the strict decode rejected it, and
the page fell back to a file artifact; the guidance fix made the model
call present, this closes the remaining shape gap.

Evidence: genui suite green incl. the reproduction case; post-deploy
E2E rerun recorded in the Dev task.

Impact: Repair strategy only; validation unchanged.

Refs: Dev task fix/genui-page-visibility (E2E follow-up)
2026-10-11 16:57:48 +00:00
weichen 16ed7b281b Add background queue for system tasks and flip ui.cardflow default on
Why: at the 3-per-conversation cap the guaranteed material task was dropped silently, and long deliverables stayed in chat because cardflow defaulted off (user ruling 2026-10-11).
Evidence: new queue lifecycle test (queued card, hard-reject for model path, FIFO start on release, card promote) passes; full go test ./... exit 0 (local, SELF).
Impact: queueable system spawns create a queued progress card at capacity and start FIFO when a slot frees (memory-only queue; restart limitation noted); model delegate_task still hard-rejects; ui.cardflow default true (EffectNewRun).
Refs: Dev task .task/feature-material-intake-flow.md I3.
2026-10-11 16:56:59 +00:00
weichen 42867aabf4 Add deliverable-choice chain: confirm_choice tool, notice contract, backstops
Why: after material organization completes, weak models report and end the turn without offering the user a choice of formal deliverables, and even after a user picks one the model may close the turn without starting the background task.
Evidence: new tests (notice-choice chain, deliverable backstop, free-input path, invalid args, notice contract) pass; full go test ./... exit 0 (local, SELF).
Impact: new confirm_choice tool issues a HITL choice card and routes the answer into a hard delegate instruction; material notices instruct the model to report then offer choices; stop hook adds two one-shot backstops (choice not offered in material notice runs; choice made but no background delegation).
Refs: Dev task .task/feature-material-intake-flow.md I2.
2026-10-11 16:53:53 +00:00