Files
reliquary/docs/workpad/reports/2026-10-16-08-headless-forks-run.md
T

66 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Run log — Trained implementer, forked per block (`spire:forks`)
- Plan: `docs/workpad/plans/2026-10-16-01-headless-forks.md` · Build plan: `docs/workpad/plans/2026-10-16-02-headless-forks-build.md`
- Branch: `headless-forks` (worktree `.claude/worktrees/headless-forks`) · Start commit: `d373689`
- Trunk notes: `docs/workpad/reports/2026-10-16-08-headless-forks-trunk-notes.md`
- Athanor: `claude-opus-5-5[1m]` (installed Spire 0.2.2 shape) · Session journal: Igor's, `docs/workpad/journals/2026-10-15-21-grotto-work.md` (not touched by the Athanor)
- Forks: none yet (the helper does not exist until Phase 1)
## Phase 0 — Preflight (STOP gate)
| Block | Owner (model id) | Commit | Tokens (if known) |
|---|---|---|---|
| 0 Preflight probes and report | the Athanor, `claude-opus-5-5[1m]`, own Bash | `7421d3a` (+ this hash fill-in) | probe calls: $5.68 over 45 calls (client estimate, sum of per-call deltas); the Athanor's own tokens unknown |
### Block 0 — Preflight probes and report
- Model: `claude-opus-5-5[1m]`
- Start / end: 2026-10-16 08:16:26 +0200 / 2026-10-16 12:16 +0200 (last probe 10:13:01; `date` jumped from 10:13 to 12:16 across two consecutive commands, cause unknown, likely host suspend)
- Done: Worktree `.claude/worktrees/headless-forks` created on new branch `headless-forks` from `d373689`. Throwaway probes written and run from the Athanor's own Bash in the session scratchpad (`…\scratchpad\headless-forks-p0\`, not in git): P0.0–P0.8 in the build plan's amended order (P0.0, P0.1, start P0.6 detached via the P0.1 rung, P0.2–P0.5, P0.7, P0.8 while it ran, then collect P0.6). Preflight report `docs/workpad/reports/2026-10-16-09-headless-forks-preflight.md` with verdict, per-item results and the Phase 1 defaults. Nothing in `plugins/` changed.
- Deviations from plan:
- P0.6 was started once P0.1's rung 3 had passed (a), (b) and (d), before (c)'s 15 minutes were up, so the TTL clock started earlier. (c) passed later at 08:39–08:45; had it failed, P0.6 would have died with it and been restarted.
- The scratch clone is `git clone --local --no-hardlinks` (hardlinks fail from `G:` to `C:`). Same content, same `.claude/settings.json`.
- P0.5's model cases ran first in a copy of the project settings (`$P0\p05-cwd`), which turned out to be an **untrusted workspace** (project `permissions.allow` ignored). To get a trusted `availableModels` reading, five tool-less "Reply OK" calls ran with cwd = `G:\dev\projects\reliquary` (trusted) and one in the worktree (trust check). They cannot edit anything (`--tools ""`), but they are live calls outside the scratch clone, against plan decision 4's letter. They left transcripts under the reliquary project slug in `~/.claude/projects/`. The unlisted-family case was run through `--settings '{"availableModels":[…]}'` instead, because reliquary lists all four family aliases.
- P0.5's `--agent` test and P0.8 ran in separate scratch dirs (`p05-cwd`, `p08-cwd`) instead of the clone, so adding an agent and a skill could not change P0.2's prefix while it ran.
- P0.1 (d): the Bash tool no longer kills a call at its timeout; it backgrounds it. (d) was produced with `TaskStop` on the backgrounded call, which kills the process tree. Recorded in the report.
- The P0.5 effort-cache case ran inside the P0.2 probe (a `--effort medium` fork of the P0.2 base) instead of a separate base.
- Flagged for review:
- The P0.1 verdict rests on the strict reading of (d) (launcher still alive when the Bash call is stopped). Rung 1 survives when the launcher has already exited (`r1-dprime`). Rung 3 is the ladder's answer; the reviewer may want to weigh rung 1 plus an exit-first launcher against rung 3's CIM env handling.
- `r3-main` and `r3-tkill` ran PATH `claude` 2.1.283 (CIM env lacked `CLAUDE_CODE_EXECPATH`); survival evidence is unaffected, the binary is.
- P0.8 ran in an untrusted workspace; the pre-approval "no" may differ in a trusted project.
- Effort: a different effort did not miss the cache; whether `--effort` took effect is unobservable.
- A fork that backgrounds a Bash command can leave an orphan process after `claude` exits (seen once on 2.1.283).
- P0.6: the 50-min ping read only 0.916 of A's context (re-created 7,463 tokens, about the size of the shared system/tool prefix). Still a hit by C5 and the later fork read 1.0004; cause not isolated.
- Visible windows (coordinator's message 09:52, user report): every rung-3 supervisor before the fix (P0.1 `r3-*`, the P0.2 and P0.6 probes) opened a visible console window (Windows Terminal) on the user's desktop. "No visible window" was added to P0.1's pass criteria and the surviving variant retested with `Win32_ProcessStartup.ShowWindow=0` for the supervisor and `CREATE_NO_WINDOW` for every child: no window in 26 checks (plus 3 on an informational Popen `CREATE_NO_WINDOW` variant), including during `claude` → `bash` → `PING`; (a)–(d) and the tree-kill pass again. A positive control (`r3-wincontrol`, 15 s) showed the detector does see the old window. Recorded in the preflight report §P0.1.
- `$P0\raw\p01\` was not cleaned between runs; `r3-kill2` finished unobserved during a 20-minute `git clone` (08:24–08:45).
- Left for later: the Phase 1 defaults listed at the top of the preflight report. Survival of a rung-3 supervisor across the Athanor's hand-back is untested (Phase 1 smoke).
- Expected broken: nothing (no product code yet).
- Commits: `7421d3a` (report, run log, trunk notes), then a one-line follow-up filling in this hash. Probe commits in the scratch clone only (`64dbefa`, `9bfefb7`, `bb5514d`, `0f72edb`, `9d3ddc1`), not in this repo.
### Phase 0 close
- Gate: none named for Phase 0 (probes only, no code in the repo). Every STOP item checked against its criterion in the report.
- Tests: not applicable (no product code). Probe results and raw paths in the report.
- Flags for the reviewer:
- Block 0: every deviation and flag above, one by one.
- Block 0: check the report's numbers against `$P0\raw\` (summaries `*.summary.json`, `p03-usage.json`, `p02\state.json`, `p06\state.json`, `p07\p07.json`, `p08\p08.json`, `p01\<tag>\check-*.json`).
- Not run / untested: survival past the end of the Athanor's turn; what effort changes; a trusted-workspace P0.8.
- Spend: $5.68 client estimate over 45 calls (trigger $25 not hit), plus three killed calls without a result (cents).
- Leftover processes: none. Swept at 10:13–12:16 by command line (`headless-forks-p0`, `p01_sup`, `p01_sleeper`, `p06_ttl`, `p02_base`) and by name (`PING`, `sleep`); the only hits were the Athanor's own Bash. One orphan was killed by hand earlier (`sleep.exe` pid 31372, from `r3-kill`).
- Open questions (for Igor and the user; none blocks Phase 1):
- U4 is moot for reliquary: the `sonnet`/`haiku` aliases in `availableModels` admit their full ids. An unlisted model is substituted silently, not refused; C8's runtime `model_refused` must key on the `system/informational` warning or a `modelUsage` mismatch.
- The Bash tool backgrounds instead of killing at its timeout. C2's `timeout: 600000` rule stays, but A2's failure mode ("killed with no JSON") is now "backgrounded, notification to the subagent". Does the Phase 3 text want a line on it?
- Rung 3 adds a PowerShell dependency (about 0.3 s per launch) and an env hand-off file. Rung 1 with a launcher that exits first would avoid both but dies if its launcher is in a stopped tree (e.g. pings launched from `wait`). The plan's ladder picks rung 3; the reviewer may weigh it.
- P0.8: injection works in a subagent preload, pre-approval does not (untrusted dir). SKILL.md needs the allow-rule note; the trusted-project case is for Phase 4.
- Forks that background a Bash command leave orphans after `claude` exits. Suggested default: a preamble line forbidding `run_in_background` in forks; Phase 1 decides.
- Verdict: **GO** (see the preflight report header).
- Status: provisional until review, fix pass and re-check close. Igor makes the GO/STOP call.
- Igor, 2026-10-16 ~12:18: Phase 0 accepted, GO, no separate review; the Phase 0 deviations go to the Phase 1 reviewer as handoff flags. Coordinator decisions: rung 3 hidden is the launch default (rung 1 only with a documented clean case); the fork preamble forbids `run_in_background`; `kill`/`expire` also sweep the fork's process tree; the model check keys on the warning event / `modelUsage` mismatch; "no visible window" is a permanent acceptance criterion in unit and smoke gates where testable; the binary is always the fingerprinted absolute path, and the env passed via CIM carries `CLAUDE_CODE_EXECPATH` or the explicit binary path.
## Phase 1 — Helper core
Intake 2026-10-16 12:18 +0200, Athanor `claude-opus-5-5[1m]`. Start commit `83f6bac`.
| Block | Owner (model id) | Commit | Tokens (if known) |
|---|---|---|---|