@staix/agent-hub 0.34.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +35 -6
  3. package/docs/adding-an-ai-tool.md +2 -2
  4. package/docs/addons/claude-mem.md +4 -4
  5. package/docs/addons/open-code-review.md +1 -1
  6. package/docs/agent-notes/README.md +6 -0
  7. package/docs/agent-notes/adapters.md +9 -5
  8. package/docs/agent-notes/budget.md +1 -1
  9. package/docs/agent-notes/bus.md +1 -1
  10. package/docs/agent-notes/daemon.md +4 -3
  11. package/docs/agent-notes/local-worker.md +1 -1
  12. package/docs/agent-notes/models.md +2 -0
  13. package/docs/agent-notes/tasks.md +1 -1
  14. package/docs/agent-notes/tests.md +5 -0
  15. package/docs/design/adapters.md +110 -2
  16. package/docs/design/agent-hub-architecture.md +63 -1
  17. package/docs/design/agent-hub.md +6 -0
  18. package/docs/design/bus.md +18 -0
  19. package/docs/design/execution-reference.md +146 -0
  20. package/docs/design/task-board.md +10 -0
  21. package/docs/dogfood.md +33 -12
  22. package/docs/events.md +38 -20
  23. package/docs/memory.md +21 -7
  24. package/docs/operations.md +539 -24
  25. package/docs/quickstart.md +12 -4
  26. package/docs/research.md +71 -13
  27. package/docs/roles.md +1 -1
  28. package/docs/sdlc.md +9 -7
  29. package/docs/security.md +87 -11
  30. package/docs/smoke.md +14 -0
  31. package/docs/specs/2026-09-19-agent-hub-design.md +8 -3
  32. package/docs/verification/2026-11-07-compat-python-startup-1248.md +51 -0
  33. package/docs/verification/2026-11-07-compat-receipt-harness-1248.md +105 -0
  34. package/docs/verification/2026-11-07-compat-receipt-producers-1248.md +96 -0
  35. package/docs/verification/2026-11-07-compat-workflow-1248.md +94 -0
  36. package/docs/verification/2026-11-07-daemon-startup-1232.md +169 -0
  37. package/docs/verification/2026-11-07-jcode-receipt-reconstruction-1248.md +118 -0
  38. package/docs/verification/2026-11-07-kimi-delayed-usage.md +34 -0
  39. package/docs/verification/2026-11-07-kimi-review-watch-1284.md +115 -0
  40. package/docs/verification/2026-11-08-agy-1.5.3.md +96 -0
  41. package/docs/verification/2026-11-08-agy-acp-t0.md +56 -0
  42. package/docs/verification/2026-11-08-hub-visual-1058.md +161 -0
  43. package/docs/verification/2026-11-08-jcode-0991-model-setter-1317.md +143 -0
  44. package/docs/verification/2026-11-08-kimi-252-model-setter-1317.md +137 -0
  45. package/docs/verification/2026-11-08-kimi-tui-completion-1282.md +45 -0
  46. package/docs/verification/2026-11-08-kimi-wire-yield-1283.md +31 -0
  47. package/docs/verification/2026-11-08-live-model-override-1317.md +250 -0
  48. package/docs/verification/2026-11-08-qwen-0269-acp.md +138 -0
  49. package/docs/verification/2026-11-08-qwen-0269-model-setter-1317.md +91 -0
  50. package/docs/verification/2026-11-09-0.35.0.md +129 -0
  51. package/docs/verification/2026-11-09-headless-records-1320.md +157 -0
  52. package/docs/verification/claude-permission-transport-native.py +10 -3
  53. package/docs/verification/claude-shell-wrapper-native.py +8 -8
  54. package/docs/verified.json +245 -15
  55. package/package.json +3 -3
  56. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  57. package/plugins/agent-hub/kimi-hook.js +20397 -0
  58. package/plugins/agent-hub/kimi-review-policy-worker.js +217 -0
  59. package/plugins/agent-hub/server.js +2701 -664
  60. package/scripts/check-docs.mjs +12 -1
  61. package/src/adapters/acp-model-policy.ts +56 -0
  62. package/src/adapters/acp.ts +175 -5
  63. package/src/adapters/agy/entry.ts +8 -5
  64. package/src/adapters/agy/hooks.ts +65 -15
  65. package/src/adapters/channel-peer.ts +33 -1
  66. package/src/adapters/claude-implementer.ts +16 -3
  67. package/src/adapters/codex-appserver.ts +118 -8
  68. package/src/adapters/codex-review-isolation.ts +3 -1
  69. package/src/adapters/compat.ts +11 -6
  70. package/src/adapters/definitions/builtin-metadata.ts +8 -1
  71. package/src/adapters/definitions/native-cli-entry-kimi.ts +76 -7
  72. package/src/adapters/definitions/native-cli-preview-common.ts +2 -2
  73. package/src/adapters/definitions/native-cli-preview-kimi.ts +9 -2
  74. package/src/adapters/definitions/reviewer-variants.ts +3 -1
  75. package/src/adapters/kimi-review-policy-worker.js +2 -0
  76. package/src/adapters/kimi-review-policy-worker.ts +85 -0
  77. package/src/adapters/kimi-review-policy.ts +68 -0
  78. package/src/adapters/kimi-review.ts +41 -41
  79. package/src/adapters/kimi-tui-facts.ts +153 -0
  80. package/src/adapters/kimi-wire-usage.ts +33 -8
  81. package/src/adapters/local-worker.ts +59 -20
  82. package/src/adapters/model-token.ts +3 -0
  83. package/src/adapters/pi.ts +27 -5
  84. package/src/adapters/registry-types.ts +34 -3
  85. package/src/adapters/registry.ts +1 -0
  86. package/src/adapters/reviewer-policy-watch.ts +86 -0
  87. package/src/adapters/reviewer-print.ts +80 -18
  88. package/src/cli/agents.ts +1 -1
  89. package/src/cli/facts-hook.ts +4 -2
  90. package/src/cli/help.ts +3 -2
  91. package/src/cli/identity.ts +3 -0
  92. package/src/cli/kimi-facts-hook.ts +11 -0
  93. package/src/cli/kimi-plugin.ts +157 -0
  94. package/src/cli/main.ts +48 -9
  95. package/src/cli/model.ts +52 -0
  96. package/src/cli/output.ts +23 -1
  97. package/src/cli/reset.ts +1 -1
  98. package/src/cli/status-lines.ts +8 -4
  99. package/src/hub/budget.ts +1 -1
  100. package/src/hub/bus.ts +40 -2
  101. package/src/hub/code-facts.ts +10 -3
  102. package/src/hub/completions.ts +3 -1
  103. package/src/hub/config-apply.ts +2 -1
  104. package/src/hub/control-client.ts +1 -1
  105. package/src/hub/daemon.ts +1050 -106
  106. package/src/hub/deliverable-files.ts +38 -5
  107. package/src/hub/dogfood-profile.ts +1 -1
  108. package/src/hub/envelope.ts +1 -1
  109. package/src/hub/events.ts +28 -18
  110. package/src/hub/execution-lineage.ts +120 -0
  111. package/src/hub/execution-reference.ts +36 -0
  112. package/src/hub/hub-tools.ts +21 -2
  113. package/src/hub/instances.ts +4 -3
  114. package/src/hub/kimi-events.ts +46 -0
  115. package/src/hub/kimi-usage.ts +132 -29
  116. package/src/hub/lifecycle.ts +31 -15
  117. package/src/hub/limits.ts +13 -4
  118. package/src/hub/manager.ts +15 -2
  119. package/src/hub/memory-policy.ts +2 -1
  120. package/src/hub/memory-sync-attestation.ts +54 -0
  121. package/src/hub/memory-sync-state.ts +20 -5
  122. package/src/hub/model-overrides.ts +115 -0
  123. package/src/hub/native-hook-launch.ts +12 -3
  124. package/src/hub/operational-view.ts +2 -2
  125. package/src/hub/peers.ts +27 -0
  126. package/src/hub/permission-mode.ts +1 -1
  127. package/src/hub/person-figures.ts +88 -0
  128. package/src/hub/report.ts +38 -4
  129. package/src/hub/research-dataset.ts +158 -0
  130. package/src/hub/research-memory.ts +68 -0
  131. package/src/hub/research-quality.ts +118 -0
  132. package/src/hub/research-record.ts +279 -0
  133. package/src/hub/research.ts +126 -27
  134. package/src/hub/restart.ts +14 -0
  135. package/src/hub/settings.ts +3 -0
  136. package/src/hub/startup-event-seeds.ts +51 -0
  137. package/src/hub/startup-readiness.ts +65 -0
  138. package/src/hub/startup-timing.ts +38 -0
  139. package/src/hub/tasks.ts +29 -9
  140. package/src/hub/ui.ts +9 -5
  141. package/src/hub/visual-assets.ts +50 -0
  142. package/src/hub/visual.ts +257 -0
  143. package/src/memory/brief.ts +169 -14
  144. package/src/memory/capture.ts +2 -1
  145. package/src/memory/recall.ts +46 -5
  146. package/src/memory/record-provenance.ts +82 -0
  147. package/src/memory/records.ts +116 -0
  148. package/src/models/route/adec.ts +190 -0
  149. package/src/models/route/config.ts +37 -3
  150. package/src/models/route/decision-evidence.ts +83 -0
  151. package/src/models/route/decision.ts +143 -0
  152. package/src/models/route/runtime.ts +13 -6
  153. package/src/ui/index.html +134 -6
  154. package/src/ui/plugin.ts +65 -4
  155. package/templates/AGENTS.block.md +1 -1
  156. package/templates/config.json +1 -1
  157. package/templates/profiles/general.json +1 -1
  158. package/templates/profiles/research.json +1 -1
  159. package/templates/profiles/writing.json +1 -1
@@ -0,0 +1,34 @@
1
+ # Kimi delayed usage and attribution receipt (#1281)
2
+
3
+ ## Scope and isolation
4
+
5
+ Measured on 2026-11-07 with agent-hub source `a3de35e41ca26614108593b61de5674a960b2b95` plus the #1281 working change, and Kimi Code CLI 2.5.2. ACP initialization served protocol version 1 and agent version 2.5.2. The wire log declared protocol version 1.5.
6
+
7
+ The measured process had a new disposable cwd, `HOME`, `KIMI_CODE_HOME`, `TMPDIR` and `XDG_CONFIG_HOME`. Its generated native config retained only the installed managed provider and model settings, with hooks and telemetry disabled. The installed account's credential/oauth directories and device identity were symlinked into the disposable native home without printing their contents. No personal project or prior session was read. No credential or plan-quota probe was made.
8
+
9
+ Each turn was one ordinary no-tool prompt. Raw prompts, answers, session identifiers and transcript paths are not reproduced here and the disposable directories were removed. The measurements below contain field names, counts, timing relationships and attribution only.
10
+
11
+ ## Native row timing and attribution
12
+
13
+ `counted` means `inputOther + inputCacheCreation + output`, the hub ceiling rule. `row within turn` compares the native row time with the captured hub turn interval. `usage after turn_end` compares the hub's `usage` event time with its immutable `turn_end` event.
14
+
15
+ | Attempt | Counted | Cache reads | Row within turn | Usage after turn_end | Attribution |
16
+ | --- | ---: | ---: | --- | --- | --- |
17
+ | 1 | 5,518 | 23,552 | yes | no | `delivery`, task 1281 |
18
+ | 2 | 237 | 28,928 | yes | no | `delivery`, task 1281 |
19
+ | 3 | 322 | 28,928 | yes | no | `delivery`, task 1281 |
20
+ | 4 | 153 | 28,928 | yes | no | `delivery`, task 1281 |
21
+ | 5 | 240 | 28,928 | yes | no | `delivery`, task 1281 |
22
+ | 6 | 325 | 28,928 | yes | no | `delivery`, task 1281 |
23
+ | 7 | 152 | 28,928 | yes | no | `delivery`, task 1281 |
24
+ | 8 | 240 | 28,928 | yes | no | `delivery`, task 1281 |
25
+
26
+ Every native row time fell inside its captured turn interval. Every row was collected before `turn_end`, and the `tokens` event carried the same `delivery`, task 1281 attribution and counted value as the `usage` event. This verifies current native row-time semantics and immediate attribution on Kimi 2.5.2.
27
+
28
+ ## AC8 verdict
29
+
30
+ **AC8 is VERIFIED as amended on 2026-11-08.** The amended criterion accepts current native row-time and attribution evidence plus the production-timer delayed fixture when no delayed native row occurs. Zero of the eight ordinary turns produced a row after `turn_end`, so the immediate rows above are not presented as delayed evidence. The original delayed-native-only leg remains unobserved on Kimi 2.5.2.
31
+
32
+ The production delayed path is covered separately by `test/daemon-kimi-delayed-usage.test.ts`: its real unreferenced 250 ms timer collects a post-result row without another turn, updates `usage`, `tokens`, the budget and roll-up, and leaves `turn_end` unchanged. The A/B test fires the injected scheduler while task B is open and proves that A's delayed row keeps A's attribution, increments no turn total, and that an ambiguous timestamp is `unattributed`. These fixtures establish the #1281 behavior, not a current native delay.
33
+
34
+ The earlier native delay observed on Kimi 2.3.1 remains recorded in [2026-10-25-kimi-usage-ac11.md](2026-10-25-kimi-usage-ac11.md). A future version that again produces a post-result row should repeat this receipt's ordinary-turn leg.
@@ -0,0 +1,115 @@
1
+ # Kimi review policy watching (#1284)
2
+
3
+ Date: 2026-11-07. Task #785. These are model-free private fixtures on dgx02,
4
+ Linux x64, Bun 1.4.2. The production Kimi preparation and reviewer peer are used
5
+ with an owned fake print/version command and synthetic OAuth files. No real Kimi
6
+ CLI, provider, account, credential or model interaction is claimed. COMPAT and
7
+ machine trust are unchanged.
8
+
9
+ The historical baseline was measured before production optimization, at
10
+ `4daaa842db4035c5504caff6867445b47b7c1be5`. It drives the actual old
11
+ `ReviewerPrintPeer` interval and complete `current()` fence. Input is exactly
12
+ 1048576 framed bytes; the generated agent file is 1048868 bytes.
13
+
14
+ The post-change samples below are bound to
15
+ `dedbf4974d2a91ebd96623f4bd4a1ca04c06ac47`. The worker mode uses the real
16
+ policy worker and new controller. Inline-reference mode uses the same full fence
17
+ on the main thread under the new controller; it is a comparator, not another
18
+ measurement of the historical interval.
19
+
20
+ ## Measurements
21
+
22
+ Values are milliseconds. Authority samples are eight synchronous `reviewToken()`
23
+ calls. Periodic samples are three checks per mode, after preparation has already
24
+ read the private files. These are small warm-fixture samples, not a cold-start,
25
+ production latency regression, p99 estimate or general speedup claim.
26
+
27
+ | Mode | Authority mean / max | Ordinary check mean / max | Ordinary start-to-start |
28
+ | --- | ---: | ---: | --- |
29
+ | Historical inline interval | 1.631 / 3.011 | 1.657 / 1.776 | 100.259, 100.214 |
30
+ | Worker | 1.709 / 3.937 | 2.748 / 2.998 | 100.362, 99.739 |
31
+ | New-controller inline reference | 1.613 / 3.095 | 1.725 / 1.877 | 99.857, 100.511 |
32
+
33
+ The worker check includes IPC and completion overhead. Work is moved off the main
34
+ event loop; the filesystem/hash work is not eliminated. Synchronous authority
35
+ checks remain synchronous and retain their separate measured cost.
36
+
37
+ A second phase adds a synthetic 150 ms hold, separately recorded from the actual
38
+ full-check cost. The worker is held inside its real request path until an
39
+ independent requester receives a real loopback control response. The fixture
40
+ checks that the underlying check has not completed prematurely. Inline modes
41
+ block the main thread; the independent requester confirms its request was sent.
42
+ The control server shares the actual reviewer's process/event loop. This is a
43
+ causal control fixture, not an installed daemon's response-time trace.
44
+
45
+ | Mode | Slow start-to-start | Causal shared-counter order |
46
+ | --- | --- | --- |
47
+ | Historical interval | 160.648, 152.533 | check start 1, check end 2, control dispatch 3, response 5 |
48
+ | Worker | 165.924, 154.460 | check start 1, control dispatch 2, response 3, check end 4 |
49
+ | New-controller inline reference | 162.538, 153.221 | check start 1, check end 2, control dispatch 3, response 5 |
50
+
51
+ Every sample's maximum concurrent checks is one. The first synthetic sample can
52
+ include requester coordination in addition to the nominal hold; it is not
53
+ reported as production hash cost. Assertions use ordering, not a host-specific
54
+ latency threshold. A fake monotonic clock separately proves that a check started
55
+ at 100 and completed at 350 schedules an immediate overdue check at 350, then a
56
+ fast completion schedules 400, without replaying every missed tick.
57
+
58
+ The full numeric baseline output is retained in the workspace's
59
+ `scratchpad/temp/task785-baseline-4daaa842.log`; the benchmark command emits the
60
+ raw arrays, ordering counters and cleanup flags. The post-change command is
61
+ `bun scripts/benchmarks/kimi-review-watch-1284.ts`, with `--inline-reference`
62
+ selecting its comparator. Each observed run confirmed peer stop, requester join,
63
+ profile removal and unchanged synthetic source files; post-change runs also
64
+ confirmed policy-worker join.
65
+
66
+ ## Validation and ownership
67
+
68
+ Both synchronous authority checks and the worker call the same complete
69
+ filesystem checker: lexical and physical cwd ancestors, native source identity,
70
+ executable metadata, source configuration hash, all three private-file hashes and
71
+ all native/private auth targets. The parent adds abort/cleanup guards before and
72
+ after an asynchronous check. No successful asynchronous result is cached as
73
+ verdict or task-MCP authority. Version probing, fresh private homes, the two-tool
74
+ allowlist and OAuth-lock teardown are unchanged.
75
+
76
+ The worker receives a closed immutable projection of expected paths, metadata
77
+ and fingerprints, not serialized task facts, configuration contents or inherited
78
+ environment. It still reads the bounded files to hash them. Requests are
79
+ serialized and replies carry only a monotonic request ID and boolean. Error,
80
+ output, protocol and early boot failures poison the probe, including before the
81
+ first periodic tick; error text is not forwarded.
82
+
83
+ Each child/review sequence owns its watcher. Stop cancels scheduling before
84
+ joining a blocked check, initiates worker termination even if native stop fails,
85
+ and joins before profile deletion or confirmed input cleanup. Failed joins keep
86
+ the owner/profile and busy state until an explicit stop retry. A late result
87
+ cannot settle or revive a subsequent review, even for the same task and batch.
88
+ Worker progress never touches the native inactivity watchdog.
89
+
90
+ The source worker has a JS wrapper. The plugin has a separately generated,
91
+ self-contained sidecar with the same basename. A fixture copies that sidecar
92
+ alone into a directory containing a space and executes it without a source tree
93
+ beside it. Both generated assets use the pinned Bun after a worktree-local frozen
94
+ install; neither is hand edited.
95
+
96
+ At `dedbf4974d2a91ebd96623f4bd4a1ca04c06ac47`, dgx02 typecheck and 75 tests
97
+ across six files passed (514 assertions), followed by both numeric benchmark
98
+ modes. Coverage includes actual workers, empty environment, closed projection,
99
+ cwd/binary/config/auth changes, equal-size restored-mtime content tampering,
100
+ atomic OAuth refresh, stop while blocked, cleanup retries, early failure,
101
+ same-task late results, watchdog and output-limit cleanup. Existing Kimi isolation,
102
+ privacy, two-tool and lifecycle assertions were retained. The one old fake launch
103
+ with `watchCurrent` gained the asynchronous probe required by the new contract.
104
+
105
+ Two earlier fixture failures are not passing evidence: `28b7a07c` stopped at a
106
+ missing MCP-schema `additionalProperties:false`; `f5b5e8e2` passed typecheck and
107
+ 56 tests but four new mtime cases used sub-ms timestamps that `Date` could not
108
+ restore exactly. The corrected fixture initializes exact whole-second timestamps
109
+ before binding; its size, precision and refusal assertions are unchanged.
110
+
111
+ Final canonical/seed/hosted-CI results are recorded at their exact tested heads
112
+ in the PR/task. Inventory discovery was deferred once with exit 75 because three
113
+ remote slots were occupied; no retry loop or local test/index fallback ran. No
114
+ documentation stamp, native version receipt, model-quality claim, merge or tag
115
+ is part of this change.
@@ -0,0 +1,96 @@
1
+ # Antigravity 1.5.3 account-free compatibility receipt
2
+
3
+ Date: 2026-11-08. Task #801, Refs #843. Repeats the [1.4.12 account-free procedure](2026-11-03-agy-1.4.12.md) and its [actual-launcher nonce leg](2026-11-03-agy-1.4.12-launcher-nonce.md).
4
+
5
+ **Decision: add exact 1.5.3 to verified.** All four required account-free legs passed on the same installed executable. The accepted 1.4.x line is unchanged; 1.5.2, 1.5.4 and other 1.5.x versions remain refused without person trust. This is compatibility evidence, not an account/model, permission-mode or headless ACP qualification.
6
+
7
+ ## Exact executable and isolation
8
+
9
+ - Host macOS 27.0.1 arm64, pinned Bun 1.4.2. Native `--version`: 1.5.3. Installed executable SHA-256 `5e4b545bff4a83a93354fc50c54631cf3e8cd02e1a469087af00929f3fdc4d51`, 208,900,592 bytes. No CLI install, update or downgrade was performed.
10
+ - CLI surface used source `4b0d36639d9417b7a810175ed3c9a13d49f429c6`; hooks and actual launcher used `01b87a7cafb35e69403d9500c4136909c3741089` (a receipt-only commit; runtime and committed bundle unchanged). The native evidence precedes the mechanical verified-set change. Frozen dependencies matched agent-mem 0.22.1 and SDK 1.30.0.
11
+ - Fresh 0700 controller roots were outside the actual home. HOME, XDG config/cache/data/state, AGENTHUB_HOME, AMEM_HOME, project, state and TMPDIR were set before hub imports. No real credentials/settings or parent agent/session/Orca markers were copied. Later controllers also started Bun from that fresh root with --no-install; the earlier worktree had no dotenv files.
12
+ - Every agy invocation, including help/version/mcp probes and launcher preflight, used `AGY_CLI_DISABLE_AUTO_UPDATE=1` and Seatbelt. The profile reuses `src/local/sandbox.ts`, then denies typed and canonical actual-home reads/writes. Only exact agy/Bun executables, required code and private fixture paths are allowed; native egress is only the fixture provider and, for the launcher, its own control port. Port 4600 is never used.
13
+ - Positive controls: `/usr/bin/true` and the pinned Bun helper succeed. Opening a named real Gemini config for reading and opening the installed binary with O_WRONLY, without truncation or writes, both fail with Operation not permitted. The provider connection succeeds; a second owned loopback port is denied. These are probe controls, not a claim of ordinary agy confinement.
14
+ - The controller compares the five named real config entries, the binary hash and its directory inventory before and after. Every completed native run matched. It joins owned teardown and checks captured process identities plus private-path survivors; it never signals unknown processes. Observed cleanup is not proof against arbitrary detached helpers.
15
+
16
+ ## CLI surface: passed
17
+
18
+ | Probe | Result |
19
+ | --- | --- |
20
+ | --version | 1.5.3, exit 0 |
21
+ | --help and help | Exit 0; --continue, --conversation, --disable-slash-commands, --input-format, --output-format, --print, --prompt-interactive, --project, --remote-control and --sandbox remain present |
22
+ | --acp and --new | Exit 2 with the expected unknown-flag diagnostic |
23
+ | Subcommands | All twelve historical subcommands remain; acp is also present |
24
+ | mcp list in the empty isolated project | Exit 0, No MCP servers configured |
25
+
26
+ Help is on stderr (3,319 bytes), so the final collector checks both streams. An earlier collector measured stdout alone and did not prove flag presence. CLI log: private scratch `temp/task801-cli-153-streams.log`.
27
+
28
+ ## Synthetic plugin MCP and hooks: passed
29
+
30
+ The installed native print transport used -p, --output-format stream-json and --disable-slash-commands against a loopback Gemini fixture. Synthetic hub_task_show and hub_review responses are stand-ins, never actual board reads or approvals.
31
+
32
+ - Four authenticated provider requests; all fifteen declaration names match the previous receipt. Native init has 60 tools and permission_mode request-review.
33
+ - MCP discovery, initialize, initialized and tools/list occur in order. Exactly two calls carry the expected object arguments: hub_task_show id 1; hub_review id 1, verdict approved, fixture-only note. Native call_mcp_tool retains ServerName, ToolName and Arguments, without toolSummary/toolAction.
34
+ - Native read_file has Path, StartLine and EndLine and reads only the canary. Its result appears in the next fixture request.
35
+ - Six phases: SessionStart, PreInvocation, PreToolUse, PostToolUse, PostInvocation, Stop; sixteen hook rows. Shared fields, invocation counters and toolCall fields match the previous procedure. Both injectSteps markers reach the later fixture request.
36
+ - Stop is NO_TOOL_CALL, executionNum 0, fullyIdle true, empty error. Print exits 0, no stderr or signal fallback. Profile, loopback and helper controls pass.
37
+
38
+ Two initial producer checks failed, and remain recorded as failed attempts. The diagnostic kept their assertions unchanged: the fixture itself sent Arguments as a JSON string, and the collector looked for system/subtype init instead of the native top-level init object. The corrected fixture sends an object, as the historical actual-hub nonce producer already did, and reads the unique init object. Exact raw arguments and request-review remain asserted. This does not claim a historical native transport difference.
39
+
40
+ Final hooks log: `temp/task801-hooks-153-object.log`; producer SHA-256 `8e60b161f01e1ec06063c56a5ab710135624f0deb2cf65297baa54c4c418c2e2`; runtime SHA-256 `6a31b50060e38e5f9bc8176f086a7ad743ec9e8b0e3d58f0182ad51116ed5cc4`.
41
+
42
+ ## Actual launcher nonce and normal TUI close: passed
43
+
44
+ One actual `ahub --live-test --project <private project> agy` session proves both legs. Native UI used a private foreground tmux 3.8 server with an explicit fresh socket and -f /dev/null; no existing tmux session, Orca window or personal profile was used. A fixed Bun-only stdin/EOF helper passed before any agent launch.
45
+
46
+ The stock gate still refused 1.5.3 during the probe. The controller used typed writeTrust only at an explicit fresh AGENTHUB_HOME/agent-compat.json, verified as a 0600 owned regular file with one exact 1.5.3 entry. Actual version assessment was trusted, not verified. This fixture waiver enabled a candidate test; it did not qualify the version or modify machine trust.
47
+
48
+ The scratch Registry claim used its own PID/signature, project and instance. Daemon memory/native capture/sync, inference, triage, research, specs, snapshots, schedules, gateway URLs, MLX and Pi auto-start were off. Parent fetch was limited to the two owned loopback ports; native had the Seatbelt fence above. Provider requests require the synthetic fixture-key, refuse Origin and are body/count bounded. No real account or cloud model was used.
49
+
50
+ | Observation | Final result |
51
+ | --- | --- |
52
+ | Managed plugin during TUI | hooks.json, mcp_config.json, plugin.json, bound to this instance/launch by actual agyMcpReady |
53
+ | Fixture privacy checkbox | unchecked observed before continuing; folder trust applies only to the private fixture |
54
+ | Provider requests and declarations | 4; declaration counts 0, 12, 15, 15 |
55
+ | Actual MCP read | one call_mcp_tool for agent-hub_agent-hub/hub_inbox |
56
+ | Nonce provenance | RAM-only producer value placed only in the scratch bus preface, never argv, env, prompts or receipt; nonceAfterInbox: true in a later provider request |
57
+ | Peer identity | canonical agy only, no agy shadow session |
58
+ | Normal close | /exit and Enter; normalExit: true, native/launcher exit 0, resume command observed, no native signal fallback |
59
+ | Cleanup | all three managed files removed, bystander plugin/rule hashes unchanged, peer offline; a new begin/end control pair proves slot release, not a second TUI launch |
60
+ | Processes and handles | interactive tree, daemon, provider, Registry claim and Registry closed; controller removed its private root; final owned-process inventory clear |
61
+ | Real config/binary | five named entries and binary/directory inventory unchanged |
62
+
63
+ The parent-JS external/unrelated fetch-attempt counters were zero. This is not a count of every native network attempt; native egress is constrained by Seatbelt. CLI/print command bound is 25 seconds; TUI total is 80 seconds with one 45-second normal-close window.
64
+
65
+ Prototype launcher attempts stopped at setup barriers, used owned fallback cleanup and are not normal-close passes. An ANSI byte-window collector could not reconstruct checkbox partial repaints; the final collector reads tmux's current screen. The first tmux run also waited for daemon idle before MCP lazy attachment, preventing the second prompt; the corrected producer uses the actual TUI input screen there. It still requires actual nonce readback, canonical identity, normal close and cleanup. No native/product permission or timeout was relaxed. An initial lexical /var versus canonical /private/var fixture mismatch was fixed in the controller; its unconfirmed first failure stage is not native evidence.
66
+
67
+ Final launcher log: `temp/task801-launcher-153-lazy.log`. Its source/bundle/private producer fingerprints follow; original historical producers were rehashed unchanged.
68
+
69
+ - Bundle SHA-256: `333975a6aeec1413cf5ae30d6bb292c7318362f795230db8e0d5133b7d144d1e`.
70
+ - interactive-bridge.ts SHA-256: `d87cb1db044cf1c036f7a41b06bf3023ab8d0b81e957e0302b154d54656d8348`.
71
+ - interactive-session.ts SHA-256: `f8a06759abead1629998593d57c0cfac69f5d488e44a0d88b549fe0d9a92febc`.
72
+ - tmux-session.ts SHA-256: `6b2f6f9216a3e2f2c3a6d4c5950b7bfe24a7162d0a331356b855ce04287253e0`.
73
+ - tmux-helper-control.ts SHA-256: `a13c7a4b1702be7f667857eee0fd9f805c16441fd0f0b9e44ce1b7d962c76373`.
74
+ - launcher-nonce.ts SHA-256: `55ff4db3462ad185dde17cc31ef971422e022f5ec8ce2940e4045501964c1ac1`.
75
+ - runtime.ts SHA-256: `6a31b50060e38e5f9bc8176f086a7ad743ec9e8b0e3d58f0182ad51116ed5cc4`.
76
+ - run-probe.py SHA-256: `16c6f4b1026250685097089f31c4b2d450d91589fa78dfa6c5f9b5c260efb5e5`.
77
+
78
+ ## Named real Gemini config inventory
79
+
80
+ Only these five entries were hashed; contents are not published.
81
+
82
+ | Relative entry | Before and after SHA-256 or absence |
83
+ | --- | --- |
84
+ | `antigravity-cli/settings.json` | `ad07119c21cf14ea153eb4200d6468add57d4e26783808f384f4bf7d4df31682` |
85
+ | `config/config.json` | `b8c51361bf83a00ae5e38b3108b48ffa3b4cfc7c4e9d9b7d16e04f74725f3c14` |
86
+ | `config/mcp_config.json` | `d8e397af03b5b032f21d0aa967086f0c78b33c87b76f2e9898ae0a144df7de02` |
87
+ | `config/import_manifest.json` | Absent |
88
+ | `settings.json` | `66c879018049d90632634790fe0b0eae54616a144e594c5db1b40b7c8be8c7b9` |
89
+
90
+ ## Reused evidence and limits
91
+
92
+ The [exact reviewed 1.5.3 ACP T0 record](https://github.com/STAIxBWLB/agent-hub/blob/1e6da1ee221acd601fa28201c8cd0081d8214566/docs/verification/2026-11-08-agy-acp-t0.md) covers account-free initialize. Its isolated session/new returned Authentication required. Its other run used an existing personal login and is not reused as account-free qualification. Neither run substitutes for the native legs above.
93
+
94
+ No real account, real model tool choice, native permission-mode mapping, headless ACP prompt/cancel, IDE or Linux behavior is qualified. The native probe's Seatbelt does not add a hub sandbox to ordinary agy. Fresh reviewer MCP and agy's implementer/verifier role ceiling are unchanged. The harness manifest keeps its historical procedure and autoAdmit false; no workflow, global trust or verified stamp is changed.
95
+
96
+ The source PR adds only exact 1.5.3, updates receipt/trustNote and keeps the 1.4.x line. Canonical DGX and hosted CI results belong to their exact committed heads and are reported separately in the PR/task submission. No release or live upgrade is claimed.
@@ -0,0 +1,56 @@
1
+ # agy acp T0 capability probe (agy 1.5.3)
2
+
3
+ Refs #1280 (P2), #485. Model-free: `initialize` and `session/new` only, no prompt, no credential read. Run with `AGY_CLI_DISABLE_AUTO_UPDATE=1`.
4
+
5
+ Two runs: run 1 under the person's real home (a mistake against the planner ruling, cleaned up below) and run 2 under a disposable HOME (the isolated run of record).
6
+
7
+ ## Run 1 (person's home, cleaned up)
8
+
9
+ The person's existing login was in scope, so `session/new` succeeded and created session state. Exactly these files were created by the probe and removed; nothing else in that home was touched:
10
+
11
+ - `~/.gemini/antigravity-cli/conversations/<sessionId>.db`
12
+ - `~/.gemini/antigravity-cli/brain/<sessionId>/` (empty `scratch/` and `.user_uploaded/`)
13
+ - `~/.gemini/antigravity-cli/log/acp-server-20261108_000903-24787.log` and `acp-server-20261108_000951-32157.log`
14
+
15
+ An `implicit/*.pb` file with a nearby mtime is not referenced by the probe's log and was left alone.
16
+
17
+ ## Method
18
+
19
+ - `agy --version` prints `1.5.3`.
20
+ - `agy acp` on stdio, newline-delimited JSON-RPC 2.0.
21
+ - Request 1: `initialize` with `protocolVersion: 1` and empty `clientCapabilities`.
22
+ - Request 2: `session/new` with `cwd` set to a scratch directory and `mcpServers: []`.
23
+
24
+ ## Run 2 (isolated HOME, the run of record)
25
+
26
+ `HOME` and `XDG_CONFIG_HOME` pointed at a fresh temp directory, no account. `initialize` answered exactly as in run 1 (same capabilities and `authMethods`). `session/new` was refused: `{"code":-32000,"message":"Authentication required"}`. The process wrote only under the temp home (`.gemini/config`, `.gemini/antigravity-cli`: state, installation id, one `acp-server` log, builtin plugins); the directory was removed afterwards.
27
+
28
+ Finding: `initialize` needs no login; `session/new` and everything after it need one of the four `authMethods`, so a hub-owned headless `agy acp` needs a person-provided login or API key and cannot be probed beyond `initialize` without one.
29
+
30
+ ## Observed in run 1 (person's home)
31
+
32
+ - `initialize` result: `protocolVersion: 1`, `agentInfo` `Antigravity ACP Server` `1.5.3`.
33
+ - `agentCapabilities.loadSession: true`.
34
+ - `promptCapabilities`: image true, audio false, embeddedContext true.
35
+ - `sessionCapabilities`: `resume`, `close`, `load`, `list`, `additionalDirectories`.
36
+ - `_meta.antigravity`: `tier`, `systemPrompt.append`.
37
+ - `authMethods`: `oauth-personal`, `oauth-business`, `gemini-api-key`, `agent-platform`.
38
+ - `session/new` result with the person's existing login: a `sessionId`, `models` (13 ids, `currentModelId` `gemini-4-argon-medium`), `modes` (`default`, `accept-edits`, `plan`; current `default`), and `configOptions` `model`, `thought_level`, `mode`.
39
+
40
+ ## Maps onto the hub's ACP surface
41
+
42
+ - Native modes `default`, `accept-edits`, `plan` map one to one to the hub's `ask`, `accept-edits` and `plan` permission modes.
43
+ - `session/resume`, `session/load` and `session/close` exist, so the hub's restore path (`restoreArgs`) can resume an agy session by id.
44
+ - `additionalDirectories` gives the hub a way to scope extra roots without a TUI flag.
45
+ - `models` and `thought_level` are selectable through `configOptions`, so `launch.model` can be passed through.
46
+
47
+ ## Not proven here (blockers for wiring `AcpPeer`)
48
+
49
+ - No prompt was sent, so these are unverified: `session/prompt` streaming shape and `stopReason` values, `session/cancel`, mid-turn steering, `session/request_permission` payloads and their option ids, and `usage_update` or token fields.
50
+ - Whether `agy acp` honours the managed hooks (`hooks.json`) or a separate approval path; the TUI hook floor (#1280 P1) may not apply to ACP turns.
51
+ - Whether `mcpServers` passed to `session/new` load the hub MCP server for a headless peer.
52
+ - Authentication of a hub-owned process: run 2 shows it is required; how the hub would supply it without reading a credential is open.
53
+
54
+ ## Decision
55
+
56
+ Probe receipt recorded; `AcpPeer` wiring for `agy` stays out of this change. Wiring needs one authorized model-backed turn to prove the prompt, permission and cancel legs, which the person must approve (it spends quota). Follow-up: a task for the model-backed receipt, then the `ahub agy --mode headless` and `ahub watch agy` wiring.
@@ -0,0 +1,161 @@
1
+ # Hub visuals evidence, #1058
2
+
3
+ This records task #709 evidence by exact head. The published 0.1.7 fixture and isolated browser legs passed below; the final canonical gate and hosted CI are recorded separately. Live observations were recorded by Codex and do not turn synthetic guard coverage into native all-peer qualification.
4
+
5
+ ## Checks by head
6
+
7
+ - `cc7b89c3f664dc08b5f9c2563ea258de22a68bc5`: DGX typecheck and focused tests passed, 177 tests, 0 failures, 2,601 assertions across 11 files. Evidence: scratchpad `temp/task709-focused-cc7b89c3f664dc08b5f9c2563ea258de22a68bc5.log`. This is focused evidence, not the canonical changed gate at the final head.
8
+ - `2bbd9b67b3b70b6f67cfed2f4476d288ab73af33`: bundle built using pinned Bun 1.4.2 and a frozen install. Generated bundle SHA256: `64e96449215a395efa8c9b99bcf525ce7eced256764705223c065aaba5d017c3`. Source provider SHA256: `ea41d5aeb7f871e3fe856d5bfabfb4c869966e6dfa75006baad40f047e171989`.
9
+ - `cfeb1d2913bb`: the first canonical DGX changed gate selected the full suite: 12,709 pass, 101 skip, 5 fail across 986 files (12,815 tests; 318,515 assertions), exit 1 in 2,205 seconds. Typecheck, inventory, bundle freshness and package checks passed. Failures were the read-only MCP tool inventory, two registry guard assertions on a config object literal, task detail section expectations and an extracted role-visibility fixture missing its new UI dependency. Corrections preserve existing assertions; this is not a green gate. No current-invocation daemon leaks were found.
10
+ - `f823646789b5e6f3022cfb38b6c617c9a89862e7`: correction-focused DGX typecheck plus 84 pass, 0 fail, 652 assertions in six files. Its subsequent full run was intentionally interrupted via the owned remote_dev SIGINT cleanup after the independent recovery finding made that head obsolete (exit 130 after 1,568 s). It is not a green full gate or a resource deferral.
11
+ - `d4b52acb59a2f8f6922bf2ed47778cbf21ba00f2`: held-recovery retention correction, DGX typecheck and 20 pass, 0 fail, 182 assertions in two files. The new fixture retains an expired-on-target row unchanged while held, releases with matching digest, then confirms normal pruning after release.
12
+ - An inventory-only DGX command at `2bbd9b67` stopped before checking classifications because its disposable tree had no frozen dependency install (`ts.ScriptTarget` unavailable). The canonical gate performs that install first. Final inventory and canonical committed-head validation are pending; no canonical pass is claimed here.
13
+
14
+ ## Actual acon observation
15
+
16
+ Two isolated runs used real acon 0.1.3, the source provider and production daemon with a synthetic peer, six visuals per run. The final run is bound to `2bbd9b67b3b70b6f67cfed2f4476d288ab73af33`; its body-free counts, hashes and cleanup are in scratchpad `temp/task709-live-2bbd9b67-e.log`. Codex viewed `temp/task709-acon-render-e.png`.
17
+
18
+ - Comparison `<b>` and table `<i>` text remained inert.
19
+ - Two valid 74-byte, 2 by 2 PNG assets returned HTTP 200 and matched their expected hashes. Before SHA256: `1fe7e0db6305cd87580a13d22dde4e6fa6efea01abab2de43f0d23fdde4e9e26`; after SHA256: `500f9b69351abec04ae9956400cc6406f640b596a4ada1e2e1a58e15d6ae4845`.
20
+ - Replacing the after PNG caused HTTP 502 with a safe System cause and next step; changed bytes were not served.
21
+ - Malformed Mermaid showed a notice and source fallback. Valid Mermaid reached the five-second fallback. Successful SVG rendering was unverified in these historical 0.1.3 runs.
22
+ - The final log records six posted visuals, two fixture PNGs, one mutation and zero external fetch attempts. Its `sharedCases: 4` counter counts the four candidate cases exercised; it is not evidence of a published shared fixture. Codex operated the browser, checked the actual DOM and viewed the screenshot; `browserAssertions: 0` is the temporary harness counter, which does not count those separate browser checks.
23
+ - Own provider, console server, tools, console, synthetic peer, daemon, registry, handles and external browser were closed; the process exited without forced stop and its scratch root was removed. Owned sockets were closed.
24
+
25
+ No account, native agent or model was used. No standalone hub UI browser was used. Initial a/b/c preflights failed at the scratch routing MLX guard before listeners were opened; no production guard or bound was changed to make them pass.
26
+
27
+ ## Boundaries and remaining evidence
28
+
29
+ - Validation rejects malformed or oversized payloads, screens text and preserves cleared extra table row keys. Tool paths and stored asset references have distinct shapes. Fake source-guard coverage is not a live privacy or native-role receipt.
30
+ - Assets remain bound to guarded file identity, hashes and current privacy authority on reads. The changed-PNG observation covers one actual asset mutation path.
31
+ - Unbound visuals expire after the configured retention period (default 30 days); task-bound records remain unless task existence proves them orphaned. Recovery inventory hashes stored metadata and payload/file-reference JSON, not image bytes. Focused fixtures cover corruption refusal, cursor cleanup, retention and archived reset separation.
32
+ - Historical 0.1.3 observations did not qualify WebP: that host and 0.1.4 refused its MIME type. The published 0.1.7 follow-up is recorded separately below.
33
+ - Historical fixtures were hub-owned candidates with source provenance. They did not fill the shared-fixture gap; the 0.1.7 follow-up imports the published cases directly.
34
+ - The ordinary peer transports were covered by source/fake checks, not native all-peer journeys. Such native journeys are not an additional acceptance requirement in the issue. Fresh-reviewer MCP intentionally remains exactly hub_review and hub_task_show under D2. Mermaid SVG success was unverified in the historical 0.1.3 run; the 0.1.7 observation below records successful rendering. D4 still explicitly permits a five-second source fallback.
35
+
36
+ The earlier planner ruling recorded AC1 unmet after the agent-console#78 handoff refusal, and AC4 unmet while agent-console#81 had no published support. Those were not waived. Published support and the 0.1.7 follow-up results are recorded below. Successful Mermaid SVG was unverified in the historical 0.1.3 evidence and is verified by the isolated 0.1.7 observation; standalone browser rendering remains unverified. D4 permits source fallback.
37
+
38
+ Completed overlap work was checked: main contains Kimi delayed usage (#783), AGY count-only hints and person attribution. Their imports, immutable turn attribution and shutdown cancellation are preserved; none replaces visual authority or generation checks. Open #800 ownerAttachment stays display-only, and #802 rememberOutcome remains separate from visual capture. The current main merge includes only already-merged work; no peer branch is imported. Final committed-head canonical validation is separate and remains pending until its result is recorded.
39
+
40
+ ## Published dependency follow-up
41
+
42
+ Primary recheck on 2026-11-08 found agent-console#78 and #81 completed and npm 0.1.7 published. The exact devDependency and lock now adopt 0.1.7. The upstream VISUAL_CASES module is imported directly, never copied: 42 cases, with six fixed, documented valid-acon/stricter-hub cap differences. Missing alt still refuses and now names the precise alt field. Old candidate provenance remains historical 0.1.3 with a separate 0.1.7 recheck; it is not labelled canonical. Type-only production imports preserve the dependency boundary.
43
+
44
+ Earlier AC1/WebP unmet observations above describe the 0.1.3 evidence. They are superseded by the following direct fixture and browser observations, not solely by an upstream issue state or package version.
45
+
46
+ - Frozen source head `afc1e459447a779a2418457640b80fda5c0eafb3`: DGX frozen install, typecheck and focused checks passed, 142 tests, 0 failures, 630 assertions across seven files, exit 0 in 37 s. Log: scratchpad `temp/task709-017-focused.log`. The canonical test imports all 42 published cases and checks six explicitly named stricter hub-cap differences.
47
+ - Real acon 0.1.7 loaded the actual source provider and production daemon in an isolated HOME/project, with a synthetic ordinary peer and no account, native agent, gateway, memory sync or model. It posted seven visuals, including four normal cases selected from the actual published module, two software PNGs and one software WebP. Published case module SHA256: `68455a97595664d88fc62567a301ef5e5e06abf78b75145f528a38b5c5bf39b6`.
48
+ - Both PNGs returned HTTP 200, `image/png`, inline disposition and the same 74-byte hashes recorded above. The 38-byte WebP returned HTTP 200, `image/webp`, inline disposition and SHA256 `ea6a0dfbc1103e231f69d8a08182ac8168f9aa06242f1d1606a9e82894a45e40`. All six displayed image elements decoded to 2 by 2 pixels after scrolling into view. The browser's lazy loading was respected, not disabled.
49
+ - The normal flow rendered A -> B in the sandboxed frame. The malformed flow showed "The diagram could not be drawn, so it is shown as text" with its original source. Codex viewed screenshots `temp/task709-acon-017-flow.png`, `temp/task709-acon-017-webp.png` and `temp/task709-acon-017-fallback.png`. The 2-pixel fixtures establish decoding, not useful image-layout quality.
50
+ - Replacing the after PNG returned HTTP 502 and the safe System cause/next step "visual asset changed since posted or no longer allowed; post the visual again using a current public file". No changed bytes were served.
51
+ - One scratch HTTP URL builder encoded the plugin reference's @ and therefore received 404; the actual console-generated route was correct. Direct HTTP readback used that route spelling. No production URL or provider code was changed to make the check pass. An initial generic CSS scroll matched an earlier figure; selecting the actual last figure exposed the expected deferred renderer and fallback. Neither observation is counted as a product failure or silently omitted.
52
+ - Body-free log `temp/task709-live-017-f.log` records seven posts, four published cases, two PNG fixtures, one WebP, one mutation and zero external fetch attempts. `browserAssertions: 0` remains the harness's counter; separate browser DOM/readback and viewed screenshots supply the browser evidence. It records provider/server/control clients/synthetic peer/daemon/registry/handles closed, owned process exited without forced stop, browser closed and scratch root removed. The separate owned browser socket directory had no open handles and was removed.
53
+
54
+ These observations complete the previously missing shared-fixture and WebP legs. The standalone dashboard remains covered by extracted UI/fake-host checks rather than a browser run, and native all-peer journeys remain unrun. The final canonical committed-head result and exact-head hosted CI are still pending here; no full green gate is inferred from the focused or browser checks.
55
+
56
+
57
+ ## Final review corrections and pending gate
58
+
59
+ Independent preflight found and verified fixes for held-recovery retention, the old host WebP refusal, and the advertised path-side alt schema. At `47b291c696d1461fa38a9d3682389879b0af783e`, alt remains required and bounded but may be empty, matching the published case and runtime. The regression checks both accepted empty alt and refused missing alt. DGX frozen install, typecheck, inventory and 143 focused tests passed (0 failures, 633 assertions across seven files; exit 0 in 37 s). Inventory was OK: 3,534 entries, 2,529 classified, unchanged 1,005-entry baseline. Log: scratchpad `temp/task709-alt-focused.log`. The pinned Bun bundle was regenerated.
60
+
61
+ The canonical run at `1ee364c3dc9c473cb3e8fa12c974e72740dc13a6` was stopped via the verified owned remote_dev helper's normal SIGINT cleanup after that schema finding made its source obsolete (exit 130 in 62 s). No pass or resource deferral is claimed. The final report head starts one fresh canonical `scripts/check.sh --changed` run; its result is not yet available here. Exact-head hosted CI remains a merge gate.
62
+
63
+ A separate O3 full gate at `45b5dca1` exposed a pre-existing main fixture assumption in `test/herdr-companion-platforms.test.ts:85`: it expects `/home/dev` not to exist, but that is the DGX container HOME. That fixture is unchanged in this branch. It is reported to the conductor rather than edited in this visual feature. A failure from that assertion must not be presented as a green canonical gate.
64
+
65
+
66
+ ## Review correction: metadata snapshots and refusal classes
67
+
68
+ The review at `687d579f` found two Important defects: operational refusal causes
69
+ were collapsed into a privacy message, and periodic snapshots re-read and
70
+ re-screened up to twenty full payloads. This revision separates operational
71
+ recovery, role, membership, observer, shutdown, authority, storage, concurrent
72
+ change, screen-unavailable and policy-unavailable diagnostics. Sensitive privacy
73
+ hits retain uniform wording. An unknown or throwing screen still fails closed;
74
+ its error body is never returned.
75
+
76
+ Snapshots use the store's metadata projection plus bounded file-path metadata,
77
+ never `get` or `payload_json`. Relevant raw policy bytes and accepted path arrays
78
+ key a narrow policy projection; no full `loadConfig` runs on this path. Current
79
+ accepted restrictions remain unioned with the normally merged candidate path
80
+ rules, and each read still checks exposed title/from/task/path metadata. Explicit
81
+ show rechecks the complete payload. Missing files keep their public explanation;
82
+ the guarded asset read alone decides current existence and hash.
83
+
84
+ The same revision makes all three prune sites wait for both recovery holds,
85
+ uses a nonmutating `Limiter.peek` before expensive validation/screening/reads and
86
+ retains one final consuming admission, admits explicit `to: "user"`, and removes
87
+ visual-only calls from task-progress evidence. Three moved limiter inventory
88
+ keys keep their original labels; the baseline is unchanged.
89
+
90
+ Structural tests cover twenty tiny and maximal-table rows, forbid full payload
91
+ reads, use corrupt/oversize body canaries, preserve metadata privacy, and assert
92
+ peek's bucket/repeat/group state never changes. Cause tests use real daemon
93
+ operations for reachable states and a real tools request under prepared recovery.
94
+ Stopping and stale child-authority branches execute the actual extracted closure
95
+ with all later ports forbidden; these are unit evidence, not native-child
96
+ qualification. New exact-head test results follow when available.
97
+
98
+ The obsolete canonical run at `687d579f` was stopped through its verified owned
99
+ remote_dev helper's normal SIGINT cleanup after this review (exit 130 in 701 s),
100
+ not counted as a pass or deferral. No duplicate run was started.
101
+
102
+
103
+ The first review-correction run at `0df8749a61accff31bdbce806f9c95d73d68f37e`
104
+ passed typecheck and inventory, then had 247 pass and 3 fail (1,351 assertions,
105
+ ten files; exit 1 in 45 s). New fixture assumptions caused the three failures:
106
+ an initially off-roster peer is refused at hello before its tool call; closing
107
+ the journal also activates a recovery hold; and `settings_reload` returning
108
+ `ok: true` can be an unconfirmed preview, not adoption. The corrections preserve
109
+ cause/next-step and zero-effect assertions, and confirm configuration adoption
110
+ before releasing the held call. This run is not a green gate. The independent
111
+ read-only preflight found no new Important code issue in that delta; the generated
112
+ bundle was excluded from its 14-file source/test/doc coverage.
113
+
114
+
115
+ Subsequent focused runs preserved those assertions while correcting the roster
116
+ fixture: `0bef303c` had 249 pass, 1 setup failure (1,367 assertions, ten files;
117
+ 46 s), `3b6dcf19` had 33 pass, 1 setup failure (291 assertions, one file; 35 s),
118
+ and the single-case `bb93351f` run failed on the fixture's status lookup (4 s).
119
+ The real roster API saves membership even when the passive fake cannot prove a
120
+ native stop; its explicit unconfirmed-stop result is asserted rather than
121
+ replaced with fabricated stop evidence. Effective settings rows, rather than a
122
+ removed peer's status entry, confirm the saved membership.
123
+
124
+ Once that setup reached the actual call, `39a75723` exposed a further product
125
+ path: the outer WebSocket membership guard returned only "codex is off roster"
126
+ before the visual handler, so the next-step assertion correctly failed (one
127
+ case, 4 s). The outer stopping and prepared-recovery guards were also traced.
128
+ Visual requests now receive the same operational guidance at those boundaries,
129
+ without changing any admission condition or non-visual response. Assertions were
130
+ not weakened to accept the incomplete message. Full native-child stop/identity
131
+ qualification remains outside these passive and extracted-unit fixtures.
132
+
133
+
134
+ At `1388cbaa06f0682124b3e8f6a3824259985a5c42`, DGX frozen install,
135
+ typecheck, inventory and all 253 affected tests passed: 0 failures, 1,395
136
+ assertions across ten files, exit 0 in 45 s. Log: scratchpad
137
+ `temp/task709-revision-check.log`. This includes the actual off-roster request,
138
+ prepared recovery requests, outer stopping branches, metadata-only large-table
139
+ checks, missing-image behavior, limiter nonmutation and existing configured MCP
140
+ read-only tests. Earlier failing fixture/setup runs are retained above rather
141
+ than represented as passing.
142
+
143
+ The rewritten outer roster message is also an exact seeded anchor. Its
144
+ `roster-request-fence` search/replacement now matches the new line while retaining
145
+ the same false-membership mutant and original named test. The affected seed is
146
+ in shard 29/64; that shard and all-anchor readback are checked separately before
147
+ submission. No claim about the entire 559-seed gate is made by a focused shard.
148
+
149
+
150
+ At `7893068fa88e4ae536311141e48c7fa38c782439`, all 559 anchors matched
151
+ exactly once. The affected shard 29/64 passed all nine original-green /
152
+ named-mutant-detected pairs, including `roster-request-fence`, in 24 s.
153
+ Log: scratchpad `temp/task709-seeds-29.log`. The mutant still replaces only the
154
+ membership predicate with false; its original named test is unchanged. This is
155
+ a focused seeded shard, not a claim that all 559 mutants ran.
156
+
157
+ The final report-only head has the same runtime and test bytes as these passing
158
+ heads. A fresh canonical `scripts/check.sh --changed` run starts at that final
159
+ head; its result and hosted full CI are not yet observed. AC6 remains a merge
160
+ gate. No timeout, retry, assertion, privacy fence or baseline was relaxed, and
161
+ no real profile, release or deployed hub was changed.
@@ -0,0 +1,143 @@
1
+ # Jcode 0.99.1 headless ACP model setter
2
+
3
+ Date: 2026-11-08. Task #809, Refs #1317 AC4. **Passed:** native setter APIs and
4
+ the actual owned `JcodePeer`/DB-latch path in a fixture with no TUI client.
5
+ This does not qualify a shared native TUI binding or failover concurrency.
6
+ The production Jcode capability remains disabled pending that form restriction.
7
+ This is compatibility evidence, not a security attestation or account/model run.
8
+
9
+ ## Exact artifact and setup
10
+
11
+ - macOS arm64 installed Jcode reports 0.99.1, v0.99.1 (7206efd0c).
12
+ Its 142,887,552-byte executable has SHA-256
13
+ `eccb33c08a21764317b0e0bf217e60c745b90f51c7bf6d2ff90b548b9fe7383e`.
14
+ A single byte-identical private executable copy is checked before/after;
15
+ no dependency tree or personal native home is copied.
16
+ - Native `jcodeCommand`, owned-group helpers, `JcodePeer`, `ModelOverrides` and
17
+ `ModelOverrideLatches` are the actual first-party implementations. The passing
18
+ adapter/latch source is `7c86077e89f790af0fd444b8ca9bd90e8d0bc09f`.
19
+ - Fresh 0700 temporary roots hold HOME, JCODE_HOME, cwd, TMPDIR, all XDG and
20
+ hub/tool homes. Empty native/project MCP files, `JCODE_DISABLE_CLAUDE_MCP=1`,
21
+ `JCODE_NO_TELEMETRY=1`, `--no-update` and `--no-selfdev` avoid account/import/
22
+ updater paths. No configured account, key or actual model is used.
23
+ Telemetry-file absence is not claimed; all native writes remain isolated.
24
+ - A native `provider add` creates one no-key OpenAI-compatible fixture profile,
25
+ default model `receipt-model-a`, pointing only to an owned ephemeral loopback
26
+ server. The integration fixture additionally declares `receipt-model-b` in
27
+ that same private profile's models array before startup. Endpoint, auth and
28
+ default A do not change. This matters: without catalog opt-in or explicit B,
29
+ the native default advertises static A only, even though its raw setter can
30
+ accept B. The probe never pretends that an unused GET model list was consumed.
31
+
32
+ ## Native isolation controls
33
+
34
+ Every native command uses Seatbelt from the existing local-worker profile plus
35
+ owned paths. Actual-home data and installed-runtime write-open are denied.
36
+ Native TCP is limited to the exact fixture provider port; an owned decoy port
37
+ is denied. Only the owned server/debug Unix sockets are allowed. No port 4600,
38
+ actual gateway, public provider, real key or native account is used.
39
+
40
+ The Rust HTTP runtime needs the named
41
+ `com.apple.SystemConfiguration.configd` lookup. A separate create/release control
42
+ returns a NULL dynamic-store handle without it and a valid handle with it,
43
+ without querying or changing configuration values. The final profile adds only
44
+ that service; file and network negative controls still pass. No OS/security
45
+ setting, file limit or deadline is changed.
46
+
47
+ The provider rejects Origin, credentials, unknown paths, oversized bodies,
48
+ unexpected models and excess completion calls. It emits bounded fixed text SSE,
49
+ never tool calls. Client filesystem/terminal capabilities are false. Owned
50
+ processes and groups are stopped and observed gone. Detached lifetime
51
+ containment is still unproven, not a disposable-runner attestation.
52
+
53
+ ## Native APIs and actual adapter behavior
54
+
55
+ The raw protocol leg initializes exact `jcode` 0.99.1/protocol 1 and creates a
56
+ session. While fixture request A is held, both `session/set_model` and
57
+ `session/set_config_option` refuse with the native processing-a-prompt error.
58
+ There is still only request A. After normal A completion, legacy set_model B
59
+ acknowledges with configOptions and the same-session config update; the next
60
+ request uses B. Standard set_config_option A then produces request A. Launch
61
+ argv remains A on both serve and ACP, with wire sequence `[A, B, A]`.
62
+
63
+ The separate integration leg uses the actual `JcodePeer` and its owned serve/ACP
64
+ children, with the same profile and fixed launch A. A transparent observer calls
65
+ the original request method with unchanged arguments and returns the same
66
+ promise; it records only bounded method/model IDs, not replacement responses.
67
+
68
+ 1. Initial native advertisement proves baseline A and advertised B. The runtime
69
+ requires exact 0.99.1 identity/receipt plus existing Jcode compat admission;
70
+ native advertisement alone cannot grant a capability.
71
+ 2. A real DB override A enters the first deliver. The provider holds A's stream.
72
+ Writing desired B while busy sends no setter or second model request.
73
+ 3. A completes unchanged. The next deliver sends standard
74
+ `session/set_config_option`, `configId: model`, value B. Native B completes,
75
+ and the actual latch reports B applied. The private provider config hash is
76
+ unchanged immediately after B, not merely after a later restoration.
77
+ 4. Clear removes the DB intent. The next deliver sets the original baseline A,
78
+ the provider observes A, and latch status is A with no desired/pending value.
79
+ 5. Three prompts have accepted/completed receipts, two standard model setters
80
+ have exact values `[B, A]`, and the same owned serve/ACP launch is stopped.
81
+ Provider config remains byte-identical after stop. The actual installed
82
+ executable and selected actual config snapshot remain unchanged for the leg.
83
+
84
+ The fixture native profile, CLI argv and synthetic responses are all declared
85
+ before effects. No `jcode_cmd`, `-m`, provider-profile or credential configuration
86
+ is made live by the runtime override. Actual hub CLI/dashboard authority is
87
+ separate unit/integration evidence, not claimed as a native journey here.
88
+
89
+ ## Shared TUI limitation
90
+
91
+ The ACP child checks its own `prompt_running`. The shared native server protects
92
+ an ordinary stream with an Agent mutex, but deferred model mutation is not a
93
+ logical TUI-turn fence. The pinned source's failed-attempt/failover retry path
94
+ releases and reacquires that mutex; a queued mutation can run in between.
95
+ [SetModel/deferred mutation](https://github.com/1jehuang/jcode/blob/v0.99.1/crates/jcode-app-core/src/server/provider_control.rs#L723),
96
+ [streaming lock](https://github.com/1jehuang/jcode/blob/v0.99.1/crates/jcode-app-core/src/server/client_lifecycle.rs#L3925)
97
+ and [failover boundary](https://github.com/1jehuang/jcode/blob/v0.99.1/crates/jcode-app-core/src/server/turn_failover.rs#L156)
98
+ are source inspection, not a native failover execution receipt.
99
+ This fixture has no TUI client and does not qualify that concurrency path.
100
+ No TUI-bound live setter is enabled from this receipt without a separately
101
+ reviewed form/ownership restriction. No native load-session recovery ceiling
102
+ is relaxed; 0.99.1 still does not echo the restored session identity.
103
+
104
+ ## Failed attempts and real-home observations
105
+
106
+ Two earlier raw attempts failed before serve readiness, with zero provider
107
+ requests/setters, confirmed owned stop and unchanged per-leg actual config.
108
+ The diagnostic attempt captured Rust system-configuration's NULL-object panic.
109
+ The isolated dynamic-store control identified the precise missing named lookup;
110
+ the final fresh raw run kept every assertion and bound and passed with it.
111
+ Private logs from the failed attempts are retained.
112
+
113
+ After the successful actual-peer run, the controller was accidentally invoked
114
+ again before its earlier completion was checked. Exclusive native-home creation
115
+ refused with EEXIST before any new native command. The first immutable structured
116
+ result is preserved; the duplicate stdout redirect overwrote that stdout log,
117
+ so the passing structured file, not the later log, is the authoritative artifact.
118
+ No duplicate native run or config restore was performed.
119
+
120
+ The selected actual Jcode/Kimi config/credential snapshot is nine entries,
121
+ with symlinks recorded without following. The actual-peer leg matched before
122
+ and after with digest
123
+ `d5e53329f27db1df63c90c6f475049b8df13611d3913ec09b7589a1e6d580997`.
124
+ Other probes observed Kimi credential drift between legs, before their native
125
+ spawn; writer attribution is unproven. There is no task-wide immutable-state
126
+ claim across those intervals, and no real file was restored or edited.
127
+
128
+ ## Evidence and remaining scope
129
+
130
+ Private workspace scratch `temp/task809-jcode` holds the producers;
131
+ `temp/task809` holds the controllers and closed case bindings/results.
132
+
133
+ | Item | SHA-256 |
134
+ | --- | --- |
135
+ | raw Mac producer | `22259a94a7e568f9570dbfcee3e8ed85075bb72cd8031c87492f58ba4c0e00b2` |
136
+ | actual-peer producer | `c75c04dcc374d1a8ed7cf7223693e975e481a9b104200ed1912ac5fd732ddcca` |
137
+ | actual-peer controller | `4a801a8d5471274ef6269144a2d98c1ee7053808cba4d540229bd5ea511d793f` |
138
+ | actual-peer structured result | `502bc53ef01e2f38462ab92387dd343788a636dfa38301753635f090930d196a` |
139
+
140
+ Native TUI/failover, other platforms/providers/versions, real accounts/models
141
+ and installed-hub rollout remain unverified. Source checks, canonical DGX and
142
+ exact-head hosted CI are separate PR gates. No COMPAT/trust widening, verified
143
+ stamp, release or production model change occurs in this task.