@staix/agent-hub 0.29.0 → 0.30.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.
- package/CHANGELOG.md +12 -0
- package/README.md +5 -3
- package/docs/agent-notes/README.md +12 -0
- package/docs/agent-notes/adapters.md +2 -1
- package/docs/agent-notes/bus.md +1 -0
- package/docs/agent-notes/daemon.md +2 -1
- package/docs/agent-notes/tasks.md +4 -2
- package/docs/agent-notes/tests.md +2 -0
- package/docs/design/adapters.md +56 -0
- package/docs/design/agent-hub-architecture.md +12 -0
- package/docs/design/bus.md +8 -0
- package/docs/design/task-board.md +18 -0
- package/docs/dogfood.md +7 -4
- package/docs/operations.md +106 -11
- package/docs/quickstart.md +10 -3
- package/docs/sdlc.md +1 -1
- package/docs/security.md +28 -2
- package/docs/smoke.md +13 -2
- package/docs/specs/2026-10-12-office-view-design.md +86 -3
- package/docs/verification/2026-11-03-0.30.0.md +54 -0
- package/docs/verification/2026-11-03-agy-1.4.12-launcher-nonce.md +42 -0
- package/docs/verification/2026-11-03-agy-1.4.12.md +90 -0
- package/docs/verification/2026-11-03-agy-tui-close.md +49 -0
- package/docs/verification/2026-11-03-grok-1.0.62-t0.md +150 -0
- package/docs/verification/2026-11-03-pi-150-compat.md +40 -0
- package/docs/verification/2026-11-03-pi-title-api.md +26 -0
- package/docs/verification/2026-11-03-qwen-0265-acp.md +55 -0
- package/docs/verification/2026-11-03-qwen-0265-dual-output.md +40 -0
- package/docs/verification/dogfood/2026-11-03.md +3095 -0
- package/docs/verification/pi-150-model-free.ts +57 -0
- package/docs/verification/pi-150-native.mjs +21 -0
- package/docs/verification/pi-150-title-api.mjs +31 -0
- package/docs/verified.json +14 -14
- package/package.json +2 -2
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +193 -29
- package/src/adapters/compat.ts +10 -10
- package/src/adapters/definitions/builtin-metadata.ts +2 -2
- package/src/adapters/local-worker.ts +22 -6
- package/src/adapters/pi.ts +92 -10
- package/src/adapters/registry-types.ts +4 -0
- package/src/adapters/registry.ts +2 -0
- package/src/cli/autonomy.ts +66 -1
- package/src/cli/console-state.ts +6 -2
- package/src/cli/help.ts +2 -0
- package/src/cli/identity.ts +8 -1
- package/src/cli/main.ts +39 -0
- package/src/cli/worktree-tidy.ts +158 -0
- package/src/cli/worktrees-output.ts +43 -0
- package/src/hub/board.ts +28 -3
- package/src/hub/bus.ts +4 -4
- package/src/hub/conductor.ts +4 -3
- package/src/hub/config-apply.ts +2 -1
- package/src/hub/daemon.ts +237 -19
- package/src/hub/dogfood-read.ts +62 -9
- package/src/hub/hub-tools.ts +11 -5
- package/src/hub/manager.ts +9 -1
- package/src/hub/peer-doing.ts +33 -3
- package/src/hub/peers.ts +7 -0
- package/src/hub/settings.ts +3 -0
- package/src/hub/tasks.ts +30 -8
- package/src/hub/ui.ts +2 -0
- package/src/hub/worktree-prs.ts +100 -0
- package/src/hub/worktree-shelf.ts +246 -0
- package/src/memory/capture.ts +1 -1
- package/src/pi/extension.ts +43 -3
- package/src/ui/index.html +133 -10
- package/src/ui/office-model.ts +64 -8
- package/src/ui/office-space.ts +1 -0
- package/src/ui/plugin.ts +14 -3
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Antigravity 1.4.12 actual-hub nonce leg through the `ahub agy` launcher (#888)
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Task #684, Refs #888. The [1.4.12 receipt of task #681](2026-11-03-agy-1.4.12.md) passed the CLI surface, the synthetic plugin MCP and hook contract and the normal TUI close, and failed the actual-hub nonce leg. This receipt re-runs only that leg, and drives it the way the person's launcher does.
|
|
4
|
+
|
|
5
|
+
**Decision: add 1.4.12 to agy `verified`.** Every account-free leg now has a pass on the same binary: the three legs from the #681 receipt, plus the nonce leg below. The accepted 1.4.x line is unchanged.
|
|
6
|
+
|
|
7
|
+
## Why the #681 nonce leg failed, and what changed
|
|
8
|
+
|
|
9
|
+
The #681 probe wrote its own plugin files and ran the bundle itself. It never asked the daemon for a launch slot (`native_hook_launch begin`), so the bundle's hub-tools socket was not an owned agy launch and joined as a distinct `agy~...` session. That session is not the project's agy and rightly got no preface. This is a defect of that producer, not an agy 1.4.12 regression. Here `ahub --live-test --project <scratch> agy` writes the managed plugin and holds the slot, as the person's launch does.
|
|
10
|
+
|
|
11
|
+
## Environment and isolation
|
|
12
|
+
|
|
13
|
+
- Native: the installed `~/.local/bin/agy`, `--version` `1.4.12`. SHA-256 `34423fc9b0af3841e7646aa72a2d40ffeab8218b22d1cb99eac7355f9eba31e3` before and after the run; the directory held the same two entries (`agy`, `agy.<n>.old`) before and after. The binary was not touched, and `AGY_CLI_DISABLE_AUTO_UPDATE=1` was set on every agy invocation.
|
|
14
|
+
- Launcher: this repository at `9eb10e34e8fa3624669d08828ac0ca65b8ec2041` (agent-hub 0.29.0, agent-mem 0.20.1), `src/cli/main.js --live-test --project <scratch> agy`, Bun 1.4.3, macOS 27.0.1 arm64. The committed plugin bundle was the one the daemon reported.
|
|
15
|
+
- Scratch daemon: started in the probe process with `startDaemon` on a loopback control port, in a disposable Git project under the per-user temporary directory (outside the person's home). Memory and native capture, inference, snapshots, MLX, design specs and Pi auto-start were off; `agy` was on the roster. The nonce `T0_LAUNCHER_NONCE_<uuid>` was held only in the scratch bus preface (`bus.preface("agy", ...)`).
|
|
16
|
+
- Every process had `HOME`, `AGENTHUB_HOME`, `AMEM_HOME`, `AGENTHUB_STATE_DIR`, `AGENTHUB_PROJECT_DIR`, `TMPDIR` and `XDG_CONFIG_HOME` set to scratch paths before any hub module loaded. The shell's live-hub locations were never used and the live hub was never contacted. The inherited agent marker stayed in place, as the live-test procedure requires.
|
|
17
|
+
- **Seatbelt:** agy itself ran under the `profile()` from `src/local/sandbox.ts` plus an explicit read/write deny of the person's home, through a `PATH` shim that `exec`s `sandbox-exec -f <profile> agy`. The launcher (`ahub agy`) and `bun` ran outside it. Checks: under the profile `cat` of the real `~/.gemini/config/config.json` exited 1 with `Operation not permitted`, and `/usr/bin/true` exited 0. The provider was a loopback fixture (`GEMINI_API_KEY=fixture-key`, `GOOGLE_GEMINI_BASE_URL` on loopback). No account and no cloud model call.
|
|
18
|
+
- The five real Gemini config entries (`antigravity-cli/settings.json`, `config/config.json`, `config/mcp_config.json`, `config/import_manifest.json` (absent), legacy `settings.json`) had the same SHA-256 or absence before and after.
|
|
19
|
+
- The daemon stopped, the fixture server stopped, no agy or scratch process remained. The original probe copies were not edited; the new probe lives in the local scratch workspace only.
|
|
20
|
+
|
|
21
|
+
## Result
|
|
22
|
+
|
|
23
|
+
| Observation | Value |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Launcher exit | 0, after `/exit` and Enter; agy closed by itself and printed its resume line |
|
|
26
|
+
| Managed plugin while the TUI ran | `hooks.json`, `mcp_config.json`, `plugin.json` |
|
|
27
|
+
| Managed plugin after the close | empty: all three removed |
|
|
28
|
+
| Peers on the scratch bus | exactly `agy` (state `idle`); no `agy~...` session |
|
|
29
|
+
| Provider requests | 4; tool declarations 0, 12, 15, 15 (`call_mcp_tool` from the second agent request, the lazy attach of 1.4.7 and 1.4.3) |
|
|
30
|
+
| MCP call | one `call_mcp_tool` for `agent-hub_agent-hub/hub_inbox`; the TUI printed `Called 1 MCP tool (agent-hub_agent-hub/hub_inbox)` |
|
|
31
|
+
| Hub log | `agy read 1 queued message(s) through hub_inbox` (the preface), then `agy -> idle`, later `agy -> offline` |
|
|
32
|
+
| **Nonce readback** | **`nonceInModelRequest: true`**: the nonce from the scratch bus preface appeared in a provider request after the tool call |
|
|
33
|
+
|
|
34
|
+
## Not verified
|
|
35
|
+
|
|
36
|
+
- A real account, a real model's tool choices and agy's own permission prompts (the provider is a fixture).
|
|
37
|
+
- `hub_send` and board calls through the TUI, the IDE form and Linux.
|
|
38
|
+
- Seatbelt around the launcher itself: only agy ran under it.
|
|
39
|
+
|
|
40
|
+
## Promotion
|
|
41
|
+
|
|
42
|
+
`src/adapters/compat.ts` adds `1.4.12` to agy `verified` and points `receipt` at this file; `test/agy-compat-receipt.test.ts` and `test/compat.test.ts` pin both. Other 1.4.x patches stay in-line and unverified; 1.5.0 stays refused.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Antigravity 1.4.12 account-free T0 re-run
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Task #681, Refs #485. This repeats the account-free CLI, print/plugin/hook and interactive-close legs of the [1.4.7 receipt](2026-10-26-agy-1.4.7.md) against the installed 1.4.12.
|
|
4
|
+
|
|
5
|
+
**Decision: do not add 1.4.12 to `verified`.** CLI surface, the synthetic MCP/native-read hook contract and normal TUI close passed. The current-bundle actual-hub nonce leg did not pass. `src/adapters/compat.ts`, `test/agy-compat-receipt.test.ts` and the smoke version line remain unchanged. This receipt does not establish that the failed leg is an agy regression; the host/bundle and producer setup also changed since the 1.4.7 run.
|
|
6
|
+
|
|
7
|
+
## Isolation and exact executable
|
|
8
|
+
|
|
9
|
+
- Native version: `1.4.12`, exit 0. Executable: the installed `~/.local/bin/agy`, SHA-256 `34423fc9b0af3841e7646aa72a2d40ffeab8218b22d1cb99eac7355f9eba31e3`. Its bytes matched before the first invocation, after each producer and after the last invocation. The person's decision was to retain this installed version; no install, update or downgrade was performed.
|
|
10
|
+
- Host: macOS 27.0.1 arm64; native producer/interpreter: Bun 1.4.3. Source and committed bundle: `a51c8fc708eda19cc57c20b1084b3978c2ec5d54`, agent-hub 0.29.0. A local `dot admit`-admitted `bun install --frozen-lockfile` preceded the probes; the installed `@staix/agent-mem` version was asserted equal to the exact 0.20.1 manifest pin.
|
|
11
|
+
- Every agy invocation set `AGY_CLI_DISABLE_AUTO_UPDATE=1`, including CLI surface and `mcp list`, print mode and TUI. Each producer had a fresh controller HOME and each native run a fresh HOME/tool-home/project/temp tree, all under `getconf DARWIN_USER_TEMP_DIR`. No credentials or native settings were copied from the real home.
|
|
12
|
+
- Each native child used the `profile()` implementation from `src/local/sandbox.ts`, followed by an explicit real-home read/write deny. Narrow read/execute exceptions covered only the native executable, Bun and the committed bundle directory. Write grants covered only the scratch paths. Egress was limited to the loopback provider fixture and, for actual-hub runs, the scratch daemon's control port. This is the probe's sandbox, not a claim about ordinary native agy confinement.
|
|
13
|
+
- An explicit controller environment replaced inherited agent markers. `AGENTHUB_HOME`, `AMEM_HOME`, `AGENTHUB_STATE_DIR` and `AGENTHUB_PROJECT_DIR` named scratch locations before hub modules loaded; every native child also had explicit scratch hub paths. The shell's live-hub locations were never used. Scratch daemons had memory/native capture, inference/triage, snapshots, MLX, Pi auto-start and design specs disabled, with agy roster admission enabled.
|
|
14
|
+
- Isolation checks opened the real Gemini settings file read-only and attempted an `O_WRONLY` open of the native binary, without `O_TRUNC` or any write. Both were denied with `Operation not permitted`. Thus even an unexpected write-open guard failure could not have changed binary bytes.
|
|
15
|
+
- The five named real Gemini config entries below matched before and after. Every completed producer removed its native temporary root; both scratch daemons stopped. A fresh final process-table inspection found no remaining native/probe process from this series.
|
|
16
|
+
|
|
17
|
+
## Producer copies and setup corrections
|
|
18
|
+
|
|
19
|
+
The three originals under `scratchpad/temp/agent-hub-267/` were hashed before copying and again after the series; all were unchanged. Only new copies under `scratchpad/temp/agent-hub-681/` were adapted:
|
|
20
|
+
|
|
21
|
+
- `actual-hub-adapted.ts`: current worktree/Bun/bundle paths, disabled updater, explicit scratch hub paths, disabled unrelated daemon features, captured hook rows.
|
|
22
|
+
- `native-hooks-adapted.ts`: current paths and isolation above; hooks moved in the copy from the older project-level `.agents/hooks.json` location to the fixture plugin's `.agents/plugins/agent-hub/hooks.json`. The MCP server remained a synthetic stand-in, never this project's hub.
|
|
23
|
+
- `tui-actual.ts`: current paths/isolation, two prompt steps and a normal `/exit` plus Enter close. The copied harness recorded `signalFallbackNeeded` separately; only a still-running child could receive a fallback signal.
|
|
24
|
+
- The CLI surface helper reused the copied actual-hub producer's profile and bounded child cleanup. One initial setup observation used Bun's `userInfo().homedir` under the isolated HOME, which named the scratch home rather than the real home. It was discarded as real-home guard evidence. All copies then pinned the controller's actual real-home path in the deny/hash inventory; the corrected CLI guards above tested the actual real files.
|
|
25
|
+
|
|
26
|
+
No source, timeout ceiling, native approval rule or product identity guard was changed to make a native leg pass. The CLI/print child bound remained 25 seconds. `/exit` was given its bounded normal-close window, with fallback recorded rather than counted as a pass.
|
|
27
|
+
|
|
28
|
+
## CLI surface
|
|
29
|
+
|
|
30
|
+
| Probe | Observation |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `--version` | `1.4.12`, exit 0 |
|
|
33
|
+
| `--help` and `help` | Exit 0; flags the launcher uses/refuses are still present, including `--continue`, `--conversation`, `--disable-slash-commands`, `--input-format`, `--output-format`, `--print`, `--prompt-interactive`, `--project`, `--remote-control` and `--sandbox` |
|
|
34
|
+
| `--acp` | Exit 2, `flags provided but not defined: -acp` |
|
|
35
|
+
| `--new` | Exit 2, `flags provided but not defined: -new` |
|
|
36
|
+
| Subcommands | `agent`, `agents`, `changelog`, `help`, `install`, `mcp`, `mic-serve`, `models`, `plugin`, `plugins`, `remote-control`, `update`; no ACP subcommand |
|
|
37
|
+
| Workspace-plugin `mcp list` | Exit 0, `No MCP servers configured.`, while the subsequent synthetic fixture run successfully discovered and called the plugin's tools |
|
|
38
|
+
|
|
39
|
+
## Synthetic plugin MCP and hook contract: passed
|
|
40
|
+
|
|
41
|
+
The print-mode loopback Gemini fixture replayed two MCP calls and a native read. No real account or cloud model turn was used. The MCP server returned fixture text only; its `hub_review` response was not a board review or approval.
|
|
42
|
+
|
|
43
|
+
- Native process exit 0, empty stderr. Plugin-local discovery recorded `server/discover`, `initialize`, `notifications/initialized`, `tools/list`, `tools/call`, `tools/call`.
|
|
44
|
+
- The two calls were `hub_task_show` with `id: 1` and `hub_review` with fixture-only arguments. Native `call_mcp_tool` retained `ServerName`, `ToolName` and `Arguments`; no `toolSummary`/`toolAction` was supplied.
|
|
45
|
+
- The native read remained `read_file` with `Path`, `StartLine` and `EndLine`, reading the scratch canary. No decoder change was made.
|
|
46
|
+
- All six plugin-local phases fired: `SessionStart`, `PreInvocation`, `PreToolUse`, `PostToolUse`, `PostInvocation`, `Stop`. Tool phases used `matcher: ".*"` with a nested hooks array.
|
|
47
|
+
- Shared hook stdin fields remained `artifactDirectoryPath`, `conversationId`, `lastUserInput`, `modelName`, `transcriptPath`, `workspacePaths`. Invocation phases added `initialNumSteps` and `invocationNum`; tool phases included `stepIdx` and `toolCall: {name, args}`, with an empty `error` on successful post-tool events.
|
|
48
|
+
- `Stop` reported `executionNum: 0`, `terminationReason: NO_TOOL_CALL`, empty `error`, and `fullyIdle: true`. The fixture's `SessionStart`/`PreInvocation` `injectSteps` ephemeral messages were accepted.
|
|
49
|
+
- Init listed 60 tools and `permission_mode: request-review`. The provider-facing declaration set remained the same 15 as 1.4.7: `ask_question`, `call_mcp_tool`, `define_subagent`, `edit_file`, `invoke_subagent`, `list_resources`, `manage_subagents`, `manage_task`, `read_file`, `read_resource`, `run_command`, `schedule`, `search_web`, `send_message`, `write_file`.
|
|
50
|
+
- Native output SHA-256: `be8d2db8393eea858058990ca90a7535c4440466d425a5f2b43d5c46a0fc9d81`. Real config inventory matched; the temporary root was removed.
|
|
51
|
+
|
|
52
|
+
## Actual scratch-hub nonce readback: failed
|
|
53
|
+
|
|
54
|
+
The actual-hub producer used the committed bundle and a nonce held only in the scratch bus preface. Its success criterion was delivery of that nonce into a later loopback provider request, not merely a native exit 0 or a tool declaration.
|
|
55
|
+
|
|
56
|
+
| Attempt | Observed result |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| Original copied bundle argv (`bun run <bundle>`) | Exit 0, empty stderr, three provider requests, one `call_mcp_tool` for `agent-hub_agent-hub/hub_inbox`; all six hooks fired. The bundle joined as a distinct `agy~...` session, returned a notice that it was not the project's agy, and did not return the canonical agy preface. `nonceInModelRequest: false`. |
|
|
59
|
+
| Explicit bundle-cwd variant (`bun --cwd <scratch-project> run <bundle>`) | Exit 0, empty stderr, two provider requests, zero MCP calls; only session/invocation/Stop hooks fired. `nonceInModelRequest: false`. |
|
|
60
|
+
|
|
61
|
+
The explicit-cwd variant addressed the current channel-project contract's requirement that the bundle process run at the project root; it did not bypass that identity check or force a model call to an undeclared tool. It still did not establish nonce readback. The first attempt's native output SHA-256 was `ba584c0ca2d301570576ae12699cffa2b41150d340fa0f8670c9a39cc0979558`; the explicit-cwd variant's was `037da39333e4439f03d9acb09ed998ef725d225837c5ba32cabceed07d44256e`.
|
|
62
|
+
|
|
63
|
+
These are recorded as failed acceptance evidence for this re-run. No claim is made that the identity notice or absent tool is caused by the 1.4.12 binary: this producer was originally written for an older hub, and the current bundle's project/session admission is another variable. No additional native retry was used to manufacture a green result.
|
|
64
|
+
|
|
65
|
+
## Interactive TUI and normal close
|
|
66
|
+
|
|
67
|
+
The explicit bundle-cwd variant was used for the interactive PTY, with fresh-HOME onboarding, then two prompts and `/exit` followed by Enter.
|
|
68
|
+
|
|
69
|
+
- The native TUI exited on its own with code 0 and printed its resume command. `signalFallbackNeeded: false`; no signal was sent to close it. The scratch daemon stopped and the native temporary root was removed.
|
|
70
|
+
- Provider declaration counts were 0, 12 and 12. Neither prompt exposed `call_mcp_tool`; MCP call count was zero and `nonceInModelRequest` was false. Only `SessionStart`, invocation phases and `Stop` were observed in this actual-bundle TUI run. Thus the normal-close sub-leg passed, while interactive actual-hub delivery did not.
|
|
71
|
+
- PTY output SHA-256: `e096b2f2f84d665c4c4dc7be7b2408c585f9743a1f5839410a93040e4abf2945`.
|
|
72
|
+
- This directly launches the native TUI in a disposable fixture. It does not verify `ahub agy`'s launch-slot release or managed-file cleanup, which belongs to the separate #443 receipt.
|
|
73
|
+
|
|
74
|
+
## Real configuration inventory
|
|
75
|
+
|
|
76
|
+
The controller hashed only the following named real `~/.gemini` files, without publishing their contents. The recorded digest/absence matched after every producer and at the end; this is not an inventory of every possible native file.
|
|
77
|
+
|
|
78
|
+
| File | Before and after SHA-256/absence |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `antigravity-cli/settings.json` | `bb14f0a81a8239c6b988873e63fdd4f55fd6c822dc695c5138e5253424df276d` |
|
|
81
|
+
| `config/config.json` | `b8c51361bf83a00ae5e38b3108b48ffa3b4cfc7c4e9d9b7d16e04f74725f3c14` |
|
|
82
|
+
| `config/mcp_config.json` | `d8e397af03b5b032f21d0aa967086f0c78b33c87b76f2e9898ae0a144df7de02` |
|
|
83
|
+
| `config/import_manifest.json` | Absent |
|
|
84
|
+
| Legacy `settings.json` | `66c879018049d90632634790fe0b0eae54616a144e594c5db1b40b7c8be8c7b9` |
|
|
85
|
+
|
|
86
|
+
## Evidence boundary and follow-up
|
|
87
|
+
|
|
88
|
+
The native print/hook fixture and normal close are established above; real-account behavior, a real model's tool choices, permission-prompt overrides, Stop continuation, IDE behavior and Linux native behavior remain unverified. Most importantly, actual-hub nonce delivery on the current bundle is not established. Diagnose the disposable producer's project identity/MCP startup path before another promotion attempt; preserve the real-home deny, updater-off environment, live-hub path override and nonce assertion.
|
|
89
|
+
|
|
90
|
+
The changed repository gate runs on the committed receipt head via dgx02; its exact SHA and result are recorded in the PR/task submission. Hosted CI is a separate gate. This receipt leaves 1.4.12 as an unverified, in-line patch, with the accepted 1.4.x line and existing verified versions unchanged.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Antigravity TUI close through `ahub agy` (#485)
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Refs #485, task #443. This is the launcher leg the [1.4.7 receipt](2026-10-26-agy-1.4.7.md) left open: the hub's own `ahub agy` launch, the launch slot while the TUI runs, and what the launcher does when the TUI is closed normally. The earlier receipts closed agy by hand under a probe. This one runs the real `ahub agy` against a real scratch daemon.
|
|
4
|
+
|
|
5
|
+
## Environment and isolation
|
|
6
|
+
|
|
7
|
+
- Hub CLI and daemon: `ahub` 0.29.0, started with `ahub --live-test --project <scratch> up --no-agents --no-console` in a disposable Git project under the per-user temporary directory (outside the person's home). The scratch `status.json` named the scratch project root as `cwd`. The CLI's own `status` was refused for the agent identity, so that file was read instead. `jcode` was put on the scratch roster for a moment while diagnosing this and removed again. Memory and inference were off in the scratch config. `agy` was on that project's roster; no other peer was started.
|
|
8
|
+
- Every command had `HOME`, `AGENTHUB_HOME`, `AGENTHUB_STATE_DIR`, `AGENTHUB_PROJECT_DIR`, `TMPDIR` and `XDG_CONFIG_HOME` set to scratch paths. The inherited agent markers were left in place, as the live-test procedure requires, and the launcher ran under `--live-test` delegation. The live hub of this repository was not contacted.
|
|
9
|
+
- agy ran the interactive TUI on a PTY with `GEMINI_API_KEY=fixture-key` and `GOOGLE_GEMINI_BASE_URL` pointing at a loopback fixture provider (the 1.4.7 receipt's design: fixed `hub_inbox` call once the model lists `call_mcp_tool`, then a fixed text answer). No account and no cloud model call. Fresh-HOME onboarding was answered with the same keys (Enter, Down, Right, Enter, Enter). The scratch settings pre-allowed `mcp(agent-hub_agent-hub/hub_inbox)`.
|
|
10
|
+
- **No Seatbelt was used around `ahub agy`** (the 1.4.7 receipt did use it). Isolation here rests on the scratch environment above and on the real-config hashes below.
|
|
11
|
+
- Bystander files the launcher must not touch were placed in the scratch project: `.agents/plugins/other/plugin.json` and `.agents/rules/r.md`.
|
|
12
|
+
- The person's real Gemini files were hashed before and after every run: `~/.gemini/antigravity-cli/settings.json`, `~/.gemini/config/config.json`, `~/.gemini/config/mcp_config.json`, `~/.gemini/settings.json` (and `config/import_manifest.json`, absent on this machine). Equal before and after in every run. The real `~/.gemini/antigravity-cli` directory did change during the window (new log files, `cli.log`, `conversation_summaries.db`, `builtin/`), and the real-config hashes are the evidence that my runs did not write there. The new entries are consistent with other agy processes on the machine: their logs show workspace `/` and the real app-data directory, while every agy run of this receipt logged the scratch project and the scratch app-data directory under its own HOME.
|
|
13
|
+
|
|
14
|
+
## Facts (final run, agy 1.4.12; the same legs also passed in an earlier run, see below)
|
|
15
|
+
|
|
16
|
+
| Leg | Observation |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| Slot is held during the launch, before agy attaches | `ahub agy` was started a second time seconds after the first, with the first still starting its TUI: exit 1, `a managed native launch is already active; end it in its terminal first`. The three managed files were still present. |
|
|
19
|
+
| Slot is held while the TUI runs | After the first prompt was answered, a second `ahub agy`: exit 1, `native peer is already attached; end it in its terminal first`. The three managed files were still present. |
|
|
20
|
+
| Launcher wrote the managed plugin | While the TUI ran, `.agents/plugins/agent-hub/` held exactly `hooks.json`, `mcp_config.json`, `plugin.json`. |
|
|
21
|
+
| Hub tools worked through the plugin | The plugin MCP server attached lazily: provider requests listed 0, 12, then 15 tools (`call_mcp_tool` from the second agent request), `call_mcp_tool` ran `hub_inbox` once and the TUI printed the fixture answer. The hub log shows `agy` going `idle`, `busy`, `idle`. |
|
|
22
|
+
| Normal close | `/exit` and Enter in the TUI: `agy` exited by itself, the `ahub agy` process exited 0, and agy printed its resume line. No signal was sent. The hub log shows `state agy -> offline`. |
|
|
23
|
+
| Plugin cleanup | After the close `.agents/plugins/agent-hub/` was an empty directory: the three managed files were removed. |
|
|
24
|
+
| Bystanders unchanged | SHA-256 of `.agents/plugins/other/plugin.json` and `.agents/rules/r.md` equal before and after. |
|
|
25
|
+
| Slot is released | A second full launch right after the first close was admitted: three managed files written, TUI ran a prompt, `/exit` closed it with exit 0, the files were removed again, the bystanders were unchanged again. |
|
|
26
|
+
| Real config | The five real-config hashes were equal before and after the run. |
|
|
27
|
+
| Cleanup | `ahub --live-test --project <scratch> down` reported `hub stopped`. No `agy` process and no scratch hub process remained. |
|
|
28
|
+
|
|
29
|
+
An earlier complete run (the first two-cycle run, agy 1.4.7 for the first cycle and 1.4.12 for the second, after the binary was replaced, see below) gave the same results for the held slot after attach, the normal close, the cleanup, the second admitted cycle, the bystanders and the real-config hashes.
|
|
30
|
+
|
|
31
|
+
## Other observations
|
|
32
|
+
|
|
33
|
+
- **Closing while a native approval is pending.** Two earlier runs typed `/exit` while the fixture's `hub_inbox` call was waiting on agy's native approval prompt (the scratch settings did not yet pre-allow it). agy did not exit within 15 s, the probe sent SIGTERM, `ahub agy` forwarded it, the slot was released and the managed files were removed. The next launch after that kill was admitted. Neither run is the normal-close leg above; they only show that the signal path also ends in a released slot and removed files.
|
|
34
|
+
- The launcher printed `agy 1.4.12 is untested (verified 1.4.2, 1.4.7; compatible: the 1.4.x line); launching on the compatible line`, as designed (#589). `src/adapters/compat.ts` is unchanged by this receipt: 1.4.12 has no T0 receipt and stays unverified.
|
|
35
|
+
|
|
36
|
+
## Side effect on the machine: agy replaced its own binary
|
|
37
|
+
|
|
38
|
+
The first scratch run started agy 1.4.7 with a scratch HOME and without `AGY_CLI_DISABLE_AUTO_UPDATE`. agy spawned its background updater, which replaced the person's `~/.local/bin/agy` (a path the scratch HOME does not isolate) with 1.4.12 and kept the previous binary beside it as `agy.<n>.old`. The kept binary has SHA-256 `b7a13e53c9f49921692676ef8edc2e60ceb67064c00bc732d9a364ec3ad75b32`, the 1.4.7 hash recorded in the 1.4.7 receipt. The new binary's SHA-256 is `34423fc9b0af3841e7646aa72a2d40ffeab8218b22d1cb99eac7355f9eba31e3`. The real Gemini configuration files were not touched. Setting `AGY_CLI_DISABLE_AUTO_UPDATE=1` for any further live agy run prevents this; the smoke ledger now says so. Rolling back is the person's choice.
|
|
39
|
+
|
|
40
|
+
## Not verified
|
|
41
|
+
|
|
42
|
+
- A real account, a real model turn and agy's own permission prompts (the provider was a fixture).
|
|
43
|
+
- `hub_send` and a board read or proposal through the TUI: only `hub_inbox` was called. AC3 of #485 names all three, so the issue stays open.
|
|
44
|
+
- The IDE form, Linux, and a Seatbelt-wrapped `ahub agy`.
|
|
45
|
+
- A launch of the verified 1.4.7 build from start to finish: the first cycle of the earlier run was 1.4.7 and the final run was 1.4.12.
|
|
46
|
+
|
|
47
|
+
## Decision
|
|
48
|
+
|
|
49
|
+
The hub launcher's own close leg holds on the 1.4.x line in a scratch project: the launch slot is held while agy starts and runs, a normal TUI close releases it so the next launch is admitted, the three managed plugin files are the only thing removed, and the person's real Gemini configuration hashes are unchanged. This does not close #485 on its own (see Not verified), so the pull request says `Refs #485`.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Grok 1.0.62 project MCP and hooks T0, 2026-11-03
|
|
2
|
+
|
|
3
|
+
T0 receipt for #635, task #325. This probes the project-file TUI alternative to the [earlier ACP receipt](2026-10-21-grok-config-acp-t0.md). It does not establish launcher implementation, model-backed delivery, or native turn-end readiness.
|
|
4
|
+
|
|
5
|
+
## Result
|
|
6
|
+
|
|
7
|
+
| Leg | Result | Direct evidence |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Pinned native version | VERIFIED | `--version` exited 0: `grok 1.0.62 (1474f9cbdd91)` |
|
|
10
|
+
| Project MCP configuration discovery | VERIFIED | `mcp list --json` reported `receipt`, `scope: project`, from `.grok/config.toml` |
|
|
11
|
+
| Project MCP trust gate and connection | VERIFIED, synthetic server only | Untrusted doctor refused to start the server; after an isolated fixture trust grant, doctor initialized it and discovered one tool |
|
|
12
|
+
| `search_tool` / `use_tool` to a hub tool | UNVERIFIED | Both credential-free `--single` attempts exited 1 with `Not signed in`; no `tools/call` was recorded |
|
|
13
|
+
| Interactive trust prompt | UNVERIFIED | An untrusted PTY startup reached sign-in before any folder-trust prompt; authentication discovery could not proceed with network denied |
|
|
14
|
+
| Hook configuration load | VERIFIED | Trusted `inspect --json` listed seven configured project event handlers, including `stop`; untrusted inspect listed none |
|
|
15
|
+
| Hook firing and stdin payloads | UNVERIFIED | No credential-free model/session turn began, and the passive payload sink was never created |
|
|
16
|
+
| Real configuration preservation | VERIFIED for nine named files | Before/after SHA-256 or absence matched for every entry listed below |
|
|
17
|
+
|
|
18
|
+
Decision for the following launcher task: the pinned build recognizes a main-session `Stop` hook configuration, separately from `SubagentStop`. This is loader evidence, not evidence that a successful main turn fires it or that its payload is sufficient for hub facts/turn end. Keep the proposed peer pull-only unless a later isolated authenticated receipt proves main-turn completion and its payload. Do not infer hook absence from the account refusal, or turn-end support from configuration load alone. #635 stays open.
|
|
19
|
+
|
|
20
|
+
## Isolation and preparation
|
|
21
|
+
|
|
22
|
+
- Base checkout: `df230f2c89d0545c1a87cfd6bb8be57505a92c6c`. Branch: `test/635-grok-t0`; dedicated worktree `.worktrees/test-635-grok-t0`.
|
|
23
|
+
- Before native probes, dgx02 ran `bun install --frozen-lockfile` at that base and asserted the installed first-party dependency against `package.json`: `@staix/agent-mem@0.20.1`. No repository runtime or inherited local `node_modules` was used by the native probes; the MCP fixture used only system Python.
|
|
24
|
+
- The native executable was copied as one file from the installed Grok binary into a private OS-temporary root. Its SHA-256, before and after the probes, was `ec434e831afdcfce87780f2815fd732b1df8a4a8de96a491716ad75d13605a4e`.
|
|
25
|
+
- Separate empty directories were supplied as `HOME`, `GROK_HOME`, `XDG_CONFIG_HOME`, `XDG_CACHE_HOME`, `XDG_DATA_HOME` and `TMPDIR`. A new throwaway Git project held the project MCP/hooks files; a second sibling project was used for the untrusted TUI probe.
|
|
26
|
+
- The child environment was an explicit allowlist: those six directories, a scratch/system-only `PATH`, `SHELL=/bin/sh`, `TERM=xterm-256color`, `LANG=en_US.UTF-8`, `USER=probe`, `LOGNAME=probe` and `NO_COLOR=1`. No account variables, inherited agent markers or personal configuration were copied.
|
|
27
|
+
- Every Grok invocation ran through macOS `sandbox-exec`, denying network, reads/writes under the person's real home, writes under `/etc` and `/Library`, and access to the securityd Mach service. Before the TUI probe, execution of `/usr/bin/open` and `/usr/bin/osascript` was also denied. These are probe controls, not a product sandbox claim.
|
|
28
|
+
- Stateful commands explicitly passed `--no-leader --no-auto-update`. The subprocess harness bounded each command to 12 seconds, then signalled only its newly created process group. The PTY observation window was five seconds. No Grok process remained in the final fresh process-table read.
|
|
29
|
+
- The first PTY capture harness had an EOF-drain bug after its native child exited: the Python harness stayed alive reading EOF. Only that identified probe-owned harness was terminated; EOF handling was corrected before the second capture. No native completion or teardown result is inferred from the discarded first capture.
|
|
30
|
+
|
|
31
|
+
## Project MCP and trust
|
|
32
|
+
|
|
33
|
+
The project's `.grok/config.toml` contained this self-contained fixture (`$PROBE_ROOT` below means the absolute temporary root substituted before writing TOML):
|
|
34
|
+
|
|
35
|
+
```toml
|
|
36
|
+
[mcp_servers.receipt]
|
|
37
|
+
command = "/usr/bin/python3"
|
|
38
|
+
args = ["$PROBE_ROOT/tools/mcp.py"]
|
|
39
|
+
startup_timeout_sec = 3
|
|
40
|
+
[mcp_servers.receipt.env]
|
|
41
|
+
PROBE_LOG = "$PROBE_ROOT/evidence/mcp-events.jsonl"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The synthetic stdio MCP server answered `initialize` using the requested protocol version, declared a tools capability and `serverInfo` of `isolated-receipt-fixture` / `1.0.0`, and answered `tools/list` with one tool named `hub_inbox`. Its description and possible result explicitly said synthetic fixture. It was not a production hub, did not attach to this repository's running daemon and did not establish a real hub-tool result.
|
|
45
|
+
|
|
46
|
+
Observed command sequence after fixture creation:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
grok --no-leader --no-auto-update inspect --json
|
|
50
|
+
grok --no-leader --no-auto-update mcp list --json
|
|
51
|
+
grok --no-leader --no-auto-update mcp doctor receipt --json
|
|
52
|
+
grok --no-leader --no-auto-update --trust inspect --json
|
|
53
|
+
grok --no-leader --no-auto-update mcp doctor receipt --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Every command above used the copied binary, isolated environment and sandbox wrapper. Before trust, inspect reported `projectTrusted: false` and `hooks: []`; MCP list still enumerated the project definition. Untrusted doctor exited 1 and reported:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
folder untrusted
|
|
60
|
+
repo-local (project-scoped) server not started for an untrusted folder
|
|
61
|
+
re-run with --trust to allow repo-local servers
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The explicit `--trust` was a controlled grant to this disposable fixture, not launcher behavior or a grant to a real project. It persisted only in the isolated `$GROK_HOME/trusted_folders.toml`:
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[folders."$PROBE_ROOT/project"]
|
|
68
|
+
trusted = true
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Afterward, trusted inspect reported `projectTrusted: true`. Doctor exited 0 with `command found`, `server started`, `handshake OK` (`protocol 2025-11-25`) and `1 tools discovered`; `healthy_count: 1`, `failing_count: 0`. The fixture recorded exactly:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
initialize
|
|
75
|
+
notifications/initialized
|
|
76
|
+
tools/list
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Initialize's `clientInfo` was `grok-shell-receipt` / `1.0.62`. No `tools/call` occurred. A discovered tool is not proof of the model's meta-tool path.
|
|
80
|
+
|
|
81
|
+
## Model/tool and interactive prompt limits
|
|
82
|
+
|
|
83
|
+
Before and after the isolated trust grant, bounded single-turn commands requested the fixture hub tool. The trusted request was:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
grok --no-leader --no-auto-update \
|
|
87
|
+
--single 'Find receipt__hub_inbox with search_tool, call it with use_tool, and report its result.' \
|
|
88
|
+
--max-turns 1 --disable-web-search --no-memory
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Both attempts exited 1, without a model turn or hook payload, and reported:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
Not signed in. To authenticate without a browser, run:
|
|
95
|
+
grok login --device-code
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
An initial syntax-only attempt incorrectly supplied `--single` without its required adjacent prompt value and exited 2; it is not a model/tool probe result. The corrected commands above are the evidence.
|
|
99
|
+
|
|
100
|
+
A separate untrusted project was launched under a PTY using `--no-leader --no-auto-update --no-alt-screen --minimal --no-memory`. It displayed sign-in and an authentication discovery failure for `https://auth.x.ai/.well-known/openid-configuration`, then exited 0. No folder-trust prompt was observed, no sibling trust entry appeared, no browser execution was permitted, and no hook payload was produced. Exit 0 here does not prove a successful session. No personal account, cached token, API key or real-home fallback was used; these legs stop at authentication.
|
|
101
|
+
|
|
102
|
+
The locally shipped MCP guide documents qualified `server__tool` catalog keys and `search_tool` / `use_tool`, so `receipt__hub_inbox` was the requested key. That documented route remains UNVERIFIED in a native model turn. To finish this leg, use an independently authorized account in a fresh isolated home and a disposable real hub, then capture the meta-tool dispatch and the actual hub result; do not reuse the person's home.
|
|
103
|
+
|
|
104
|
+
## Hooks and payloads
|
|
105
|
+
|
|
106
|
+
The fixture `.grok/hooks/receipt.json` registered command handlers for `SessionStart`, `UserPromptSubmit`, `Stop`, `StopFailure`, `StopCancelled`, `SessionEnd` and `SubagentStop`. Each handler used the same passive script, with a two-second hook timeout:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
#!/bin/sh
|
|
110
|
+
/bin/cat >> "$PROBE_ROOT/evidence/hook-payloads.jsonl"
|
|
111
|
+
/bin/echo >> "$PROBE_ROOT/evidence/hook-payloads.jsonl"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The actual generated script contained the absolute sink path. It did not deny actions or invent events. Trusted inspect listed these native event names:
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
session_start
|
|
118
|
+
user_prompt_submit
|
|
119
|
+
stop
|
|
120
|
+
stop_failure
|
|
121
|
+
stop_cancelled
|
|
122
|
+
subagent_stop
|
|
123
|
+
session_end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The sink remained absent, so there are no observed hook stdin payloads to publish. In particular, this receipt has no observed `sessionId`, `hookEventName`, `lastAssistantMessage`, stop/interrupt discriminator or main-session/subagent binding. The shipped hooks guide describes `Stop` for genuine main-turn completion, `StopFailure` for API failure, `StopCancelled` for non-completion and `SubagentStop` for subagents, and documents camelCase fields plus compatibility aliases. These are documented hypotheses for the authenticated follow-up, not captured payload facts. Merely registering `SubagentStop` cannot establish main-turn completion.
|
|
127
|
+
|
|
128
|
+
The local shipped guide bytes consulted were identified by SHA-256 (their documentation content does not substitute for native runtime evidence):
|
|
129
|
+
|
|
130
|
+
| Guide | SHA-256 |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `07-mcp-servers.md` | `67558820ab3f0c49d56f87ce9d6927f2d6d179558f7a1e0466750a9771a43c3a` |
|
|
133
|
+
| `10-hooks.md` | `2a3a12201597fa6ab1885fa473096565a6c99fbfaf656627c65fa15653e14970` |
|
|
134
|
+
| `02-authentication.md` | `f16e7fe4cecc2836643d3474dbbc6c2b4a0ea12edf2b56b8a5a0a4ecb24efbec` |
|
|
135
|
+
|
|
136
|
+
## Real configuration hashes
|
|
137
|
+
|
|
138
|
+
Only the controller computed SHA-256/absence of these named real `~/.grok` files, without printing or copying their contents. Grok itself could not read that home. All nine entries matched after the final native probe. This is a bounded inventory, not a claim about every native configuration path.
|
|
139
|
+
|
|
140
|
+
| File | Before and after |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `config.toml` | `cbafbea937a8ad50323aed808e68912706a063c7c88868a8fd9f58252bb68f22` |
|
|
143
|
+
| `version.json` | `182eeb64f0fe20c17ddea37071954ff25b1424f3b807fea13697754c803439f7` |
|
|
144
|
+
| `trusted_folders.toml` | `4e9eee9a1a037d109d59ed1d8112795f55381465cd219266b2f1777d4ec8b945` |
|
|
145
|
+
| `auth.json` | SHA-256 matched; credential-file digest omitted from the public receipt |
|
|
146
|
+
| `config.json`, `settings.json`, `mcp.json`, `managed_config.toml`, `requirements.toml` | Absent before and after |
|
|
147
|
+
|
|
148
|
+
## Repository validation
|
|
149
|
+
|
|
150
|
+
The final committed receipt is checked with `scripts/check.sh --changed` on dgx02; the PR and task submission record the exact head and gate result. Hosted CI is independent. No compatibility registry, launcher, generated bundle or native support claim is changed by this documentation-only T0.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Pi 1.5.0 model-free compatibility receipt
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Task #684, Refs #888. This repeats the [Pi 1.4.0 receipt](2026-10-26-pi-140-compat.md) for the published `@earendil-works/pi-coding-agent@1.5.0`. Same legs, model-free, no account.
|
|
4
|
+
|
|
5
|
+
**Decision: add `1.5.0` to Pi `verified`.** Every leg passed. No range is inferred: the Pi entry still has no `line`, so any other version needs the person's `ahub agents trust pi <version>`.
|
|
6
|
+
|
|
7
|
+
## Identity and isolation
|
|
8
|
+
|
|
9
|
+
- Package: `@earendil-works/pi-coding-agent` 1.5.0, installed from the registry into a private npm prefix with a scratch HOME, cache and temporary directory and empty npm user and global config files. The person's `~/.pi` and global packages were not touched. npm held back two lifecycle scripts (`protobufjs` postinstall, a version-scheme warning, and `@google/genai` preinstall, an `echo`). They were read and judged inert for this probe, and were not replayed: the producer passed without them, and no flag was added to make it pass.
|
|
10
|
+
- npm integrity: `sha512-xNDZ5kqowO6Z03FS2gwAkPEGk1ssxVcYKQ6qZId84mFEvwACvvyc2l0vAMOS+c5zvxLRMLBE9r4y44IGYkMJaQ==`. The package carries no `gitHead`.
|
|
11
|
+
- Native `dist/cli.js` SHA-256: `8189b66abc4f9f431dbb70941dcba690d76d040de1fbfff212886be35a53639d`. This is the same value the 1.4.0 receipt records for its `dist/cli.js`, so the launcher entry file did not change between the two releases. The 1.5.0 changes are in other files of the package and are exercised by the legs below.
|
|
12
|
+
- Host: macOS arm64, Bun 1.4.3, Node 24.18.1, repository at `9eb10e34e8fa3624669d08828ac0ca65b8ec2041`.
|
|
13
|
+
- Each native run used an empty temporary HOME and `PI_CODING_AGENT_DIR`, a temporary cwd and session directory and an environment of PATH, those paths and invented loopback bridge settings. No account, token, prompt or inference.
|
|
14
|
+
- Real configuration: SHA-256 of every file under the person's `~/.pi/agent` (excluding sessions, logs, caches, installs and `bin`) and `~/.qwen`, plus the person's `pi` launcher binary and the listing of installed Pi releases, was taken before and after the producer run: 9551 entries, identical.
|
|
15
|
+
|
|
16
|
+
## Results
|
|
17
|
+
|
|
18
|
+
| Leg | Result | Evidence |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Native identity | pass | `--version` returned exactly `1.5.0`, exit 0, empty stderr; package name and version checked independently. |
|
|
21
|
+
| Real CLI extension load and RPC session identity | pass | `--mode rpc` with the hub extension: `get_state` succeeded with a session id and file, `messageCount` 0; the extension emitted `session_start` and `session_shutdown`. |
|
|
22
|
+
| Installed SDK extension registration | pass | The 1.5.0 `DefaultResourceLoader` and `createAgentSession` loaded this checkout's extension and registered exactly `compat_probe` as the active tool, with no builtin tools. |
|
|
23
|
+
| Managed tool callback and receipt replay | pass | The registered callback was invoked without a prompt and posted to the isolated bridge through the real `PiToolReceipts`; two identical calls returned identical success with one effect. |
|
|
24
|
+
| Failed tool result | pass | The bridge fixture denial returned `failed: true` and the extension returned `isError: true`. |
|
|
25
|
+
| Host permission modes | pass (host fixtures) | `test/permission-modes.test.ts` "Pi mode grants edits once, keeps shell on the console, and ask restores the console path": 1 pass, 12 assertions. |
|
|
26
|
+
| Version admission | pass (host fixtures) | `test/pi-compat.test.ts` and `test/compat.test.ts`: 43 pass, 0 fail. |
|
|
27
|
+
| Provider requests | pass | Zero requests reached the loopback provider; no prompt was submitted. Native and SDK stderr were empty. |
|
|
28
|
+
|
|
29
|
+
Producer result: `pi 1.5.0 model-free receipt: PASS`. The producer is the 1.4.0 one with the version constants and driver file name changed (`pi-150-model-free.ts`, `pi-150-native.mjs`); no assertion was relaxed.
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
bun docs/verification/pi-150-model-free.ts <prefix>/node_modules/.bin/pi <prefix>/node_modules/@earendil-works/pi-coding-agent
|
|
33
|
+
env -u AGENTHUB_HOME -u AGENTHUB_PROJECT_DIR -u AGENTHUB_STATE_DIR bun test test/pi-compat.test.ts test/compat.test.ts
|
|
34
|
+
env -u AGENTHUB_HOME -u AGENTHUB_PROJECT_DIR -u AGENTHUB_STATE_DIR bun test test/permission-modes.test.ts --test-name-pattern 'Pi mode grants'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Not verified
|
|
38
|
+
|
|
39
|
+
- Account-backed inference, a model-generated tool request, a real provider's quota behavior and interactive TUI coexistence. The SDK callback leg does not claim model-generated tool dispatch.
|
|
40
|
+
- Linux and Intel macOS. No other Pi release is inferred.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Pi 1.5.0 session-title API probe
|
|
2
|
+
|
|
3
|
+
Task #689, Refs #1055 (T1). Model-free native API receipt, macOS arm64, Node 24.18.1.
|
|
4
|
+
|
|
5
|
+
The installed `@earendil-works/pi-coding-agent@1.5.0` exposes a working native session-name setter and reader:
|
|
6
|
+
|
|
7
|
+
- Extension API: `setSessionName(name: string): void` and `getSessionName(): string | undefined`.
|
|
8
|
+
- Session: `AgentSession.setSessionName(name: string)` and the `sessionName` getter.
|
|
9
|
+
- Session manager: `appendSessionInfo(name: string)` and `getSessionName(): string | undefined`.
|
|
10
|
+
|
|
11
|
+
The [producer](pi-150-title-api.mjs) loads the real package's `DefaultResourceLoader`, `createAgentSession` and extension runner. It registers an account-free probe tool, invokes that callback directly after `bindExtensions`, and asserts the native API changes an initially unnamed session to `Fixture session title`. Both the extension reader and `SessionManager` return that name. After disposal, `SessionManager.open(sessionFile).getSessionName()` returns the same name. No prompt is submitted to an agent or provider.
|
|
12
|
+
|
|
13
|
+
The native setter appends a `session_info` entry. A handler registered through the real `ExtensionAPI.on("session_info_changed", handler)` receives the new name, also asserted by the producer. Pi delays creating a new session file until a user or assistant message exists. This probe appends a synthetic user fixture to the session manager before calling the setter; the fixture is never sent to a model. It proves native persistence for an existing conversation, not persistence of an empty session.
|
|
14
|
+
|
|
15
|
+
## Isolation and result
|
|
16
|
+
|
|
17
|
+
- Fresh HOME under `getconf DARWIN_USER_TEMP_DIR`, separate `PI_CODING_AGENT_DIR`, XDG config/data/cache and TMPDIR. The child environment contains only these paths, PATH and the explicit package path.
|
|
18
|
+
- Exact 1.5.0 package from the existing scratch npm prefix used by the [compatibility receipt](2026-11-03-pi-150-compat.md). The person's default launcher still selects 1.4.0; it was not invoked or changed.
|
|
19
|
+
- Frozen worktree dependencies installed before the probe: `@staix/agent-mem@0.20.1`, matching the exact manifest pin. Native package version independently asserted as 1.5.0.
|
|
20
|
+
- `sandbox-exec` uses `src/local/sandbox.ts`'s network-disabled profile, adds a real-home read/write deny, then grants only read access to the scratch native package and Node installation. Writable files are confined to the disposable HOME. No credentials or live hub connection.
|
|
21
|
+
- SHA-256 manifests of the 15 real `~/.pi` configuration/launcher entries were identical before and after. The manifest excludes sessions, logs, cache and install trees; it is not a claim to hash every installed package or historical session. Private per-file digests remain in the scratch evidence directory.
|
|
22
|
+
- Exit 0, empty stderr, setter/reader/reopen assertions PASS. An initial hand-written sandbox profile terminated Node before the producer ran; the final run used the repository profile and passed.
|
|
23
|
+
|
|
24
|
+
Reproduction: run `node docs/verification/pi-150-title-api.mjs` with `PI_TITLE_PACKAGE` pointing to the exact 1.5.0 package and fresh HOME/tool-home paths, inside the network-disabled sandbox described above. Do not run with the person's real HOME.
|
|
25
|
+
|
|
26
|
+
This permits the native-slot implementation for Pi. It does not prove a model-generated `hub_set_title` call, delivery through a live hub, or a live Pi restart. AC7 remains a separate live receipt in #1143.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Qwen Code 0.26.5 ACP receipt
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Task #684, Refs #888, `qwen` row only. This repeats the [0.26.4 ACP receipt](2026-10-31-qwen-0264-acp.md) on the published `@qwen-code/qwen-code@0.26.5`, with a private npm prefix, isolated HOME and fixed synthetic configuration. No account, real credential, provider inference or ACP prompt was used. It does not admit the separate `qwen-dual` contract (see the [dual-output receipt](2026-11-03-qwen-0265-dual-output.md)).
|
|
4
|
+
|
|
5
|
+
**Decision: add `0.26.5` to `COMPAT.qwen.verified`.** Every ACP leg passed. No intermediate release and no range is inferred. `latest` on npm is 0.26.6 today; it is not admitted.
|
|
6
|
+
|
|
7
|
+
## Artifact and isolation
|
|
8
|
+
|
|
9
|
+
The package was installed under the local scratch workspace in a private prefix with a scratch HOME, cache and temporary directory and empty npm user and global config files. The person's global prefix, `~/.qwen` and `~/.pi` were not installation targets. npm held one lifecycle script, `@qwen-code/audio-capture` `install` (`node install.js`). It was read, found to locate a prebuilt microphone addon with a non-fatal failure path, and replayed under the same isolated environment: exit 0. No install script was disabled to make the probe pass.
|
|
10
|
+
|
|
11
|
+
| Artifact | Binding |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| npm release | 0.26.5, `gitHead` and upstream `v0.26.5` tag `db0e4e24a0d89b211b2a15f4af2be22adac71dfc` |
|
|
14
|
+
| npm integrity | `sha512-iqcBqLQDmKvOtRcVvF78l7bf0NpdymGFBo0qNY0ausPezht+PLXkh15vnIILaBKtM4BabtHSv60xWftMomJ7hw==` |
|
|
15
|
+
| `cli-entry.js` SHA-256 | `113efe4104a9fc66f507d34bfd6abbd896ceb77de47f4b468a0825a327fdc6a5` (the same bytes as the 0.26.1 and 0.26.4 entry files: the entry is a loader, the code is in chunks) |
|
|
16
|
+
| `chunks/acpAgent-HO52UOPA.js` SHA-256 | `794bda74c4d100ab3367ae2e5d880ef0a610df4c84d1db1475d78283b75a8e1e` (the chunk name differs from 0.26.4's `acpAgent-D7OFGHAI.js`) |
|
|
17
|
+
| Host | macOS arm64, Node 24.18.1 |
|
|
18
|
+
|
|
19
|
+
Every native process received a fresh temporary HOME and cwd, private `QWEN_HOME`, `QWEN_RUNTIME_DIR` and `XDG_CONFIG_HOME`, a synthetic API key and `--auth-type openai --model fixture-model --openai-base-url http://127.0.0.1:9/v1 --telemetry=false`. The 0.26.4 receipt's Node preload denied application network APIs and recorded six blocked startup attempts here too; none connected through those guarded APIs. This is preload evidence, not a kernel network sandbox.
|
|
20
|
+
|
|
21
|
+
Real configuration: SHA-256 of every file under the person's `~/.qwen` and `~/.pi/agent` (excluding sessions, logs, caches, installs and `bin`) and of the globally installed qwen's `cli-entry.js` and `package.json` was taken before and after the producer runs: 9550 entries, identical.
|
|
22
|
+
|
|
23
|
+
## Native ACP, no prompts
|
|
24
|
+
|
|
25
|
+
`qwen --acp --bare --advisor off` initialized with protocol version 1 and `agentInfo` name `qwen-code`, title `Qwen Code`, version `0.26.5`. The only offered authentication method was the synthetic `openai` terminal method. No prompt was sent.
|
|
26
|
+
|
|
27
|
+
`session/new` succeeded. Available modes were `plan`, `default`, `auto-edit`, `auto` and `yolo`, with current mode `default`: the same five ids as 0.26.4. Each transition in `default -> auto-edit -> yolo -> default` returned an acknowledgement, so the hub's ask/default, ask-when-needed/auto-edit and never-ask/yolo map is still a subset of the native ids. The session exposed only the fixture model.
|
|
28
|
+
|
|
29
|
+
The native leader exited after its owned group received SIGTERM, and the producer confirmed `groupGone: true`.
|
|
30
|
+
|
|
31
|
+
## Actual published permission handler
|
|
32
|
+
|
|
33
|
+
An exports-only scratch copy of the published ACP chunk (`export{SubAgentTracker,toPermissionOptions,resolvePermissionOutcome}` appended) was placed beside the original inside the private package, preserving its relative imports. The original chunk was not edited. The fixture invoked the actual `SubAgentTracker.createApprovalHandler` with synthetic client, tool and event ports, not a model-generated tool turn.
|
|
34
|
+
|
|
35
|
+
- The request carried the fixture session, pending tool-call id, raw input, native MCP tool metadata and permission progress updates.
|
|
36
|
+
- The exact options were `proceed_always_project` and `proceed_always_user` as `allow_always`, `proceed_once` as `allow_once`, and `cancel` as `reject_once`.
|
|
37
|
+
- An allow-once response reached `event.respond` as `proceed_once`; a cancelled outcome reached it as `cancel`; the real outcome helper rejected an unoffered option.
|
|
38
|
+
|
|
39
|
+
## Not verified
|
|
40
|
+
|
|
41
|
+
A real model-generated permission turn, a real login or provider, model behavior, Linux and Intel macOS. This receipt did not review upstream source between 0.26.4 and 0.26.5; the claim is the native behaviors above on the exact published artifact. Host changed-source checks and exact-head CI are separate PR evidence.
|
|
42
|
+
|
|
43
|
+
## Evidence fingerprints
|
|
44
|
+
|
|
45
|
+
Producers and result JSONs stay outside git under the local scratch workspace.
|
|
46
|
+
|
|
47
|
+
| File | SHA-256 |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `qwen-acp-probe.py` | `12e60602ca5d00ed29473f3afef277b0c5661aca286692864da8fc69ced9d2e2` |
|
|
50
|
+
| `qwen-acp-result.json` | `442f2e33c13232723eb646119f49f52fcb8df06de7c59ee32402ab377525710a` |
|
|
51
|
+
| `qwen-permission.mjs` | `989ba620e7d099b74ec5b4b1efb78d9d6cc96b5ef5b364c058a077dfc8621a31` |
|
|
52
|
+
| `qwen-permission-result.json` | `958a77ea7618e0efd04a78520aadf83654e5b74a0158a05061d0bed4406d7c31` |
|
|
53
|
+
| `deny-network.cjs` | `361148af658dd4b65ed35308622ec99bb882ec5a25fab54581776546f139e892` |
|
|
54
|
+
|
|
55
|
+
The two probe copies differ from the 0.26.4 producers only in paths and the expected version string.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Qwen 0.26.5 dual-output attempt, not qualified
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-03. Task #684, Refs #888, the separate `qwen-dual` row. The [0.26.5 ACP receipt](2026-11-03-qwen-0265-acp.md) does not qualify the TUI contract. This repeats the corrected [0.26.4 attempt](2026-10-31-qwen-0264-dual-output.md) (the v2 producer, fixed OpenAI-compatible loopback responses, no real model, account or credential) on `@qwen-code/qwen-code@0.26.5`.
|
|
4
|
+
|
|
5
|
+
**Decision: do not add 0.26.5 to `COMPAT["qwen-dual"].verified`.** Q2 did not pass. Exactly 0.26.1 stays verified for this entry, and `src/adapters/compat.ts` is unchanged for it.
|
|
6
|
+
|
|
7
|
+
## Artifact and controls
|
|
8
|
+
|
|
9
|
+
The candidate is the private-prefix package described in the ACP receipt (upstream tag and `gitHead` `db0e4e24a0d89b211b2a15f4af2be22adac71dfc`, Node 24.18.1, macOS arm64). The retained global 0.26.1 install (`cli-entry.js` SHA-256 `113efe4104a9fc66f507d34bfd6abbd896ceb77de47f4b468a0825a327fdc6a5`) served as a read-only matched control, always with a fresh temporary HOME and cwd and the same producer. Each fixture used a PTY, private input and event files, a scratch git project, a synthetic key and a loopback server. The Node network guard's positive control passed; every observed Node process loaded the guard; every owned process group was confirmed gone; the temporary roots were removed. Model inference calls: 0.
|
|
10
|
+
|
|
11
|
+
Real configuration: the person's `~/.qwen`, `~/.pi/agent` and the global qwen install hashed the same before and after (9550 entries, together with the ACP runs).
|
|
12
|
+
|
|
13
|
+
## Observed outcomes
|
|
14
|
+
|
|
15
|
+
| Check | 0.26.5 | Matched 0.26.1 control |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Q7 version and guard positive control | pass, 0.26.5 | pass, 0.26.1 |
|
|
18
|
+
| Q2 second submit becomes a separate user turn after the first completes | **fail**: `Q2 fewer than two user events` | **fail**, the same error, same fixture |
|
|
19
|
+
| Q3 shell and native MCP `can_use_tool`, allow, TUI Enter, duplicate refused, read-only control | pass | not selected |
|
|
20
|
+
| Q4 external SIGINT leaves the turn running; person Esc stops it and the next turn works | pass | not selected |
|
|
21
|
+
| Q5 unread output FIFO does not block the TUI answer | pass | not selected |
|
|
22
|
+
| Q6 resume id, no old-submit replay, prior context in the resumed request | pass | not selected |
|
|
23
|
+
|
|
24
|
+
Q2 fails identically on the already-verified 0.26.1 with this producer, so it is a limit of the held-stream workload the corrected fixture uses and not a 0.26.5 regression: the same outcome the 0.26.4 receipt recorded. It also means this fixture cannot reproduce the queued-submit observation the [original 0.26.1 receipt](2026-10-25-qwen-dual-output-t0.md) rests on. The task gate (promote only when every model-free leg passes) does not allow a `qwen-dual` bump while a required leg is unestablished, and no TUI adapter, queue, cancellation policy or existing admission is changed.
|
|
25
|
+
|
|
26
|
+
## Source note
|
|
27
|
+
|
|
28
|
+
Upstream `DualOutputBridge.ts` and `RemoteInputWatcher.ts` have the same blob ids at v0.26.1 (`b475278c`), v0.26.4 (`715a550c`) and v0.26.5 (`db0e4e24`): `1e1a4e71fafd0c29c62e4ca60243449bd698d20a` and `8a3eabf4e29804ce5f63d40d4a083d14f489dbb3`. That is scoped supporting evidence about those two files, not native acceptance.
|
|
29
|
+
|
|
30
|
+
## Not verified
|
|
31
|
+
|
|
32
|
+
Q2 on any version with this producer, a real account or provider, model choices and quality, token and quota behavior, Linux and Intel macOS. Explicitly failed and unselected legs above are not relabelled as passes.
|
|
33
|
+
|
|
34
|
+
## Evidence fingerprints
|
|
35
|
+
|
|
36
|
+
| File | SHA-256 |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `qwen-dual-probe-v2.py` | `114c032afce5caef4f59072f0a1730bc78a70788fd49ad17e5ff2f1eef4c947e` |
|
|
39
|
+
| `qwen-dual-v2-0265-result.json` | `1062244e51f5c1aab71f2778d08116c3c00f81929be9aa209fc3467763cc0471` |
|
|
40
|
+
| `qwen-dual-v2-0261-control-result.json` | `d4384d0b54f42e789f09f44346201b75285b1afafc78eb3d22ff3271b38ce72a` |
|