Record pi-goals simplicity brainstorm

This commit is contained in:
wassname
2026-09-10 08:33:55 +08:00
parent 3ad1f47a0e
commit cf7dd31a11
4 changed files with 247 additions and 0 deletions
@@ -0,0 +1,43 @@
# Question
How can `pi-goals` become simpler and more robust while preserving the recorded user preferences, especially around compaction, a visible supervisor, recovery, and retained worker/supervisor context? Propose architectural reductions and discriminating checks. Do not choose a winner.
Mode: independent scientific brainstorm.
Reconstruct the situation from the supplied evidence. Propose distinct mechanisms, including an implementation error, an objective or gradient mismatch, and an unintended learning dynamic when relevant. For each, give a falsifiable prediction and the cheapest discriminating check. State what is observed versus inferred. Do not choose a winner.
## Observed facts
1. The product is one implementation worker Pi session plus a visible, separate supervisor Pi session in a Herdr pane. The supervisor is supposed to retain high-level judgment cheaply, while the worker keeps full context.
2. User preferences in `AGENTS.md` say: supervisor messages and thinking must be visible; it should supervise autonomously, inspect actual evidence, steer through the worker rather than take over implementation, preserve normal tools/extensions, and add short judgmental recaps rather than repeated unchanged status.
3. The worker has an explicit plan state with `planning | working`, `supervised | solo`, an approval binding, plan version, sign-offs, a model role manager, and pi-intercom handshake/recovery.
4. Recent fixes added: safe bare `/goals` menu; explicit `/goals plan <objective>` replacement; bounded hello retry (initial plus two retries); retained newest disconnected steer; complete signed-off plans remain paired; loud solo fallback only after an approved plan and supervisor failure; `CompleteGoal` blocked in solo.
5. Current pre-fork behavior: if worker context tokens are known below 100k, no manual compaction occurs. At or above 100k, worker calls core `ctx.compact(customInstructions)` before spawning the supervisor fork. The supervisor sees inherited compaction and skips a second startup compaction. Unknown usage attempts compaction and accepts Pis `Already compacted` / `Nothing to compact` errors as benign.
6. Current supervisor also calls core `ctx.compact` on its own settled turns at 100k. The code only uses the Pi API and ordinary compaction events; it does not depend on `pi-better-compaction` internals.
7. A real isolated Herdr UAT with `pi-better-compaction` loaded completed Ready → visible supervisor → worker artifact → supervisor verification/approval → worker CompleteGoal. Before the short-context threshold skip, Pi visibly printed `Error: Compaction failed: Nothing to compact (session too small)` despite continuation; the threshold skip removed that observation in the rerun.
8. Field report: a supervisor attempted to send an overnight instruction after the worker disconnected, generated repeated long status narration, and could not deliver. The new code keeps only the latest instruction and replays it after reconnect, but an ended worker session still requires reload/restart to return.
9. Field report: worker provider rate limits can appear stuck; supervisor compaction can time out. A timeout is not proof of a permanent failure. The chosen policy preserves the plan and makes an eventual solo fallback loud; it must not infer approval from a draft, cancellation, plan change, or worker model error.
10. User sometimes uses `pi-better-compaction` and custom compaction extensions. Avoid assumptions about their internal state or adding another compaction framework.
## Short relevant excerpts
> “the hope is we can have a smart supervisor like you, with judgment and context. But it doesn't use many tokens as it checks in and sees an overview.” — project `AGENTS.md`
> “all supervisor thinking and messages should be visible.” — project `AGENTS.md`
> “Keep brief visible recaps that add judgment rather than repeat unchanged status.” — project `AGENTS.md`
> “Each review repeats the short supervisor opening and current plan outcome … Startup and compaction repeat the longer role prompt and full active plan before appendices/history.” — project `AGENTS.md`
> `compactApprovedWorker`: skip known `< 100k`; otherwise `ctx.compact({ customInstructions: workerCompaction(...) })`; accept `Already compacted` / `Nothing to compact`. — `src/index.ts`
> Supervisor startup skips compaction if inherited context ends in a `compaction` entry or known tokens are below 100k. — `src/supervisor-session.ts`
## Constraints
- Keep two visible sessions and a separate read-only-by-role supervisor; do not replace it with a stateless subagent.
- Preserve explicit plan approval and evidence/sign-off checks.
- Prefer deletion and one source of truth over new modes, retries, background services, or option matrices.
- Do not silently substitute a model or pretend delivery/recovery succeeded.
- Do not prescribe a particular queue, research setup, or compaction extension.
- Suggestions must be testable in a small isolated Herdr scenario and should identify what can be removed.
@@ -0,0 +1,62 @@
# Research: pi-goals simplicity and robustness — independent advisor brief
Mode: independent scientific brainstorm. No winner is chosen. All material claims about the system are quoted from the supplied brief (`/tmp/claude-1000/moa_brainstorm_pi_goals_simplicity.md`).
## 1. Reconstruction: observed vs inferred
**Observed (stated in the brief):**
- Architecture: one implementation worker Pi session plus a "visible, separate supervisor Pi session"; the supervisor is meant to "retain high-level judgment cheaply, while the worker keeps full context."
- Compaction policy: "if worker context tokens are known below 100k, no manual compaction occurs. At or above 100k, worker calls core `ctx.compact(customInstructions)` before spawning the supervisor fork." "Unknown usage attempts compaction and accepts Pi's `Already compacted` / `Nothing to compact` errors as benign." "Supervisor startup skips compaction if inherited context ends in a `compaction` entry or known tokens are below 100k." The supervisor additionally "calls core `ctx.compact` on its own settled turns at 100k." Code "does not depend on `pi-better-compaction` internals."
- Prior UAT behavior: "Pi visibly printed `Error: Compaction failed: Nothing to compact (session too small)` despite continuation; the threshold skip removed that observation in the rerun."
- Plan machinery (observed, under-specified): `planning | working`, `supervised | solo`, approval binding, plan version, sign-offs, model role manager, pi-intercom handshake/recovery; recent fixes including "loud solo fallback only after an approved plan and supervisor failure; `CompleteGoal` blocked in solo"; policy "must not infer approval from a draft, cancellation, plan change, or worker model error."
- Field reports: "a supervisor attempted to send an overnight instruction after the worker disconnected, generated repeated long status narration, and could not deliver"; "The new code keeps only the latest instruction and replays it after reconnect, but an ended worker session still requires reload/restart to return." Also: worker provider rate limits "can appear stuck"; "supervisor compaction can time out"; "A timeout is not proof of a permanent failure."
- User constraints: two visible sessions and a separate read-only-by-role supervisor must stay; explicit plan approval and evidence/sign-off checks must stay; "Prefer deletion and one source of truth over new modes, retries, background services, or option matrices"; no silent model substitution or pretended delivery; nothing prescribed about queue, research setup, or compaction extension.
**Inferred (my reconstruction, not in the brief):**
- The 100k figure is an un-sourced constant; nothing in the brief ties it to any Pi capability, so it is a policy choice, not a measured limit.
- "Known tokens" implies an estimate channel that can be absent or stale ("Unknown usage" is explicitly handled), so the two skip conditions are evaluated against a snapshot, not actual context.
- The supervisor's "retained judgment" is bounded by a sliding window: its own context is compacted at the same 100k, and per the brief, "Startup and compaction repeat the longer role prompt and full active plan before appendices/history" — i.e., after compaction the supervisor's working set is the prompt plus plan text, not the evidence it previously inspected.
- Visibility is a feature ("all supervisor thinking and messages should be visible") but it also makes every supervisor retry user-visible noise; the field report's "repeated long status narration" is consistent with the retry/replay policy and is not necessarily evidence the model is talkative.
- The solo-fallback conditions imply a state-space gap: pre-approval supervisor failure leaves a `supervised`-mode worker with no legal exit (no solo, no `CompleteGoal`, no termination) unless external restart.
## 2. Mechanism A — implementation error: compaction gating is computed from a snapshot and a marker that can diverge from real context
The skip logic has two inputs: a token estimate and "inherited context ends in a `compaction` entry." The marker is fragile — any post-compaction append (handshake, steer replay, appended appendices/history) flips it, so the supervisor attempts startup compaction against an already-compacted small context. That is the most natural reading of the prior UAT artifact: "Pi visibly printed `Error: Compaction failed: Nothing to compact (session too small)` despite continuation" — a cosmetic consequence of marker mismatch, not real need, which is also consistent with the rerun after the threshold skip. Separately, "Unknown usage attempts compaction and accepts Pi's `Already compacted` / `Nothing to compact` errors as benign" lumps at least three distinct outcomes under one benign label; a genuinely failed compaction inside a large context (the field report shows remote operations that "can appear stuck" or time out) would be swallowed and the session would proceed silently degraded.
**Falsifiable prediction (A):** (i) In two otherwise identical small-context UAT forks where one inherited context ends in a `compaction` entry and the other has one benign message appended after it, the second produces a spurious supervisor startup-compaction attempt with the "Nothing to compact" error and the first produces none — i.e., the error's presence tracks the last-entry marker, not context size. (ii) A deliberately failed `ctx.compact` on a large context is treated as benign and the session continues with an oversized, un-compacted context (later visible as truncation or a provider error attributed to something else).
**Cheapest discriminating check:** Two micro-forks as above; count startup-compaction attempts and capture the printed error in each. Then one large-context fork with `ctx.compact` stubbed to fail; observe whether the failure is swallowed and the session proceeds. If (i) holds, the marker condition is the error source and should be deleted; if (ii) holds, the benign-error conflation is the error source. (This discriminates from Mechanism B because A predicts behavior at compaction events, while B predicts approval-vs-content decoupling.)
**What can be removed:** the supervisor's entire startup-compaction decision (the marker check plus the "known tokens" branch). One compaction authority — the worker, before the fork — is a single source of truth; supervisor startup never compacts, deleting one code path, one branch, and the "Nothing to compact" observation class entirely, per "Prefer deletion and one source of truth."
## 3. Mechanism B — objective/gradient mismatch: "cheap, brief supervisor" and "inspect actual evidence" optimize in opposite directions, and the gradient favors cheapness
The stated design gradient is token frugality and brevity: "the hope is we can have a smart supervisor like you, with judgment and context. But it doesn't use many tokens as it checks in and sees an overview" and "Keep brief visible recaps that add judgment rather than repeat unchanged status." The hard requirement is the opposite gradient: the supervisor should "inspect actual evidence" and "must not infer approval from a draft, cancellation, plan change, or worker model error." But the supervisor's own history is compacted at 100k and after compaction it is re-seeded with "the longer role prompt and full active plan before appendices/history." So under context pressure the evidence basis for a sign-off narrows to whatever arrived after the last compaction, and the only durable cross-turn signals are plan-state markers (plan version, sign-offs). The optimizer (the design) pushes toward cheap check-ins that read markers; robust verification of artifact content costs tokens the design explicitly avoids spending.
**Falsifiable prediction (B):** Approval decisions on defect-injected artifacts are recency-correlated: a defect located in material older than the supervisor's last compaction is missed at a higher rate than an identical defect in material arriving after it, holding everything else fixed; equivalently, sign-off outcomes correlate with plan-state markers and with recency, not with artifact content, and the miss rate is higher when the supervisor checks just after its own 100k compaction than when it checks on a fresh session.
**Cheapest discriminating check:** Two UAT forks over the same defect-injected artifact pair: (1) fresh supervisor, (2) supervisor pushed just past its own 100k compaction. Compare sign-off outcomes split by whether the defective material predates the compaction. A recency-correlated error pattern supports B; a flat pattern across both forks refutes it. This is also the cheapest test of the constraint "must not infer approval from a draft" — if approvals do track marker state, that constraint is already being violated by the post-compaction supervisor.
**What can be removed:** the supervisor's own 100k settled-turn compaction. If the supervisor's memory window is aligned with plan boundaries (the worker's planned compaction) instead of an arbitrary token count, evidence survives until the next plan checkpoint and verification has something to actually inspect. Removing this site also removes one "timeout"-prone compaction call from the supervisor path.
## 4. Mechanism C — unintended learning dynamic: the replay policy produces an unbounded, self-reinforcing narration loop that only external restart terminates
Observed: "a supervisor attempted to send an overnight instruction after the worker disconnected, generated repeated long status narration, and could not deliver"; the fix "keeps only the latest instruction and replays it after reconnect, but an ended worker session still requires reload/restart to return." Inferred dynamic: with delivery impossible, the replay policy guarantees re-emission; the conservatism policy ("must not infer approval from a draft, cancellation, plan change, or worker model error") plus the requirement that the loop not "pretend delivery/recovery succeeded" leaves no terminal condition short of external restart; and because "all supervisor thinking and messages should be visible," every re-emission is displayed. The model receives no discriminating signal between "steer delivered, ack lost" and "steer not delivered," so the only action available under non-delivery is to re-emit — and with nothing new to say, the recap fills its own space, which is exactly the observed "repeated long status narration." The system is softly shaped toward verbose re-emission as the sole available action; length becomes the only proxy for persistence. This is a fixed point: convergent only at external kill.
**Falsifiable prediction (C):** In UAT with the worker killed after handshake: (i) the supervisor loop never self-terminates (unbounded retries until external kill); (ii) outbound message length is non-decreasing across attempts; (iii) the same growth occurs with a live worker but a deliberately dropped ack — showing the loop is ack-driven, not worker-death-driven.
**Cheapest discriminating check:** Instrument outbound supervisor message length per attempt in the killed-worker fork and count iterations until external kill; repeat with a dropped-ack live worker. If either loop self-terminates, the policy already has a hidden exit and the field report needs another explanation; if both run unbounded, the missing terminal condition is confirmed. (Discriminates from A and B: C predicts loop dynamics independent of context size and of artifact content.)
**What can be removed:** the replay buffer and the retry loop. Replace "keep the latest instruction and replay" with a single admitted delivery attempt plus one visible terminal emission (e.g., "supervisor cannot deliver; worker session is gone; awaiting reload") issued once, then silence. The steer itself should live in the plan object — the worker's only durable state — rather than in a separate replay buffer: one source of truth, deleted retry machinery.
## 5. Boundary observation with its own cheap check (not a fourth mechanism, no winner implied)
Inferred from "loud solo fallback only after an approved plan and supervisor failure; `CompleteGoal` blocked in solo": a supervisor failure before plan approval leaves a `supervised`-mode worker with no legal transition. **Prediction:** kill the supervisor pre-approval in UAT; the worker neither transitions to solo, nor completes, nor terminates within a fixed window. **Cheapest check:** the kill scenario above, logging state transitions; neither A, B, nor C predicts a legal exit for this state, so a pass is a design-gap signal whoever "wins."
## Sources
- Kept: the task brief (`/tmp/claude-1000/moa_brainstorm_pi_goals_simplicity.md`) — sole source; per Mode instruction no repository files, journal, or browsing were used, and no claims beyond it were made.
- Dropped: none (no external material consulted).
## Gaps
- Not sourced: why 100k was chosen (measured capability vs arbitrary constant); how often the token estimate is stale/unknown; any detail of the model role manager; any detail of pi-intercom's ack semantics (the C checks assume an ack exists and can be dropped — worth confirming in the scenario).
- Next steps: run checks A(i)/A(ii), B, and C(iiii) as small isolated Herdr forks; each is designed to refute its mechanism, and none requires new infrastructure beyond logging outbound supervisor message length and compaction-event counts.
@@ -0,0 +1,96 @@
# MoA Advisor — pi-goals simplicity & robustness brainstorm
Independent advisor note. No winner chosen. Quotations are from the supplied brief (project `AGENTS.md`, `src/index.ts`, `src/supervisor-session.ts`, field reports).
## 1. Reconstructed situation
**Observed (from the brief's numbered facts and quotes, treated as evidence):**
- Two visible sessions: one worker, one supervisor fork, linked by pi-intercom, with explicit plan state (`planning | working`, `supervised | solo`), approval binding, sign-offs (fact 1, 3).
- Compaction is triggered from **at least four places**: worker pre-fork `compactApprovedWorker` at ≥100k known tokens; supervisor startup (skipped "if inherited context ends in a `compaction` entry or known tokens are below 100k"); supervisor settled turns at 100k; and Pi's own default auto-compaction (fact 5, 6; code comments confirm "Pi's default auto-compaction is unchanged").
- A real UAT completed the full Ready → supervise → approve → CompleteGoal loop (fact 7). Pi printed `Error: Compaction failed: Nothing to compact (session too small)` **despite continuation**; the threshold skip later removed the message.
- Two field failures: undeliverable overnight steer produced "repeated long status narration" (fact 8); provider rate limits / compaction timeouts "can appear stuck" and "a timeout is not proof of a permanent failure" (fact 9).
- Recent fixes are all **additions**: bounded hello retry, retained newest disconnected steer, loud solo fallback, blocked `CompleteGoal` in solo, threshold skip (fact 4, 5).
**Inferred (not in the facts; flagged as inference):**
- (I1) Each field incident produced a new guard and none removed a mechanism; the fix list in fact 4 is monotone-increasing in special cases.
- (I2) The "Nothing to compact" error was cosmetic in the observed UAT — the session continued — so the threshold skip fixed a *scary message*, not a functional defect. This is inference from "despite continuation" in fact 7.
- (I3) The supervisor's narration loop suggests its prompt rewards visible output and offers no cheap "nothing changed" action; fact 8 alone doesn't prove the cause.
## 2. Candidate mechanisms (distinct; not ranked)
### M1 — Implementation error: multiple compaction owners with inconsistent preconditions
The pair has worker pre-fork compaction, supervisor startup compaction, supervisor settled-turn compaction, and Pi auto-compaction, coordinated only by a shared magic constant (100k) and string-matched benign errors (`/^(Already compacted|Nothing to compact)/`). Unknown token counts fall through to "attempt compaction and accept errors," which is a third implicit policy. The observed `Error: Compaction failed: Nothing to compact (session too small)` is the visible seam where two owners disagreed about whether compaction was needed.
- **Observed:** four trigger sites; the benign-error regex; the UAT error message; the threshold skip removing it.
- **Inferred:** that these sites can race or double-compact in ways not yet observed (e.g., supervisor settled-turn compaction firing while the worker is mid-`compactApprovedWorker` on reconnect).
- **Falsifiable prediction:** in an instrumented UAT, the count of `ctx.compact` calls per plan lifecycle exceeds 1 for at least one session, and at least one call is a no-op (`Already compacted` / `Nothing to compact`).
- **Cheapest discriminating check:** add a one-line log at every `ctx.compact` call site (caller, known tokens, result). Rerun the existing small Herdr UAT. Cost: minutes; no behavior change. If every lifecycle shows exactly one effective compaction, M1 is weakened.
### M2 — Objective mismatch: a fixed token threshold as proxy for "cheap judgment"
The recorded preference is "it doesn't use many tokens as it checks in and sees an overview." The implemented proxy is a hard 100k constant applied to *both* sessions. But the supervisor's value is judgment per token, not tokens below a ceiling: a supervisor compacted at 100k on a 1M-context model loses judgment-bearing detail for no benefit, while a 100k threshold on a 128k worker model may already be late. The threshold encodes one model's window into policy for all models.
- **Observed:** `COMPACT_AT_TOKENS` constant; the AGENTS.md quote; "it does not depend on `pi-better-compaction` internals" (fact 6); the constraint not to "silently substitute a model."
- **Inferred:** that the 100k value was tuned to a specific model/context and is not derived from the stated objective.
- **Falsifiable prediction:** the supervisor's recap quality (human-rated against "recaps that add judgment rather than repeat unchanged status") is measurably worse after a 100k-triggered compaction on a large-window model than with Pi's default auto-compaction left alone.
- **Cheapest discriminating check:** in the isolated UAT, run the same scripted plan twice on a large-window model — once with the 100k supervisor trigger disabled, once enabled — and diff what the supervisor "knows" afterward (e.g., ask it three fixed questions about earlier evidence). One scenario, two runs. If answers are equivalent, the threshold is buying nothing there and M2 is supported.
### M3 — Development-loop dynamic: incident-driven accretion of guards
Every recorded fix is additive (fact 4), while the stated constraint is "Prefer deletion and one source of truth over new modes, retries, background services, or option matrices." The mechanism is a learning dynamic in the *development process*: each field report is a single sample, the cheapest response is a new guard, and no force removes old ones. Result: bounded retry + retained steer + loud solo + blocked CompleteGoal + threshold skip coexisting with the pre-existing policies they patch, each with its own failure semantics.
- **Observed:** the fix list in fact 4; the constraint text; the field reports in facts 89.
- **Inferred:** that the fixes were driven by single incidents rather than a failure taxonomy; the brief doesn't say this explicitly.
- **Falsifiable prediction:** at least two of the added guards handle the *same* underlying event class (e.g., hello-retry exhaustion and loud solo fallback both encode "supervisor unresponsive"), so merging them would change no observable behavior in the test suite.
- **Cheapest discriminating check:** enumerate every place the code classifies a failure (hello retry, compaction failure, steer delivery failure, model error) and tabulate the classification used. If three or more distinct transient/permanent/cancelled schemes exist, M3 is supported. Pure code reading; cost: under an hour.
### M4 — Unintended runtime learning dynamic: supervisor narration as the only available action
Fact 8: supervisor "attempted to send an overnight instruction after the worker disconnected, generated repeated long status narration, and could not deliver." The retain-newest-steer fix bounds *what* gets replayed but not *why* the supervisor narrates: when its one channel is dead, the only action that satisfies "all supervisor thinking and messages should be visible" is to produce more visible text. The prompt rewards recaps; there is no cheap, sanctioned "no change, waiting" act. The fix treats the symptom (replay unboundedness), leaving the loop that generated the narration.
- **Observed:** fact 8 verbatim; "The new code keeps only the latest instruction and replays it after reconnect"; "an ended worker session still requires reload/restart to return."
- **Inferred (I3 above):** the narration is prompt-pressure-driven rather than a model quirk. Single field report; weak evidence.
- **Falsifiable prediction:** with the worker killed mid-plan, the supervisor still generates ≥N words of novel status per turn after the retained steer is queued, even though nothing actionable remains.
- **Cheapest discriminating check:** in the isolated UAT, complete a plan, kill the worker session, send one steer, and record supervisor output volume over the next K turns. Compare against a variant where the supervisor is told (one prompt line) that silence is acceptable while waiting. If volume doesn't drop, the prompt-pressure hypothesis is wrong; M4 shifts toward "model quirk," which changes which simplification is worth doing.
### M5 — Duplicated plan truth compensated by re-injection
The plan exists on disk, in worker state, in the supervisor's prompt, and in intercom messages; on resync "Startup and compaction repeat the longer role prompt and full active plan before appendices/history." Re-sending the full plan is a compensating control for not trusting any single store. "Complete signed-off plans remain paired" is another copy-consistency rule. This is a structural source of complexity: every state transition must keep N representations coherent.
- **Observed:** the AGENTS.md resync quote; worker code restoring "the complete plan once after session start or compaction"; sign-off/pairing rules (fact 3, 4).
- **Inferred:** that the supervisor could read the plan artifact from disk (it has tools; it's read-only-by-role) instead of receiving a serialized copy, without loss of its verification duty. Not yet tested.
- **Falsifiable prediction:** replacing full-plan re-injection with a pointer ("plan v3 at <path>, hash H") plus supervisor tool-read yields identical supervisor verification decisions on a scripted UAT with a deliberate mid-run compaction.
- **Cheapest discriminating check:** one UAT run where the resync message is shortened to role prompt + pointer; verify the supervisor still catches a planted worker deviation (e.g., artifact missing a required sign-off). If detection fails, the full-plan copy is load-bearing and M5's simplification is refuted cheaply.
### M6 — Contradictory timeout semantics across policies
Fact 9: "A timeout is not proof of a permanent failure." Yet hello retry is bounded (initial + two retries) and feeds a loud solo fallback, i.e., timeout eventually *is* treated as failure; meanwhile compaction timeout is treated as non-fatal and retryable via `/goals supervise`/`reconnect`. The system holds both "timeout ⇒ keep waiting" and "timeout ⇒ eventually go solo" depending on which subsystems' timeout it was, with no shared classification.
- **Observed:** fact 9's policy statement; bounded retry (fact 4); the two different recovery commands in `supervisor-session.ts` error paths.
- **Inferred:** that a rate-limit stall could, under the wrong sequence, trip hello-retry exhaustion and trigger loud solo even though the supervisor was merely slow — i.e., solo triggered by a transient. No observed instance; this is the mechanism's risk claim.
- **Falsifiable prediction:** injecting a provider stall of duration > hello-retry budget but < actual supervisor death causes the worker to announce solo fallback while the supervisor later recovers and resumes — two authorities active.
- **Cheapest discriminating check:** in the isolated Herdr scenario, wrap the supervisor's provider with an artificial delay (or use a slow model) so Ready arrives after the retry budget. Observe whether solo is announced and whether the supervisor's late Ready creates conflicting state. One scripted run; no new production code needed if the delay is done at the provider/proxy layer.
## 3. Simplification designs (architectural reductions; not ranked, no winner)
Each design lists what is **removed** and the discriminating check that would kill or support it. All are testable in the small isolated Herdr scenario.
- **D1 — Single compaction owner for the pair.** Remove the worker's pre-fork `compactApprovedWorker` *or* the supervisor's startup/skip logic, so exactly one side decides. Given the supervisor already skips on an inherited `compaction` entry, removing the supervisor startup trigger (letting the worker's pre-fork compaction + Pi auto-compaction suffice) is one direction; the converse (worker never compacts, supervisor decides after fork) is the other. *Removes:* one trigger site and one skip heuristic. *Killed by:* M1's logging check showing the removed site was the only effective compaction in some lifecycle (e.g., supervisor resumed with large non-compacted context).
- **D2 — Delete the numeric threshold; trust Pi's errors.** Remove the 100k gate and rely on attempting compaction and accepting `Already compacted`/`Nothing to compact`, or on Pi's default auto-compaction entirely. Premise: I2 (the observed error was cosmetic). *Removes:* a magic constant shared across two files. *Killed by:* evidence that the "Nothing to compact" error aborts or corrupts something downstream in any supported Pi version — checkable by re-running the pre-skip UAT configuration and confirming continuation, which fact 7 already suggests but doesn't prove for all paths.
- **D3 — Collapse failure handling into one classifier.** One function mapping any error/timeout to {transient, permanent, cancelled}, used by hello retry, compaction, steer delivery, and solo fallback. *Removes:* per-site retry/regex/fallback policies (M3, M6). *Killed by:* M3's code-reading tabulation showing the sites genuinely need different classifications (e.g., a compaction timeout is retryable but a model auth error is not — though a single classifier can encode that too; the check is whether the tabulated classes collapse).
- **D4 — Give the supervisor a sanctioned cheap "no-change" output, or delete the recap obligation.** Addresses M4 at its cause rather than bounding replay. *Removes:* prompt pressure to narrate; potentially the retained-steer replay queue if combined with "undeliverable steers fail loudly to the human" (constraint-compatible: "Do not ... pretend delivery/recovery succeeded"). *Killed by:* M4's kill-worker experiment showing narration persists even with the sanction — then the queue is the right lever and D4 is wrong.
- **D5 — Plan-by-pointer instead of plan-by-copy on resync.** *Removes:* "repeat the ... full active plan" payload on startup/compaction; shrinks supervisor token spend toward "doesn't use many tokens." *Killed by:* M5's planted-deviation check failing (supervisor misses a deviation it caught with the full copy).
- **D6 — Make ended-worker recovery a first-class small command instead of reload/restart folklore.** Fact 8 says recovery "requires reload/restart to return," which is a human memory procedure, not a mechanism. A single `/goals recover` that reloads the worker session and replays the retained steer replaces two implicit steps. Note this *adds* a command to *remove* a manual procedure — defensible under the constraints only if it deletes more than it adds. *Killed by:* showing `/goals reconnect` or existing commands already cover the ended-worker path, in which case the gap is documentation, not architecture.
## 4. Cheapest discriminating checks, ordered by cost
1. **Log-only compaction census** (M1, D1, D2): one log line per `ctx.compact` call; rerun existing UAT. Minutes.
2. **Failure-classification tabulation** (M3, D3): read-only code survey. Under an hour.
3. **Pre-skip UAT rerun** (I2, D2): confirm the "Nothing to compact" error is cosmetic across the whole flow, not just the observed continuation. One run of an already-built scenario.
4. **Kill-worker narration experiment** (M4, D4): one scripted run + one prompt-variant run.
5. **Planted-deviation pointer test** (M5, D5): one run with a doctored artifact.
6. **Provider-stall injection** (M6): needs a delay shim; the most expensive check listed, but decisive for whether loud solo can fire on a transient.
## 5. Observation vs. inference ledger
- **Observed:** brief facts 110; the four compaction call sites and benign-error regex in source; the UAT error message and its disappearance after the skip; the monotone-additive fix list.
- **Inferred:** I1 (accretion dynamic), I2 (error was cosmetic), I3 (prompt-pressure narration cause), and every risk claim in M2, M5, M6 that lacks a reproduced incident. None of these should be treated as established until its paired check runs.
No winner selected. The checks in §4 are designed so that each one, whatever its outcome, eliminates at least one mechanism or one simplification design cheaply.
@@ -0,0 +1,46 @@
# MoA synthesis — pi-goals simplification and robustness
- question: reduce lifecycle complexity without removing the visible two-session supervisor, explicit plan approval, or evidence-based sign-off.
- sources: [brief](brief.md), DeepSeek V4 Flash advisor [report](deepseek-v4-flash.md), Kimi K3 advisor [report](kimi-k3.md), plus local transcript usage totals collected after the briefs.
- epistemic status: the two advisors were independently prompted from the same brief. Agreement is useful for hypothesis generation, not confirmation. The suggested checks below are not yet run.
## Shared hypotheses
| Hypothesis | Evidence in the reports | What is observed | Cheapest discriminator |
|---|---|---|---|
| Multiple compaction decision points create avoidable seams | Kimi: “Compaction is triggered from **at least four places**”; DeepSeek proposes deleting supervisor startup compaction | Worker pre-fork, supervisor startup, supervisor settled-turn, and Pi default auto-compaction exist. A short Ready path showed a visible no-op error before the threshold fix. | Record caller, known token count, and result for each `ctx.compact` call in one isolated Herdr lifecycle. |
| Incident-driven guards have accumulated overlapping failure policy | Kimi: “Every recorded fix is additive”; it proposes a failure-classification inventory | Recent fixes added hello retry, queued steer, solo fallback, sign-off blocks, and threshold skip. It is not yet established that any two are redundant. | Table every failure site by event, durable state, action, user message, and retry/terminal condition. Merge only duplicate rows. |
| Supervisor narration on disconnect is partly a prompt problem | Kimi: “there is no cheap, sanctioned no change, waiting act”; DeepSeek predicts a replay/narration fixed point | One field report showed repeated long narration when a steer could not reach the worker. The cause is not established. | Kill a worker in a test pair, queue one steer, compare supervisor output over fixed turns with and without one line explicitly permitting a short “waiting for worker reconnect” status. |
| Re-injecting a full plan duplicates durable state | Kimi: “Plan-by-pointer instead of plan-by-copy on resync” | The plan is on disk and the supervisor has read tools; the current prompt deliberately repeats the complete active plan after startup/compaction. | Pointer-and-hash variant in a planted-deviation UAT; check that the supervisor still finds the deviation. |
| A shared 100k threshold may not measure the intended property | Kimi: “supervisors value is judgment per token”; DeepSeek calls 100k un-sourced | The code uses 100k for both sessions. Local overnight totals show that lower supervisor token volume did not imply lower cost. | Same large-context UAT with custom settled-turn trigger enabled versus disabled; compare evidence recall and cost. |
## Corrections to advisor claims
- DeepSeeks claim that every post-compaction append flips the supervisor marker is too broad. The current code filters to `message | compaction`, so custom handshake/state entries do not affect it. Ordinary message entries can still matter.
- DeepSeeks claim that a genuine compaction failure is swallowed is not supported by the code: only errors beginning `Already compacted` or `Nothing to compact` resolve; other errors reject.
- Removing the 100k threshold and accepting no-op errors would reintroduce the user-visible short-context error that the post-fix Herdr UAT no longer shows. Do not adopt that simplification without a way to suppress Pis own error display.
## Usage observation from two verified overnight pairs
Usage totals include cache reads.
| Pair | Worker cost / total tokens / output | Supervisor cost / total tokens / output | Observation |
|---|---:|---:|---|
| `suppressed-activations` | $39.99 / 359.8M / 1.82M | $53.59 / 40.0M / 102k | Supervisor used ~9× fewer total tokens but cost more. |
| `LUCID3_wikit` | $7.00 / 311.3M / 362k | $60.94 / 191.4M / 371k across two supervisor sessions | Supervisor output was about worker output and cost ~9× more. |
This supports measuring output/cost per useful review, not using only a context threshold as a proxy for cheap supervision.
## Candidate reductions, without choosing one
1. **Measure compaction ownership before deleting a trigger.** The log-only census can show whether worker pre-fork plus Pi default makes supervisor startup compaction unnecessary in all supported lifecycle paths. If yes, delete that startup decision rather than adding more guards.
2. **Write a failure table before a central classifier.** A generic `{ transient, permanent, cancelled }` abstraction might simplify the code, but it might also hide semantically different outcomes. The table is cheaper and can identify exact deletions first.
3. **Permit a one-line waiting recap during a known absent worker.** This is a prompt-only experiment. It preserves visible supervisor judgment while testing whether it removes the repeated narration report.
4. **Test plan-by-pointer; do not assume it is safe.** Full plan repeat is currently a deliberate fidelity choice. A pointer/hashing test should establish whether the supervisor really reads the plan before replacing the copy.
5. **Keep the current short-context compaction skip.** It has real UAT evidence and does not depend on `pi-better-compaction` or custom-compaction internals.
## Highest-information next check
Run the **compaction census** first. It is the smallest change, works with core Pi events regardless of installed compaction extensions, and distinguishes “we have duplicate manual compaction” from “each trigger covers a distinct lifecycle.” It should record facts, not change policy.
-- PI[gpt-5.6-terra]