📝 Headless-forks post-mortem and Spire guidance text audit
This commit is contained in:
@@ -17,6 +17,16 @@
|
||||
- **"Could all this not be expressed simpler?"** For example, resolve complex ifs into a simple, elegant `match`, or move a class up a layer because that decouples the whole structure. Simplification is design work, and no stage of the current cycle does it: reviews hunt bugs, fixes add, nothing removes.
|
||||
- The user wonders whether this is partly their own fault, for being chaotic and having too many thoughts at once. *(Igor's note: the build's failure modes — no structure in the plan, cold starts, review loops that only add — are process failures, not the user's.)*
|
||||
|
||||
## Correction and additions (user, 2026-10-16, later)
|
||||
|
||||
- "How much Opus can throw out" meant **how much output it can generate**, not deleting code. Igor misread this above as "trust Opus to throw code away".
|
||||
- On deleting code, the user's actual view:
|
||||
- Throwing code away is sometimes wise, **as long as you commit before throwing it out**. History is usually useful.
|
||||
- All code teaches something. This prototype holds a lot of wisdom and logic, and the user doesn't want to downplay it. **It was just too much.**
|
||||
- It would have helped to have a prototype first, and then use it to write the real code.
|
||||
- The user wants the whole build bundled into a report that honestly calls it a failure. The approval waits cost time, but they are not the main issue.
|
||||
- **Guidance hasn't found its sweet spot yet.** Open question: how big are the skills in text, how much of it is filler, and is each skill truly written for an agent, or does it regurgitate knowledge the model already has?
|
||||
|
||||
## Answer: how much code can Opus 5.5 produce in one go?
|
||||
|
||||
*(Igor, 2026-10-16, from the claude-api skill's model table)*
|
||||
|
||||
@@ -202,6 +202,35 @@
|
||||
- About two thirds is detached-process policing; most of the rest is unrequested heuristics.
|
||||
- Recommendation: keep stream parsing, usage and cache accounting, env scrub, the argv builder and templates; replace the supervisor with a blocking call under `run_in_background`; ~600–800 lines.
|
||||
- Pre-rewrite check: does TaskStop on a backgrounded Bash call kill the claude.exe grandchild?
|
||||
- User corrections and asks:
|
||||
- "throw out" meant output volume. Delete code only after committing; history is useful.
|
||||
- The prototype holds wisdom; it was just too much; a prototype first would have helped.
|
||||
- Wants a post-mortem that calls this a failure (approval waits aren't the main issue).
|
||||
- Wants to know skill text size, filler, and whether the skills are written for agents.
|
||||
- Brainstorm corrected. Dispatched two Opus agents in parallel (30 min timebox each): post-mortem → reports/2026-10-16-23-headless-forks-postmortem.md; guidance-text audit → reports/2026-10-16-23-spire-guidance-text-audit.md.
|
||||
- Post-mortem back (claude-opus-5-5): reports/2026-10-16-23-headless-forks-postmortem.md.
|
||||
- ~12,700 lines in total (code, tests, process docs) vs ~1,100–1,300 needed. ~21 h wall clock, 11.6 h of it waits, **~9 active hours, which is the real failure**.
|
||||
- Top causes:
|
||||
1. The premise fell (Bash backgrounds long calls) and nobody re-planned.
|
||||
2. The goal and design specified a large tool.
|
||||
3. No size criterion, and reviews only add (+480 lines of fixes, ~25 unrequested items never cut).
|
||||
4. No code structure in the plan.
|
||||
5. Opus everywhere with no budgets.
|
||||
- The 1.1 skeleton alone was 1,124 lines.
|
||||
- **Igor's own miss, made explicit:** the Phase 0 hand-back stated the Bash-background finding, and Igor answered with "rung 3 default" instead of stopping to re-plan.
|
||||
- Igor proposed a gremlins MVP box list:
|
||||
- train/spawn as blocking calls; the Athanor runs spawns under run_in_background; stop via TaskStop (5-min check first);
|
||||
- usage from the result JSON; warmth reported only, no pings; rebase optional;
|
||||
- no detach code, so it may be cross-platform; ~400–600 lines in a few modules;
|
||||
- one agent, one go, happy path first, one boxes-and-deletion review.
|
||||
- The user had asked: "ecosystem first" (inventory harness/stdlib/existing tools before building), which belongs in grotto's orientation probe. The user feels it's their fault for keeping the first drop; Igor: a rewrite is cheap now that the prototype exists.
|
||||
- Guidance audit back (claude-opus-5-5): reports/2026-10-16-23-spire-guidance-text-audit.md.
|
||||
- ~25k words on main.
|
||||
- Split: 42% agent instruction / 22% facts / 9% general knowledge / 23% filler / 4% stale.
|
||||
- Planner, attacker and reviewer carry ~83% preloaded workpad + implementation text.
|
||||
- Steering sentences match today's behaviour exactly: reviewer.md:22 "Answer every … flag … one by one", "Hunt …", run-log handoff fields with no length cap, attacker.md:25 asking for more scope.
|
||||
- No size, happy-path or delete guidance anywhere.
|
||||
- Stale text includes the athanor.md:32 Agent-tool fork and the zathras "Always pass model".
|
||||
|
||||
## Adepts
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
# Post-mortem: the headless-forks / gremlins build
|
||||
|
||||
- **Date**: 2026-10-16
|
||||
- **Author model**: claude-opus-5-5 (one agent, read-only apart from this file, 30-minute timebox)
|
||||
- **Verdict**: **a failure.** The code works, but the build missed the brief by a factor of 4–5 in size and took most of a day. Most of the excess came from planning and process, not typing.
|
||||
- **Sources**: journal `docs/workpad/journals/2026-10-15-21-grotto-work.md` (cited as J:line), the goal, design, plan and build plan on `main`, the code verdict `reports/2026-10-16-22-gremlins-code-verdict.md` (V:line), the brainstorm `brainstorm/2026-10-16-22-grotto-plan-structure.md` (B:line), and on the branch worktree `.claude/worktrees/headless-forks/docs/workpad/`: the run log `reports/2026-10-16-08-headless-forks-run.md` (RL:line), the preflight (PF:line), the reviews, re-checks and digests, plus `git log headless-forks`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Outcome
|
||||
|
||||
**Asked for.** "Spire ships a **small deterministic helper** (a script in the skill …) that owns the `claude -p` command line. It covers: train a base, fork the base with a brief, update the base, report usage, and list or expire bases" (goal:17). The intent was to keep bookkeeping out of agent attention (goal:12).
|
||||
|
||||
**Delivered.** Branch `headless-forks` at `ab1d945`, 51 commits, not merged, Phase 3 not reviewed, block 3.8 left as WIP (J:196).
|
||||
|
||||
| Artifact | Lines |
|
||||
|---|---|
|
||||
| `gremlins.py` | 4,155 |
|
||||
| `tests/test_gremlins.py` | 4,235 (about 180 tests) |
|
||||
| SKILL.md, preamble, templates | 189 |
|
||||
| Process documents (design 430, plan 257, build plan 337, three contract digests 869, run log 812, preflight 187, five reviews and checks 989, platform handoff 339, trunk notes 53) | about 4,270 |
|
||||
|
||||
That is about 12,700 lines of code, tests and process documents for a tool the verdict sizes at **600–800 lines plus about 500 lines of tests** (V:97-109). The verdict: "careful, consistent and well tested, and it works … still over-built by about four to five times", with "roughly two thirds" of it policing detached processes (V:16). A live happy path on Sonnet 5.5 ran clean for $0.09, with a cache hit on the fork (V:140-151).
|
||||
|
||||
**Time.** From the goal (01:23, J:73) to the stop (22:20, `ab1d945`) was **about 21 h of wall clock**. The build itself, from B0 (08:15) to the stop, took **about 14 h**.
|
||||
|
||||
| Bucket | Hours | Evidence |
|
||||
|---|---|---|
|
||||
| Push approval stall before the build (B0) | ~6.4 | J:102, J:104 |
|
||||
| Unexplained gap in Phase 0 (10:13 → 12:16) | ~2.0 | RL:18, J:116 (probably an approval prompt; the Athanor guessed "host suspend") |
|
||||
| Unexplained gap in block 1.2 (12:31 → 15:42) | ~3.2 | RL:105, J:120 |
|
||||
| **Total waits, mostly approvals** | **~11.6** | J:130 says "~11 h" |
|
||||
| Active build time, 08:15–22:20 minus the in-build gaps | **~8.9** | below |
|
||||
|
||||
Even with every approval wait removed, the build took **about 9 active hours** for a "small helper". That is the failure. The waits only made it look worse.
|
||||
|
||||
---
|
||||
|
||||
## 2. Timeline
|
||||
|
||||
Times are 2026-10-16 (+0200) unless marked. They come from commits and from the run log's `date` stamps.
|
||||
|
||||
| Time | Step | Duration | Notes |
|
||||
|---|---|---|---|
|
||||
| 10-15 21:23 | Session start; grotto orientation, experiment synthesis | — | not this build |
|
||||
| 00:44–01:16 | Headless-fork research (local tests, $0.48) | ~0.5 h | J:52-64; this is where the mechanism was proven |
|
||||
| 01:23 | Goal written, decisions settled | — | J:73-74 |
|
||||
| ~01:25–01:50 | Design → plan → attack, three Opus agents | ~0.5 h | J:75-101 |
|
||||
| 01:50 → 08:15 | B0 push waiting for approval | **6.4 h** | J:104 |
|
||||
| 08:16–12:17 | **Phase 0** preflight | 4.0 h | 1 h is the TTL test by design (J:107); ~2 h is a gap (RL:18) |
|
||||
| 12:18–12:29 | 1.1 skeleton, state, `where`, `init` | 8 min | already **1,124 lines** of code |
|
||||
| 12:31–15:49 | 1.2 launch and supervise | 3.3 h | about 3.2 h of it is the clock gap; code grows to 2,403 |
|
||||
| 15:50–15:56 | 1.3 smoke | 6 min | |
|
||||
| 15:57–16:40 | Phase 1 review → fix → re-check | 43 min | 3 Important, 16 Minor; +245 code lines |
|
||||
| 16:42–17:44 | **Phase 2** (2.1 15 min, 2.2 22 min, 2.3 8 min, smoke 8 min) | 1.0 h | code goes 2,648 → 3,640 |
|
||||
| 17:44–18:22 | Phase 2 review → fix → re-check | 38 min | 2 Important, 14 Minor; +147 code lines |
|
||||
| 18:23–18:44 | Phase 3 digest (684 lines) → pre-build check → amendment | 21 min | the check step was added by Igor (J:160) |
|
||||
| 18:44–20:24 | **3.1 rename** | **1 h 40** | a sed job took the time of an audit (J:172-176) |
|
||||
| 20:26–20:39 | 3.2 platform seam and gate | 13 min | +274 code lines |
|
||||
| 20:41–21:43 | 3.3 N3, N4, kill flake | 62 min | the flake did not reproduce (RL:627) |
|
||||
| 21:45–21:57 | 3.4 WSL check, 3.4a test fixes | 12 min | |
|
||||
| 21:59–22:18 | 3.5–3.7 text, references, handoff | 19 min | handoff report is 339 lines |
|
||||
| 22:20 | 3.8 stopped by the user; WIP commit | — | J:196 |
|
||||
|
||||
**Where the active ~9 h went:**
|
||||
|
||||
- About 2 h on Phase 0 probing, and 1 h waiting on the TTL test. This was the most valuable part.
|
||||
- About 1 h writing the core in Phase 1. Block 1.2 is hidden inside a 3.3 h span.
|
||||
- About 1 h on Phase 2 features, most of them heuristics (V:74-91).
|
||||
- About 1 h 40 on review, fix and re-check loops, plus digest checks.
|
||||
- About 3 h on Phase 3: the rename alone took 1 h 40; the seam over a supervisor that should not exist; one hour chasing a flake.
|
||||
|
||||
Each block owner was a fresh Opus 1M agent using **187k–351k tokens** (RL:66-67, RL:261-263, RL:236, RL:482). The Athanor reached about 515k tokens by the end of Phase 2 (J:149).
|
||||
|
||||
**Code growth** (`git show` on each commit; `gremlins.py` / tests):
|
||||
|
||||
| Commit | Point | Code | Tests |
|
||||
|---|---|---|---|
|
||||
| `d36ac2f` | 1.1 skeleton | 1,124 | 673 |
|
||||
| `009a252` | 1.2 supervisor | 2,403 | 1,587 |
|
||||
| `7b9b748` | P1 fixes | 2,648 | 1,976 |
|
||||
| `5fda2e2` | 2.2 rebase/re-train | 3,420 | 3,020 |
|
||||
| `4b92b51` | 2.3 usage | 3,640 | 3,378 |
|
||||
| `d2d5104` | P2 fixes | 3,787 | 3,630 |
|
||||
| `e9f1b06` | 3.2 seam and gate | 4,070 | 3,944 |
|
||||
| `62eef3b` | 3.3 N3/N4 | 4,155 | 4,222 |
|
||||
|
||||
Two facts stand out. The skeleton alone, before any launch code, was already larger than the whole minimal version. And by the end of Phase 1 the code was about 3× the verdict's target, before a single review fix landed.
|
||||
|
||||
---
|
||||
|
||||
## 3. Root causes, ranked
|
||||
|
||||
Each candidate the user named is tested against the evidence. They are ranked by how much of the excess size and time they explain. Approval waits are ranked last on purpose: they cost hours but no lines.
|
||||
|
||||
### RC1. Phase 0 removed the design's main premise, and nobody re-planned. **Supported; the biggest single driver.**
|
||||
|
||||
- The design's shape: "Launch returns at once (detached supervisor)" (design:255). Its fallback was `--attach` under `run_in_background`, with the line "**The Athanor never relies on the background notification**" (design:149). Risk R1 was that detached children would die when the Bash call ended (design:373).
|
||||
- Phase 0 found that a Bash call past its timeout "is **not killed**; it is moved to the background … and its completion notification arrived in this subagent" (PF:71). That falsifies the reason for detaching.
|
||||
- What happened next: to keep pass criterion (d), "a Bash call that the tool kills on timeout" (build plan:223), the Athanor manufactured the kill with `TaskStop` (RL:25). The test was kept alive, and nobody asked whether it still mattered. The preflight says "no fallback beyond the ladder was needed" (PF:50). Igor made rung 3 (PowerShell/CIM hidden detach) the permanent default (RL:58). The open question "does the Phase 3 text want a line on it?" (RL:52) was routed as a documentation item (RL:507).
|
||||
- The cost: two thirds of the code (V:16, V:60-72), meaning detach, supervisor, `SupClock`, orphan watchdog, heartbeats and reaping, the pid-reuse-safe tree kill, `RegistryLock`, and most of the platform seam. The seam then put an interface over machinery that should not have existed (470 lines for one tested platform, V:26, V:72).
|
||||
- Igor noticed only at 22:11, after the user asked "an operating system?" (J:191-193).
|
||||
|
||||
### RC2. The goal and plan specified a large tool; "small" was a label. **Supported.**
|
||||
|
||||
- The goal's own criteria include computed keep-warm, expire and re-train rules (goal:23), rebase-or-delta policy (goal:27), agent-file specialisation, the fingerprint, and the env scrub (goal:17-29). Igor admits this: "small helper was a label, not a requirement" (J:194).
|
||||
- The design and plan then turned each criterion into machinery:
|
||||
- 13 commands (plan:88);
|
||||
- a ping rule with an activity window and a break-even cap "at 19 and 11" (plan:204);
|
||||
- five rebase and re-train thresholds plus binary drift (plan:205, design:210-216);
|
||||
- `lost` detection and three watchdogs (plan:197).
|
||||
- The verdict's "heuristics nobody asked for" (V:74) is half true. The **user** didn't ask for them. **Igor's goal and the design** did. The failure is that nobody turned the user's sentence into a size or a scope cap.
|
||||
- The attack (build plan) found no STOP-level issues (build plan:18). It attacked correctness and harness risks, not size. So it *added* contracts (orphan kill, C1–C20) on top.
|
||||
|
||||
### RC3. No design or size criterion anywhere, and a review loop that only adds. **Supported. Weaker in lines than RC1/RC2, strong as a pattern.**
|
||||
|
||||
- No document sets a line budget, a module budget or a "simplest thing" test. Not the goal, the design, the plan, the build plan, the reviewer brief or the digest check.
|
||||
- Reviews hunted bugs and found real ones (section 4), and every fix added code and tests:
|
||||
- P1 fixes: +245 / +389 lines (`7b9b748`);
|
||||
- P2 fixes: +147 / +252 (`d2d5104`);
|
||||
- 3.3's N3/N4 fixes: +85 / +278.
|
||||
- Both Phase 2 documents carry a "**Built but not asked for (on record only)**" section: about 25 unrequested additions, among them `--warm-margin-s`, `ping_missed`, `rebase_conflict` and six new job fields (phase2-review:212-228; phase2-recheck:135-146). None was cut. The section header says outright that recording replaces removing.
|
||||
- The code now references 49 distinct review-finding IDs about 100 times (V:44). It reads "like layers of review fixes", and several mechanisms are "a patch on a patch" (V:66-67).
|
||||
- In lines, review fixes account for about 480 of 4,155 (about 12 %). The loop didn't create the bulk. It **locked it in**: each pass hardened over-built code with more tests (now longer than the code) instead of asking whether it should exist.
|
||||
|
||||
### RC4. Plans without code structure; architecture invented per phase in self-written digests. **Supported.**
|
||||
|
||||
- The plan fixes a command surface, a result JSON and two state machines (plan:86-130). It does not fix modules, a data model or layering. "One dependency-free file" was the design's only structural statement (J:77).
|
||||
- The Athanor filled the gap with its own contract digests (Phase 1 121 lines, Phase 2 64, Phase 3 **684**). Phase 3's digest alone is about as long as the whole minimal tool.
|
||||
- **Every Important finding** in Phases 1 and 2 traced back to points these digests left undefined (J:123, J:150-154). Igor named the pattern himself (J:154).
|
||||
- The result is a single 4,155-line file with a 150-line `_conclude` god function that mixes classification, eight flag rules, two near-duplicate dicts and the base state machine (V:78-84).
|
||||
- The brainstorm draws the lesson directly: the plan needs "at least the structure of the code" (B:9).
|
||||
- One caution: the experiment's "code in the plan adds nothing" result was measured on correctness and merge choice, not design quality (B:43; experiment report:13, :356). It doesn't contradict this root cause.
|
||||
|
||||
### RC5. Opus 1M everywhere, no budgets or timeboxes, and an orchestrator that explained instead of checking. **Supported.**
|
||||
|
||||
- Every block owner was Opus 1M except 2.3 (Sonnet) (RL:66-67, RL:261-263). No brief carried a time or token budget until the user forced one at 22:11 (J:177).
|
||||
- The rename went to a block "called mechanical" with "a 10-part rename map and audit-grade checks, with no model downgrade and no timebox" (J:175).
|
||||
- Its run-log note diffs 191/200 assert lines and classifies every remaining "fork" hit by line (RL:540-559).
|
||||
- It took 1 h 40 against an estimated 10–15 min (J:174).
|
||||
- The 3.3 flake hunt started 16 busy-loop processes and ran 10 instrumented reproductions on a pre-change copy, all to classify a flake that never came back (RL:627).
|
||||
- Igor's admissions:
|
||||
- he rationalised the rename ("touches every file") before checking (J:172);
|
||||
- his "$25 spending cap" wording was misleading (J:109);
|
||||
- he accepted the Athanor's "host suspend" guess for a gap that was probably an approval prompt (J:114, J:116);
|
||||
- he passed the user's lean instructions on "late or diluted" (J:183). "Implement first, test at the end" arrived after the last Phase 2 code change (J:148).
|
||||
- Process steps Igor added on his own:
|
||||
- a full review, fix and re-check loop per phase;
|
||||
- the pre-build digest check (J:160, J:181).
|
||||
- The digest check did pay off (J:169), but it was another cold-start Opus read of 684 + 4k lines.
|
||||
|
||||
### RC6. Every block was a cold-start agent re-reading thousands of lines. **Supported as a cost driver; partly as a size driver.**
|
||||
|
||||
- Each block owner started fresh and read the plan, build plan, digests, run log and code. That is 5–6k lines by Phase 3 (B:8), at 187k–351k tokens per block.
|
||||
- The successor boot section lists **six document groups** to read before touching code (RL:503).
|
||||
- Size effect: nobody held the whole code (J:189), and by design the Athanor reads no code (goal:26). So no single agent was ever in a position to say "this whole stack is unnecessary". The irony is that this build lacked the very trained-and-forked implementer it was building (B:8).
|
||||
|
||||
### RC7. No prototype first. **Supported, and linked to RC1.**
|
||||
|
||||
- Phase 0 probed mechanisms (detach rungs, cache ratio, TTL, usage fields) with throwaway scripts. It never ran an end-to-end happy path of the product shape.
|
||||
- A roughly 300-line `train → spawn → usage` script run under `run_in_background` would have exercised the completion notice directly. It would have made RC1 obvious at about 10:00, not 22:11.
|
||||
- The verdict's minimal version is that prototype, written after the fact (V:97-132). The user says so: "it would have helped to have a prototype first, and then use it to write the real code" (B:26).
|
||||
|
||||
### RC8. Mid-build scope additions on top of over-built code. **Partly supported; a consequence, not a cause.**
|
||||
|
||||
- The rename, the platform seam, the path matrix, the WSL check and the cross-platform handoff were all added during the build, by user decision (goal:50-71, J:129-145). Together they were most of Phase 3 (about 3 h, about 515 code lines).
|
||||
- They were reasonable requests against the code as it stood. The seam was asked for because the code had "12 scattered `if IS_WINDOWS` branches" (J:143), and those exist mostly because of the supervisor (RC1). This is listed for completeness, not as blame. The user wondered whether their own "chaotic" input caused this (B:18). The evidence points at the process.
|
||||
|
||||
### RC9. Approval waits. **Real, about 11.6 h, but not the main issue.**
|
||||
|
||||
- They are explained by the user being away while not in auto mode (J:116). They added wall clock and no lines.
|
||||
- Removing them still leaves about 9 active hours and a 4–5× over-build.
|
||||
|
||||
**What the evidence does not support.** The single-file stdlib constraint (J:188, hypothesis 3) as a cause of size. It explains why everything sits in one file. It doesn't explain why there is so much.
|
||||
|
||||
---
|
||||
|
||||
## 4. What worked
|
||||
|
||||
- **The mechanism is verified and works.** `claude -p --resume <base> --fork-session` with an identical fingerprint gets cache hits:
|
||||
- 0.9999 on a small base in the smoke (RL:154);
|
||||
- about 1.0 on a 182k-token base (J:112);
|
||||
- a clean live run in the verdict (V:147).
|
||||
- **The cache and usage accounting is real know-how**: `StreamState`, `usage_from_result` with the 1h/5m split, cost deltas against the session's cumulative total, `cache_verdict`, `infer_ttl`, `base_warmth` (V:48-50). The smoke reconciled every ledger line against the raw `total_cost_usd` differences (RL:157).
|
||||
- **Phase 0 findings that are expensive to re-derive:**
|
||||
- the 1 h TTL, and that a hit refreshes it (J:107);
|
||||
- unlisted models are substituted silently, not refused (J:112);
|
||||
- plan mode upgrades Haiku;
|
||||
- CIM detach is needed if one does detach;
|
||||
- **the Bash tool backgrounds rather than kills, and the notice returns** (PF:71). This last one is a graduation candidate (J:246), and it is the finding that should have reshaped the build.
|
||||
- **Env scrub constants**: an empirically gathered list of Desktop and SDK variables (V:52).
|
||||
- **The reviews caught real bugs**, each fixed with a test that fails on the old code (J:127-128, J:156):
|
||||
- I2: the pid-reuse tree walk could have killed `dwm`/`winlogon` on this host (phase1-review:22);
|
||||
- I1: errors misreported as `model_refused`;
|
||||
- Phase 2 I1: `delta_tokens` would have forced a rebase before every fork.
|
||||
- **The digest check paid off at once**: one BLOCKER (gate tests that could never pass, and whose closed case passed for the wrong reason), plus 12 ADJUSTs (digest-check:9-26, J:169). The *point* is right: check the architecture before the build. The *vehicle* was a symptom of RC4.
|
||||
- **The run log and journal made this post-mortem possible.** Every gap, admission and deviation is timestamped. Audit-grade logging was too expensive per block (RC5), but as a record it is excellent.
|
||||
- **Discipline held**: no push or merge by the Athanor, no attribution lines, no leftover processes after any phase (RL:49, RL:194), and the visible-window bug was fixed and verified in 26 checks (J:111).
|
||||
|
||||
---
|
||||
|
||||
## 5. What the code is worth
|
||||
|
||||
The user's view, and this report agrees: the prototype **holds a lot of wisdom and logic and should not be downplayed; it was just too much** (B:25). Treat it as a prototype to learn from:
|
||||
|
||||
- **Keep as a reference:** `StreamState`, `usage_from_result`, `cache_verdict`/`infer_ttl`/`base_warmth`, `api_error_reason`, the `SCRUB_*` lists and `scrubbed_env`, `claude_argv` and the fork argv, `atomic_write_bytes`/`_retry`, the templates and preamble, and the ledger plus `usage --format md` (V:46-56). That is about 600 lines of distilled facts.
|
||||
- **Keep as evidence:** the tests that pin real harness behaviour, such as the P0.2 seq-1 numbers in `RuleTests` (RL:106), the path matrix, and the WSL findings (RL:658-669, zombie liveness, PATH interop).
|
||||
- **Keep as a negative example:** the supervisor stack and the heuristics layer, as a worked case of what correctness-only review and an unchallenged premise produce.
|
||||
- **Don't delete it from history.** The user's rule is: commit before throwing out (B:24). The branch is the record (J:196).
|
||||
|
||||
The next step is the user's call (J:197, J:229): a minimal rewrite over blocking calls run with `run_in_background`, or straight to the Rust app. One check comes first: does `TaskStop` on a backgrounded Git Bash call kill the `claude.exe` grandchild (V:134)? PF:71 suggests it does ("kills the process tree by parent links"). A one-line confirmation on the target shape is still worth running.
|
||||
|
||||
---
|
||||
|
||||
## 6. Lessons: options for grotto and Spire
|
||||
|
||||
These are options, not verdicts. Each one names the root cause it addresses.
|
||||
|
||||
### Grotto (design → plan → handoff)
|
||||
|
||||
1. **The plan fixes the code structure** (RC4). The plan includes modules, the data model, the main interfaces, and where the special cases live. Options: a short skeleton in the plan (signatures plus the data model, no bodies), or a "structure" section that the attacker must attack. Then no builder writes a contract digest; a gap goes back to the planner.
|
||||
2. **A size budget per artifact** (RC2, RC3). The goal or plan states an expected size: "helper ≤ 800 lines, tests ≤ 600". Crossing 1.5× is a STOP that goes to Igor. Options: hard cap vs. checkpoint; lines vs. commands or flags.
|
||||
3. **Prototype first** (RC7, RC1). Before the full plan, one agent writes the happy path (about 300 lines, one timebox) on the real harness, and the plan is written from it. The prototype can be thrown away after it is committed.
|
||||
4. **A premise list with re-plan triggers** (RC1). The design lists the premises its shape rests on (for example "R1: Bash kills long calls, so we detach"). Every preflight result is checked against that list, and a falsified premise forces a re-plan, not a documentation note. Option: the preflight report gets a mandatory "premises still standing?" table.
|
||||
5. **Goals separate the user's words from Igor's criteria** (RC2). "Small" in the user's sentence becomes a measurable criterion. Criteria Igor added are marked as such, so the user can strike them.
|
||||
6. **The attacker gets a simplicity pass** (RC2, RC3): "what is the smallest design that meets the goal, and which contracts can be dropped?", next to the correctness and conventions passes.
|
||||
|
||||
### Spire (Athanor, reviewer, Igor, implementation skill)
|
||||
|
||||
7. **The reviewer gets a design and size criterion** (RC3). Add findings classes such as "remove", "merge" and "simplify". "Built but not asked for" becomes a cut list by default, with keeping as the exception that must be argued. Option: a separate, cheap "subtractive review" at phase end that may only propose deletions.
|
||||
8. **Fix passes have a line budget** (RC3). A fix that adds more than N lines, or a new flag or field, goes back to Igor as a design question.
|
||||
9. **Briefs carry a model, a time budget and a token budget** (RC5). Mechanical blocks get a cheap model, a scripted transform (sed plus one test run) and a timebox, and the review checks them; they don't self-audit (J:176). Option: a default table in the implementation skill (mechanical → Sonnet or Haiku, 15 min; core → Opus, 60 min).
|
||||
10. **Use the trained implementer for the build itself** (RC6). Once the helper exists, train one base on plan, structure and code, and fork it per block, instead of 5–6k-line cold starts. Until then: hand-off notes over full re-reads, and a fixed boot set of at most two documents.
|
||||
11. **Igor checks before explaining, and adds no process step without asking** (RC5). For any anomaly (a long block, a clock gap, a cost), Igor reads the evidence first (run log, `ps`, the commit) and states it as unverified if he doesn't. New steps (digest checks, extra reviews) are proposed to the user with their cost.
|
||||
12. **One review per build or per risk, not per phase by default** (RC3, RC5). The review, fix and re-check triple ran twice and cost about 1 h 20. Option: a review per phase only where the plan marks the phase as high-risk; otherwise one review at the end.
|
||||
13. **The cheap gate excludes slow full suites** (J:146): already sent mid-build; accrete it into the implementation skill.
|
||||
14. **A fresh Athanor per phase, booted from a short state section** (J:149). Keep this, but cap the boot reading (see 10).
|
||||
|
||||
### Measure next time
|
||||
|
||||
- Active time vs. wait time per block. Have the run log record "waiting on approval" when a prompt is pending, if the harness exposes it. Otherwise flag gaps over 10 min explicitly as unknown.
|
||||
- Lines added per block and per fix pass, next to the token counts already logged.
|
||||
|
||||
---
|
||||
|
||||
## Gaps in this post-mortem
|
||||
|
||||
- The block 1.2 span (12:31–15:49) can't be split into work and waiting. The subagent's harness duration of 11,929 s covers both (RL:67).
|
||||
- The Athanor's and Igor's own token use is unknown (RL:13, RL:193), so the full token cost of the build can't be given.
|
||||
- The front-end time (design, plan, attack) is estimated from journal order. The journal has few timestamps there (J:73-101).
|
||||
- Phase 3 was never reviewed, so its share of real bugs vs. over-build isn't assessed beyond the verdict.
|
||||
@@ -0,0 +1,246 @@
|
||||
# Spire guidance-text audit: size, filler, steering
|
||||
|
||||
- Date: 2026-10-16 22:58 · Model: `claude-opus-5-5` · Branch audited: `main` (plus the `headless-forks` worktree for gremlins and the branch Athanor)
|
||||
- Scope: `plugins/spire/` skills (SKILL.md + references; no `templates/` dirs exist on main), agents, plugin CLAUDE.md, README. Also the injected `.claude/spire/project.md`.
|
||||
- Method: `wc -w` for size; tokens ≈ words × 1.3 (tables and code blocks tokenize worse, so real numbers run higher). I read every file in the load bundles in full and sampled the rest (svg references and parts of init only skimmed). Class percentages are estimates from reading, not measurements.
|
||||
- Findings and options only. Nothing here is a verdict.
|
||||
|
||||
## 1. Sizes
|
||||
|
||||
### Per file (main)
|
||||
|
||||
| Group | File | Words | ≈ Tokens |
|
||||
|---|---|---:|---:|
|
||||
| **igor** | skills/igor/SKILL.md | 3473 | 4515 |
|
||||
| | references/mindset.md (`@`-included) | 348 | 452 |
|
||||
| | references/model-tiers.md | 713 | 927 |
|
||||
| | references/journal-template.md | 153 | 199 |
|
||||
| | references/project.md (blank template) | 351 | 456 |
|
||||
| | references/harness-notes.md (moved-stub) | 107 | 139 |
|
||||
| | agents/igor.md | 85 | 111 |
|
||||
| **implementation** | skills/implementation/SKILL.md | 1395 | 1814 |
|
||||
| | references/spawning-claude-code.md | 1172 | 1524 |
|
||||
| | references/models.md | 691 | 898 |
|
||||
| | references/superpowers.md | 461 | 599 |
|
||||
| | references/run-log.md | 410 | 533 |
|
||||
| **workpad** | skills/workpad/SKILL.md | 1768 | 2298 |
|
||||
| **project** | skills/project/SKILL.md | 45 | 59 |
|
||||
| | + injected `.claude/spire/project.md` (reliquary) | 216 | 281 |
|
||||
| **adepts** | skills/adepts/SKILL.md (+ roster output, ~6 words here) | 100 | 130 |
|
||||
| **research** | skills/research/SKILL.md | 1155 | 1502 |
|
||||
| | skills/research-tree/SKILL.md | 1213 | 1577 |
|
||||
| **svg** | SKILL.md + inline-svg.md + layout-legibility.md | 859 + 1318 + 757 | 3814 |
|
||||
| **other skills** | init | 1835 | 2386 |
|
||||
| | zathras | 1011 | 1314 |
|
||||
| | curator | 327 | 425 |
|
||||
| | knowledge | 319 | 415 |
|
||||
| **agents** | adept | 1431 | 1860 |
|
||||
| | athanor | 980 | 1274 |
|
||||
| | researcher | 450 | 585 |
|
||||
| | search | 396 | 515 |
|
||||
| | attacker | 326 | 424 |
|
||||
| | planner | 288 | 374 |
|
||||
| | reviewer | 276 | 359 |
|
||||
| | scout | 268 | 348 |
|
||||
| | zathras | 92 | 120 |
|
||||
| **misc** | plugin CLAUDE.md | 27 | 35 |
|
||||
| | README.md (not loaded by agents) | 353 | 459 |
|
||||
| **Total (main)** | | **24 953** | **≈ 32 400** |
|
||||
|
||||
Branch worktree `headless-forks` for comparison: gremlins/SKILL.md **2052** (≈ 2670 tok), preamble.md 247, templates 463 (gremlin briefs, not Athanor reading), `where` injection ≈ 133. On the branch the Athanor's text also grows: athanor.md 980 → **1658**, implementation SKILL 1395 → 1474, spawning-claude-code 1172 → **3077**, run-log 410 → 552, models 691 → 854.
|
||||
|
||||
Fixed overhead in every main session: skill descriptions ≈ 620 words and agent descriptions ≈ 630 words (≈ 1.6k tok). workpad (102), svg (114), research-tree (102) and athanor (127) have the longest descriptions. The repo CLAUDE.md (117 words) loads too.
|
||||
|
||||
### Load bundles (what one agent carries at start)
|
||||
|
||||
"Preloaded" = frontmatter `skills:` plus `@`-includes plus CLAUDE.md. "+ mandated" = files the preloaded text tells the agent to read before it can do its job. I assumed the `@references/mindset.md` include expands inside a skill. Nobody has checked that.
|
||||
|
||||
| Bundle | Preloaded | Words | + mandated reads | Words | ≈ Tokens (with mandated) | Agent-specific share |
|
||||
|---|---|---:|---|---:|---:|---:|
|
||||
| **Igor boot** | igor.md, igor SKILL, mindset, project (+project.md), adepts, workpad, repo CLAUDE.md | 6 152 | journal-template | **6 305** | **≈ 8 200** (+1.6k listings) | igor SKILL+mindset ≈ 61% |
|
||||
| **Athanor start (main)** | athanor.md, project, workpad, implementation, CLAUDE.md | 4 521 | spawning (impl:67 "Read … before dispatching"), run-log | **6 103** | **≈ 7 930** (+ models.md 691 → ≈ 8 830) | athanor.md 16% |
|
||||
| **Athanor start (branch)** | + gremlins, longer athanor/impl | 7 330 | spawning 3077, run-log 552 | **10 959** | **≈ 14 250** (+ models 854 → ≈ 15 360) | athanor+gremlins 34% |
|
||||
| **Planner** | planner.md, project, workpad, implementation, CLAUDE.md | 3 829 | — | 3 829 | **≈ 4 980** | 7.5% |
|
||||
| **Attacker** | attacker.md + same | 3 867 | — | 3 867 | **≈ 5 030** | 8.4% |
|
||||
| **Reviewer** | reviewer.md + same | 3 817 | — | 3 817 | **≈ 4 960** | 7.2% |
|
||||
| Adept (for reference) | adept.md, workpad, adepts, CLAUDE.md | 3 416 | adepts/CLAUDE.md + handoff (project data) | 3 416+ | ≈ 4 440+ | 42% |
|
||||
| Zathras (for reference) | zathras.md + skill, project, workpad, adepts | 3 349 | — | 3 349 | ≈ 4 350 | 33% |
|
||||
|
||||
The bundles look like this: **workpad (1768 words) is preloaded into seven agents**, and **implementation (1395) is preloaded into planner, attacker and reviewer**. In each of those three, workpad plus implementation makes up ~83% of what the agent carries. Only 7–8% is its own job description.
|
||||
|
||||
## 2. Content classes
|
||||
|
||||
Classes: **a** agent-specific operational instruction · **b** project/harness facts · **c** general knowledge the model has · **d** filler (persona, motivation, history, repetition, hedges, examples restating a rule) · **e** stale or contradicting.
|
||||
|
||||
### Overall split
|
||||
|
||||
Weighted over all 24 953 words on main: **a 42% · b 22% · c 9% · d 23% · e 4%** (≈ 10.5k / 5.5k / 2.2k / 5.8k / 0.95k words).
|
||||
|
||||
Per bundle (with mandated reads):
|
||||
- **Igor boot:** a 41 · b 16 · c 10 · d 30 · e 3
|
||||
- **Athanor start (main):** a 41 · b 27 · c 10 · d 18 · e 4
|
||||
- **Planner/attacker/reviewer:** a ~45 · b ~12 · c ~17 · d ~23 · e ~3. Much of the "a" is somebody else's job (the reviewer carries the attack procedure and the bug-hunting rules; the planner carries the phase-review rules).
|
||||
|
||||
### Per file (estimates)
|
||||
|
||||
| File | a | b | c | d | e | Notes |
|
||||
|---|---:|---:|---:|---:|---:|---|
|
||||
| igor SKILL | 45 | 12 | 5 | 33 | 5 | Persona/voice 9–41 ≈ 544 words; delegation rule restated ~8×; three near-identical adept spawn templates (133–161, 164 words) |
|
||||
| mindset.md | 15 | 0 | 5 | 80 | 0 | Philosophy plus a note to future editors ("Protect them in any rewrite") |
|
||||
| model-tiers.md | 40 | 30 | 0 | 25 | 5 | Table near-duplicates igor SKILL 77–89 |
|
||||
| harness-notes.md | 0 | 0 | 0 | 90 | 10 | Moved-stub restating spawning rules |
|
||||
| journal-template | 60 | 10 | 0 | 30 | 0 | |
|
||||
| project skill + project.md | 40 / 85 | | | | 20 / 15 | project.md is stale (see e) |
|
||||
| adepts SKILL | 20 | 40 | 0 | 40 | 0 | 40-word developer HTML comment loaded into every boot |
|
||||
| workpad SKILL | 45 | 10 | 25 | 20 | 0 | Ticket context 48–68 ≈ 346 words; document-kind definitions |
|
||||
| implementation SKILL | 55 | 10 | 10 | 20 | 5 | Rationale paragraphs; Bugs section is generic |
|
||||
| spawning-claude-code | 10 | 75 | 0 | 10 | 5 | Good "b" content; history rows |
|
||||
| run-log | 70 | 10 | 0 | 20 | 0 | Field-heavy (see §4) |
|
||||
| models.md | 10 | 50 | 0 | 40 | 0 | Sources list, withdrawn notes |
|
||||
| superpowers.md | 30 | 40 | 0 | 25 | 5 | Only read on demand |
|
||||
| athanor.md | 55 | 10 | 0 | 25 | 10 | Furnace persona; stale fork step |
|
||||
| planner.md | 80 | 0 | 10 | 10 | 0 | Tightest file in the plugin |
|
||||
| attacker.md | 45 | 0 | 0 | 45 | 10 | ~70% restates implementation 24–34, which it also preloads |
|
||||
| reviewer.md | 40 | 0 | 0 | 55 | 5 | ~60% restates implementation 51–58 |
|
||||
| adept.md | 60 | 15 | 5 | 20 | 0 | Folder tree duplicates the scaffolded adepts/CLAUDE.md it reads at genesis |
|
||||
| researcher / search / scout | 20–40 | 0 | 30–50 | 15–30 | 0–5 | Tool lists, "start narrow" |
|
||||
| zathras SKILL | 25 | 25 | 0 | 40 | 10 | Persona plus a contradicting model rule |
|
||||
| research / research-tree | 35–50 | 0–5 | 20–25 | 25 | 5–10 | |
|
||||
| init / curator / knowledge / svg | mostly a+b | | | | | Human-triggered or on-demand, outside the bundles |
|
||||
|
||||
### (c) General knowledge: quotes
|
||||
|
||||
- `agents/search.md:27-29`: "**Start narrow.** Use Grep with a specific symbol or pattern before broadening." / "**Read strategically.** Don't read entire large files"
|
||||
- `agents/researcher.md:31`: "**Synthesize, don't summarize.**"; `:41-42` "Use clear headings and short paragraphs" / "Lead with the answer"
|
||||
- `agents/researcher.md:13-18`, `search.md:12-17`, `scout.md:12-17`: tool lists that restate the frontmatter (`- Search code and files (Glob, Grep)` …)
|
||||
- `skills/research/SKILL.md:55-56`: explains what `WebFetch` and `WebSearch` do
|
||||
- `skills/workpad/SKILL.md:97-103`: textbook distinctions ("A brainstorm is divergent … A design is convergent")
|
||||
- `skills/research-tree/SKILL.md:44`: topological layering explained ("always one past its deepest prerequisite")
|
||||
- `skills/implementation/SKILL.md:63`: "**Explore before you focus.** Look one or two layers up from the symptom, skim recent commits …"
|
||||
- `skills/igor/SKILL.md:63`: "**Fearlessness means flagging misconceptions.** When the user has a factual error, say so directly."
|
||||
|
||||
### (d) Filler: quotes
|
||||
|
||||
- `skills/igor/SKILL.md:9`: "Says \"yeth, marthter\" exactly zero times."
|
||||
- `skills/igor/SKILL.md:21`: "Every minute spent doing work yourself is a minute you are unavailable to the user. Your value is proportional to your presence." (again at `:65` and `mindset.md:27`)
|
||||
- `skills/igor/SKILL.md:23`: "This directive governs everything below. … If any instruction below seems to conflict with delegation, delegation wins."
|
||||
- `skills/igor/SKILL.md:34`: the furnace grammar rule ("never 'the Athanor is in the oven' or similar inversions"). The same metaphor repeats at `:91`, `athanor.md:4-6`, `athanor.md:21` ("You ARE the oven"), `zathras SKILL:15`, README:32
|
||||
- `skills/igor/SKILL.md:36-41`: four example flourishes
|
||||
- `skills/igor/references/mindset.md:21-29`: "The five voice lines … Protect them in any rewrite". This is an editor instruction that loads into every Igor run
|
||||
- `skills/zathras/SKILL.md:13`: "Not Zathras the great leader, not Zathras the quiet one. This Zathras." and `:37-40` example lines
|
||||
- `plugins/spire/CLAUDE.md:1`: "a wizard's private workshop where knowledge accumulates"
|
||||
- `skills/implementation/SKILL.md:30`: "This step is what pays for dropping per-task review. … Without it, lean is just less review." (and again in `igor SKILL:99`)
|
||||
- `skills/igor/SKILL.md:93`: "(in spacecraft it overrode 4.6 pins in 184 of 184 spawns)". This is history inside a rule
|
||||
- `skills/research/SKILL.md:12-14`: the "core problem this solves" narrative
|
||||
- `skills/adepts/SKILL.md:7-10`: "Note: This skill uses Bash(bash:*) … a novel pattern. … Per harness design this should pre-approve"
|
||||
- `references/spawning-claude-code.md:51`: a row that says it "is not evidence for alias-over-pin"
|
||||
- `references/models.md:26`: withdrawn 4.6/Opus-5 notes kept in the active file
|
||||
- `agents/planner.md:33`, `attacker.md:39`, `reviewer.md:35`: "Do this yourself; do not dispatch further agents." None of these agents has the Agent tool in its `tools:`, so the sentence does nothing. The same goes for `search.md:21`: "You do not have the Agent tool. Do not attempt to use it. Do not suggest that work be delegated"
|
||||
- Gremlins (branch): 17 review-finding tags the model cannot resolve, such as "(P0.1)", "(M16)", "(N1)", "(Minor 13)", "(Phase 1 M3)", "(C4)". "N1" names two different things (`gremlins/SKILL.md:105` delta-section rule, `:111` orphan watchdog)
|
||||
|
||||
### (e) Stale or contradicting: quotes
|
||||
|
||||
- `agents/athanor.md:32`: "A complex block in the area you just read can go to a fork of yourself" and `skills/implementation/SKILL.md:49` "**trunk and forks** … go to a fork of the builder". The goal decision of 2026-10-16 (`goals/headless-forks.md:47`) drops Agent-tool forks, and `spawning-claude-code.md:61` records the `fork` type as not offered. On main this tells the Athanor to use a path that is not there. The branch fixes it.
|
||||
- `skills/igor/SKILL.md:66`: "**Fork sparingly.** Forking yourself is a last resort." Same unavailable mechanism.
|
||||
- `skills/zathras/SKILL.md:74`: "**Model must be explicit.** Always pass `model` on `Agent` calls." This contradicts `igor SKILL:93` and `spawning:18` ("Pinned agents: omit `model`"). Passing the alias overrides the pins (184/184).
|
||||
- `skills/zathras/SKILL.md:70`: "Multi-file refactors, cross-cutting changes → Athanor" vs `model-tiers.md:22` "the `athanor` gets a reshaped build plan, never an unplanned build brief".
|
||||
- `skills/igor/SKILL.md:173`: "Give every dispatched agent an explicit output file path". `scout` and `search` have no Write tool.
|
||||
- `skills/igor/SKILL.md:99`: "Igor with user or Pinky" and "(trial since 0.2.2)". Pinky does not exist ("Pinky, when it exists", `spawning:54`).
|
||||
- `skills/igor/SKILL.md:43`: "If it loaded the blank template (the hint says 'run /spire:init')". `skills/project/SKILL.md` never loads the blank template. It echoes a one-line message, so `igor/references/project.md` (351 words) is unreachable through that path.
|
||||
- `.claude/spire/project.md` (injected into every bundle): the agent list "igor, athanor, adept, researcher, scout, search, zathras" has no planner/attacker/reviewer. There is no `## Build` section, though implementation:82 reads it. The field is called "Verification commands", not Gate/Tests. "Legacy: `plugins/g4b_ai/` still exists (… being phased out)".
|
||||
- `skills/research/SKILL.md:121`: "Which model to use — out of scope" right below its own model table (`:26-30`). Same at `research-tree:100`.
|
||||
- `agents/researcher.md`: three fetch caps, "at most 3–5" (`:23`), "1–3 key sources" (`:30`), "at most **5** … hard cap" (`:36`).
|
||||
- `skills/research/SKILL.md:59-63`: MCP server names (`@anthropic/fetch`, `markdownify`, `jina-reader`) that are not verified.
|
||||
- `skills/init/SKILL.md:219,226`: the adept template frontmatter has two `status:` keys (`generated` and `active`).
|
||||
- `skills/adepts/SKILL.md:9-10`: "should pre-approve the command at load time". The gremlins work found that `allowed-tools` did *not* pre-approve in a subagent (`gremlins/SKILL.md:27`, P0.8).
|
||||
- `athanor.md:60` and `implementation:87`: two paragraphs on superpowers, which the user no longer runs, loaded at every Athanor start to say it is "not part of the loop".
|
||||
|
||||
## 3. Duplication
|
||||
|
||||
| Rule | Where (file:line) | Count |
|
||||
|---|---|---:|
|
||||
| Igor delegates / "work vs conversation" | igor SKILL 15–21, 29, 54, 65, 67, 186; mindset 19, 25–29; zathras 21 | ~9 |
|
||||
| Stamp the model id / check the stamp | igor 93; model-tiers 39; spawning 20; implementation 53, 68; run-log 9, 37; athanor 45; planner 34; attacker 40; reviewer 37 | 11 |
|
||||
| Pinned → omit `model`, unpinned → pass alias, no Fable | igor 93; model-tiers 35–40; spawning 18–19, 47–49; athanor 45; models.md 31; (contradicted: zathras 74) | 6 |
|
||||
| Leaf briefs "do this yourself; do not dispatch" | igor 181; harness-notes 12; spawning 21; implementation 67; athanor 46; zathras 74; model-tiers 33; research 111; planner/attacker/reviewer | 11 |
|
||||
| Gate between blocks, tests once per phase | igor 99; implementation 18, 41; athanor 33–34; attacker 32; init 72–73; project template 27–28 | 7 |
|
||||
| Review: answer every flag, hunt weakened checks / tests that cannot fail, list unplanned additions | igor 99; implementation 54–55; reviewer 22–24; athanor 34; run-log 54 | 5 |
|
||||
| One fix pass, re-check only Critical/Important, stop | igor 104–105, 177; implementation 19, 56–57; athanor 40; reviewer 29–31; superpowers 20 | 7 |
|
||||
| Separation of roles | igor 101; implementation 22; planner 15; attacker 15; reviewer 16; athanor 51; model-tiers 11–13 | 7 |
|
||||
| Attack checklist | implementation 26–28; attacker 19–25; igor 99 | 3 |
|
||||
| Code in a plan only where its form is the decision | implementation 34; planner 29; attacker 33; superpowers 21 | 4 |
|
||||
| Times from `date`, not feel | igor 174; implementation 76; run-log 7–8; journal-template 14 | 4 |
|
||||
| Agents write their own reports | igor 173; athanor 54; zathras 82; model-tiers 21 | 4 |
|
||||
| Goals read-only | igor 178; athanor 53; zathras 86 | 3 |
|
||||
| Notifications = turn ending | igor 180; harness-notes 9; spawning 22 | 3 |
|
||||
| Research agent tiers and fetch caps | research 26–32, 49; model-tiers 8–10; igor 79–81; researcher 23/30/36; search 38; scout 33 | 6+ |
|
||||
| Athanor furnace metaphor | igor 34, 91; athanor 4–6, 21; zathras 15; README 32 | 6 |
|
||||
| Adept folder tree | adept.md 114–131; init 181–198 (→ adepts/CLAUDE.md, read at genesis) | 2 |
|
||||
| Delegation table | igor 77–89; model-tiers 5–17; zathras 65–72 | 3 |
|
||||
|
||||
Inside the planner/attacker/reviewer bundles, the agent body restates rules that are also in the preloaded implementation skill, so each agent reads the same rule twice per start.
|
||||
|
||||
## 4. Steering risk
|
||||
|
||||
The user's earlier finding is that a single sentence steers Opus 5.5 strongly. These sentences most likely push toward over-building, over-verifying or audit-style notes.
|
||||
|
||||
**Toward audit-style review and long notes**
|
||||
1. `agents/reviewer.md:22`: "Answer **every** deviation and flag in the run log's handoff notes, one by one." This is reinforced at `implementation:54` and `igor SKILL:99` ("it answers every handoff flag"). Together with item 2, the review turns into a point-by-point audit, and its length follows the builder's flag count, not the risk.
|
||||
2. `references/run-log.md:54`: "Flags for the reviewer: every deviation and every 'flagged for review' line above, one per bullet". `:41` invites "anything the reviewer should look at". Builders flag freely and reviewers answer each one.
|
||||
3. `references/run-log.md:37-44`: eight fields per block (model, start/end `date`, done, deviations, flagged, left for later, expected broken, commits), plus a Tokens column, provisional status and "Not run / untested". The branch adds usage tables. Nothing caps the length.
|
||||
4. `agents/reviewer.md:23`: "**Hunt** weakened checks … and tests that cannot fail". "Hunt" invites a search that keeps going until it finds something.
|
||||
|
||||
**Toward over-building (scope)**
|
||||
5. `agents/attacker.md:25`: "Missing function: a thing planned that does nothing, a path with no way back (onboarding without offboarding), error handling, security." This asks the attacker to add scope, against its own `:33` "Scope cut back to the goal". It is probably the strongest single scope-widener in the cycle.
|
||||
6. `agents/attacker.md:23` / `implementation:26`: "consumers of changed semantics … other readers, stats, migrations, callers in other crates". Useful, but with no stopping rule.
|
||||
7. `agents/planner.md:26`: "within a phase, **steps** with a completion criterion each". `models.md:17` already notes that 5.5 plans ran ~11× larger, yet planner.md has no size cap.
|
||||
8. `research-tree:41`: "List every sub-topic you can think of, even ones that feel redundant."
|
||||
|
||||
**Toward over-verifying**
|
||||
9. `igor SKILL:93`: "check the stamped id before acting on the result; if it is not the intended model … re-dispatch". The stamping rule appears 11 times across the bundles (§3).
|
||||
10. `athanor.md:34`: "read the fix's diff for loosened assertions or deleted checks before you report green". This is the reviewer's job, done a second time by the builder. The branch makes it a mechanical per-block grep (`git diff … | grep -c '^-.*assert'`).
|
||||
11. `implementation:62-63`: "If you cannot write the failing test, keep investigating" plus four exploration acts before any bug fix ("Skip this for obvious bugs" helps).
|
||||
12. `igor SKILL:187`: every wrap-up runs adept handoffs, accretion, and graduation candidates. `mindset`/`igor:61`: "**Best over fastest.**" pushes toward thoroughness over speed in general.
|
||||
13. `adept.md:81`: refresh `handoff.md` after every state-changing consultation, plus journal entries and `search` dispatches ("Don't guess").
|
||||
|
||||
**Sentences that are missing (would push toward small and simple)**
|
||||
- No size limit for plans, build plans, run logs, review reports, session journals or the Athanor's deliverable. The only caps in the plugin are adept `handoff.md` ≤ ~40 lines, adept `CLAUDE.md` ≤ ~60 lines, docs split at ~200 lines, and trunk notes "a page".
|
||||
- No "the smallest change that meets the goal" or "prefer deleting to adding" for planner, attacker or builder.
|
||||
- No "happy path first; edge cases only where the plan names them."
|
||||
- No reviewer rule like "report findings only; do not list what you checked and found fine; an empty section is omitted."
|
||||
- No "flag only what you are unsure of; 'none' is the normal answer" for handoff notes.
|
||||
- No cap on tests added per block, and no "a test per behaviour the plan names, not per branch."
|
||||
- The attacker has no "cutting is the main job; adding a function needs the goal to require it."
|
||||
|
||||
## 5. Sweet-spot options
|
||||
|
||||
Options for discussion, not decisions. The target sizes are rough and assume the content classes above.
|
||||
|
||||
### Igor boot (now ≈ 6.3k words / 8.2k tok)
|
||||
|
||||
- **Option I-1, lean (≈ 2.2–2.6k words / ~3k tok).** Persona in two lines, one flourish rule, no examples. Delegation stated once with the line test (code, commands or artifacts → delegate). Drop mindset.md from boot and keep "Orienting is not deciding" as one bullet. One delegation table: delete model-tiers.md or turn it into the only table. One adept spawn template with a variant line. The cycle as stage list plus decision tree (~250 words), pointing to implementation for detail. Replace the workpad preload with a 150-word placement card (folders, `YYYY-MM-DD-hh-slug`, stage→folder), since Igor delegates the writing. Remove the history and Pinky.
|
||||
- **Option I-2, moderate (≈ 4k words / ~5.2k tok).** Keep the Voice section but cut it to ~150 words and keep workpad preloaded. Remove only the duplicates (delegation ×8, model rules, notification rules) and the stale fork and Pinky lines.
|
||||
- Either way: fix the injected project.md (agent list, a `## Build` section), drop the adepts dev comment, and fix the zathras model contradiction.
|
||||
|
||||
### Athanor start (main ≈ 6.1k words / 7.9k tok; branch ≈ 11k / 14.3k)
|
||||
|
||||
- **Option A-1, lean core (main ≈ 1.8–2.2k words; branch ≈ 3.5–4k).** athanor.md at ~500 words: procedure plus keepers, no furnace description, no superpowers, no fork step. A "builder core" excerpt of implementation (~400 words: build-phase rules, deviation logging, project settings) instead of the whole skill. The run-log template cut to ~200 words: block row, a handoff note of Done / Deviations / Flags (default "none") / Commits, and a phase close. The spawning reference split into a ~250-word rules card (preloaded or mandated) and the claim tables on demand. No workpad preload, because the brief and the run-log template give the paths. On the branch: split gremlins into a core of ~800–1000 words (setup, the call sequence, waiting, failure → action) and an on-demand results/flags reference, and strip the finding IDs.
|
||||
- **Option A-2, keep structure (main ≈ 4k).** Keep the skills preloaded but delete the duplicates (stamp ×4, leaf ×3, fork, superpowers paragraph) and cap the run log ("a handoff note is at most 8 lines").
|
||||
|
||||
### Planner / attacker / reviewer (now ≈ 3.8–3.9k words each, 7–8% their own)
|
||||
|
||||
- **Option P-1, self-contained (≈ 500–800 words each).** Each agent body carries its whole procedure: planner as now, attacker as now minus "Missing function", reviewer as now. Add a ~200-word shared "cycle contract" (roles, gate/test cadence, severity grades, where outputs go), duplicated on purpose or put in a tiny `spire:cycle` skill. Preload neither workpad nor implementation, because the brief names the output path. That makes each start about 5–7× smaller.
|
||||
- **Option P-2, preload a slim implementation.** Shrink implementation itself to ~700 words (move Bugs, Context and Composition into references), keep the preload, and drop the agent-body restatements.
|
||||
- Either way, add size and simplicity sentences: planner "a plan fits in ~N lines; cut anything the goal does not need"; attacker "cutting is the main job; added scope needs the goal to require it"; reviewer "findings only; answer a handoff flag only when it hides a finding; no 'checked, fine' lines".
|
||||
|
||||
### Read-only agents (scout/search/researcher)
|
||||
|
||||
- About 100–200 words each would do: the budget, the output form, the fetch cap (one number). Drop the tool lists and the "you do not have the Agent tool" paragraphs, which the tool restriction already enforces.
|
||||
|
||||
### Order of savings (rough, per start)
|
||||
|
||||
1. Stop preloading workpad where the brief gives the path: −1.8k words in each of 6 bundles.
|
||||
2. Stop preloading full implementation into planner/attacker/reviewer: −1.4k words each.
|
||||
3. Cut Igor persona, mindset and delegation repetition: −1.2 to −1.8k words at boot.
|
||||
4. Split spawning and gremlins into a core card plus on-demand tables: −1 to −2.5k on the branch Athanor.
|
||||
5. Remove stale and contradicting lines (fork, Pinky, zathras model rule, project.md): small in words, large in steering.
|
||||
Reference in New Issue
Block a user