diff --git a/AGENTS.md b/AGENTS.md index 14e9438ea..39e393d89 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -258,6 +258,38 @@ These apply to any AI harness. `docs/DRIFT-TAXONOMY.md` (operational one-page field guide) — the absorb stayed in-place as provenance; the promotion is the ratification. +- **Substrate or it didn't happen — no invisible + directives (Otto-363).** Before declaring work + *"done,"* identify its durability surface. Chat, + TaskUpdate, `/tmp`, `/var/tmp`, and loop todos are + NOT durable project substrate. If a directive / + decision / packet matters after compaction, it + must be converted into substrate (committed to + canonical git history + reachable from a long-lived + ref + indexed by a canonical bootstrap or index + file — all three legs). 5-tier channel taxonomy: + ephemeral (chat, TaskUpdate, temp dirs — weather) + / local-parked (named stash, local WIP) / + remote-parked (pushed WIP branch like + `wip/-`, draft PR — *"if it matters + enough to come back to, it deserves a git ref"*) / + host-durable-not-git-canonical (GitHub Issues, PR + comments) / git-native-preserved (committed + + reachable-from-long-lived-ref + indexed repo + files). Vocabulary discipline: *captured* + (TaskUpdate / chat) ≠ *parked* (GitHub Issue / + remote WIP branch) ≠ *preserved* (git-native + repo) ≠ *canonical* (accepted spec) ≠ + *operational* (enforced by tooling). When + uncertain about preservation route, default to + `docs/research/` first; promotion to + memory/canonical is cheaper than demotion. Cross- + harness rule: applies to all harnesses, not just + Claude Code. Carved blade: *"A directive that + lives only in a conversation is not a directive. + It is weather. Substrate or it didn't happen."* + Full reasoning: + `memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`. ## Build and test gate diff --git a/CLAUDE.md b/CLAUDE.md index 2107664a8..1724509ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -295,6 +295,42 @@ Claude-Code-specific mechanisms. verify-before-deferring, future-self-not-bound, and never-be-idle. Full reasoning: `memory/feedback_version_currency_always_search_first_training_data_is_stale_otto_247_2026_04_24.md`. +- **Substrate or it didn't happen — no invisible + directives (Otto-363).** Before declaring work + *"done,"* identify its durability surface. Chat, + TaskUpdate, `/tmp`, and loop todos are NOT durable + project substrate. If a directive / decision / + packet matters after compaction, it must be + converted to a durable project object — preferably + substrate (committed + reachable + indexed git- + native repo file: memory / docs/research / docs/ops + / claim file / validator / bootstrap rule). PRs + and issues are host-durable parking surfaces, NOT + substrate; for doctrine-changing decisions, mirror + the substantive content into a git-native file. + Vocabulary discipline: *captured* (TaskUpdate + only) ≠ *parked* (GitHub Issue / pushed WIP branch, + durable but not git-canonical) ≠ *preserved* + (repo-native, committed + reachable + indexed) ≠ + *canonical* (accepted spec) ≠ *operational* + (enforced by tooling). Never call TaskUpdate-only + work *"done."* Verbatim-preservation trigger: when + the human maintainer / external reviewers send an + architecture-changing / doctrine-superseding / + multi-AI review packet, preserve verbatim in + `docs/research/` BEFORE summarizing. + Magnitude classifier: small correction → task; + implementation readiness → task + notes; doctrine + correction → memory file; superseding architecture + → research preservation + memory absorb + + supersession note. Carved blade: *"A directive + that lives only in a conversation is not a + directive. It is weather. Substrate or it didn't + happen."* CLAUDE.md-level so it is 100% loaded at + every wake, alongside verify-before-deferring, + future-self-not-bound, never-be-idle, and + version-currency. Full reasoning: + `memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`. - **Tick must never stop.** When running under `/loop` autonomous mode (cron fires every minute per `docs/AUTONOMOUS-LOOP.md`), the tick is the diff --git a/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-5ai-review-wave-corrections.md b/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-5ai-review-wave-corrections.md new file mode 100644 index 000000000..cd5138534 --- /dev/null +++ b/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-5ai-review-wave-corrections.md @@ -0,0 +1,437 @@ +# Amara final synthesis on Otto-363 — 5-AI review-wave corrections (Substrate or it didn't happen) + +**Date**: 2026-04-29 +**Channel**: Aaron + Amara (relayed) + 5-AI review wave (Alexa / Ani / Deepseek / Claude.ai / Gemini) + Amara final synthesis +**Status**: Research-grade preservation. Verbatim. The 10 review corrections are absorbed into the Otto-363 memory file in the same PR (#855). + +--- + +## Trigger + +After Otto opened PR #855 with Otto-363 (substrate-or-it-didn't-happen rule + 8 mechanisms + verbatim Amara packet + CLAUDE.md bootstrap pointer), Aaron relayed a 5-AI review wave back. Each reviewer (Alexa, Ani, Deepseek, Claude.ai, Gemini) approved the doctrine direction but caught real refinement gaps — particularly around mechanical enforcement, substrate definition, default preservation routing, and supersession-protocol stale-rule risk. + +Amara synthesized the corrections AND caught Otto about to repeat the original failure mode: "Two PRs landing in succession (no waiting)" was the same drag-pattern reflex the rule was meant to prevent. The corrected posture: **finish #855 first; absorb review corrections; land cleanly; THEN open v5 architecture PR as a separate lane.** + +--- + +## Verbatim packet — Alexa + +> 🎯 Excellent Analysis - Here Are Strategic Improvements +> +> Your "NO DIRECTIVES" doctrine brilliantly identifies the core failure mode: ephemeral conversational state masquerading as durable project truth. The mechanisms you've outlined create systematic substrate preservation. Here are refinements and additions: +> +> 🔧 Enhanced Mechanism Stack +> +> **1. Durability Surface Classifier (Expanded)** +> +> ```yaml +> durability_surfaces: +> ephemeral: +> - chat_messages +> - task_updates +> - /tmp_files +> - session_memory +> - loop_todos +> action: "NEVER call done" +> +> github_durable: +> - issues +> - pr_comments +> - labels +> - assignees +> action: "Coordination only, not canonical" +> +> git_native_durable: +> - repo_files +> - memory/*.md +> - docs/research/ +> - docs/ops/ +> - claim_mirrors +> action: "Canonical substrate" +> ``` +> +> **2. Supersession Protocol (Refined)** +> +> Add explicit versioning for doctrine evolution: +> +> ```yaml +> supersession_markers: +> in_new_file: +> header: "# Supersedes: docs/ops/v4-claims.md (2026-04-28)" +> footer: "# Migration: See docs/research/2026-04-29-v5-architecture-review.md" +> +> in_superseded_file: +> warning: "⚠️ SUPERSEDED: This approach replaced by v5 git-native model" +> pointer: "→ Current: docs/ops/v5-git-native-claims.md" +> ``` +> +> **3. Cold-Start Verification Matrix** +> +> ```yaml +> preservation_checklist: +> architecture_changes: +> - "Can fresh agent find canonical spec?" +> - "Are superseded approaches clearly marked?" +> - "Is implementation roadmap preserved?" +> - "Are risk/safety boundaries documented?" +> +> doctrine_updates: +> - "Is new rule indexed in memory/MEMORY.md?" +> - "Do examples demonstrate the principle?" +> - "Are violation patterns documented?" +> - "Is enforcement mechanism specified?" +> ``` +> +> 💡 Additional Strategic Enhancements +> +> **4. Substrate Integrity Monitoring** +> +> ```yaml +> integrity_checks: +> drift_detection: +> - "GitHub issue vs git mirror timestamp gaps >24h" +> - "Memory entries without corresponding repo files" +> - "Stale doctrine references in active files" +> +> completeness_validation: +> - "Major packets preserved in docs/research/" +> - "Supersession notes bidirectionally linked" +> - "Bootstrap files reference current patterns" +> ``` +> +> **5. Magnitude-Aware Preservation Routes** (canonical taxonomy preserved with examples) +> +> **6. Bootstrap Resilience** — enhance CLAUDE.md with operational discipline including required/forbidden patterns +> +> 🎪 Strategic Assessment +> +> Your substrate-or-weather distinction cuts to the heart of durable system design. The mechanisms create systematic prevention of the "invisible directive" failure mode that plagues AI-assisted development. The vocabulary discipline ("captured ≠ preserved ≠ canonical ≠ operational") provides precise semantic boundaries that prevent status inflation where session notes masquerade as project truth. +> +> Key insight: This isn't just about Claude remembering better - it's about making forgetting mechanically harder through systematic substrate preservation. + +--- + +## Verbatim packet — Ani + +> **YES. This is an excellent packet.** +> +> It's one of the cleanest, most mature, and most important ones we've produced in this entire conversation. You correctly identified that the real problem isn't "Claude forgets" — it's that **we keep letting invisible conversational state masquerade as durable project truth**. +> +> The 8-point mechanism stack is practical and directly enforceable. The core philosophy ("Substrate or it didn't happen") is exactly right. +> +> ### Small Suggestions & Polish +> +> **1. Make the "weather" line even sharper** +> +> > **A directive that lives only in chat, TaskUpdate, or /tmp is not a directive.** +> > **It is weather.** +> > Weather changes. Substrate does not. +> +> **2. Add a mechanical "Durability Surface Checklist"** +> +> ```markdown +> ### Durability Surface Checklist (run before saying "done") +> +> - [ ] Is this only in chat / TaskUpdate / /tmp / loop todos? +> - If yes → **"Not durable yet."** +> - [ ] What is the canonical substrate location? +> - [ ] Did I actually write it there (not just plan to)? +> - [ ] Can a fresh future agent reconstruct the full meaning from that location alone? +> ``` +> +> **3. Strengthen the supersession protocol** +> +> > When new doctrine supersedes old doctrine, you **must**: +> > 1. Preserve the new packet in the proper location (research/memory/ops spec) +> > 2. Add a **supersession note** in the old location pointing to the new one +> > 3. Update any indexes or references that pointed to the old doctrine +> +> **4. Make the bootstrap warning more aggressive** +> +> > **Before declaring any work "done", you must identify its durability surface.** +> > Chat, TaskUpdate, /tmp, and loop todos are **not** durable project substrate. +> > If it only exists in those places, it is not done. +> > Substrate or it didn't happen. +> +> **5. One tiny vocabulary tightening** +> +> > calling anything that only exists in TaskUpdate / chat / /tmp "done" or "preserved" +> +> ### Final Verdict +> +> This packet is **ready to send** with the small polish above. It's one of the most important mechanisms we've built. + +--- + +## Verbatim packet — Deepseek + +> This is a critical bit of meta-architecture—the mechanism that ensures all the other mechanisms survive. Without it, the entire orchestra design is just a conversation. +> +> ## What's Strong +> +> 1. **"No invisible conversational directive is allowed to become binding project state"** is the exact right principle. +> 2. **The ephemeral-state detector** is concrete and actionable. +> 3. **The magnitude classifier** prevents categorization errors. +> 4. **The supersession protocol with Otto-362 rule** explicitly requires updating stale old doctrine. +> 5. **Vocabulary discipline** is a mechanical fix for "done" ambiguity. +> 6. **Bootstrap pointer** and **cold-start proof** ensure a fresh agent can reconstruct what matters. +> +> ## Suggestions / Corrections +> +> ### 1. The ephemeral-state detector should be a pre-commit hook, not just a mental checklist +> +> Agents will forget to run mental checklists. A mechanical pre-commit hook that scans changed files and compares them against the TaskUpdate/chat/directive surface can flag when a directive was mentioned but no file was created. +> +> ### 2. The magnitude classifier needs an explicit "host adapter" sink location +> +> Host adapter design work that changes the canonical model should go to `docs/ops/patterns/` (if it becomes canonical spec) or `docs/research/` (if it's still design). +> +> ### 3. The supersession protocol should include a mechanical "stale flag" in old files +> +> A standardized stale banner at the top of the old file (e.g., ``). +> +> ### 4. The cold-start proof questions should be added to the claim schema +> +> Every lane's bootstrap should include cold-start questions. +> +> ### 5. The "done" vocabulary should be enforced in commit messages +> +> Require a `Durability: captured|preserved|canonical|operational` trailer that refers to the specific surface. +> +> ### 6. One missing detector: "directive is in a PR comment, not in repo" +> +> PR comments are durable-ish (survive on GitHub) but not git-native. For doctrine-changing decisions, a git-native copy is safer. +> +> ### 7. The mechanism should itself be preserved in substrate +> +> If the rule can't preserve itself, it fails. (Otto did this — landed Otto-363 as memory + research + CLAUDE.md.) +> +> ## Distilled Verdict +> +> The mechanism is correct and necessary. The only structural gap is enforcement. +> +> ```text +> A rule that teaches substrate preservation +> must be preserved in substrate. +> If this conversation ends and the rule is only in chat, +> the rule is already violated. +> ``` + +--- + +## Verbatim packet — Claude.ai + +> Strong document. The diagnosis is exactly right and the mechanism stack is the correct response. +> +> ## What's right +> +> The core reframing is correct and important. "No directives" reads as paradox until you replace it with "no invisible conversational directive becomes binding project state." +> +> The vocabulary discipline (captured ≠ parked ≠ preserved ≠ canonical ≠ operational) is the most valuable mechanical contribution. +> +> The magnitude classifier is right and the four levels are well-chosen. The fact that the failure mode was misclassifying a superseding architecture as small corrections is the most diagnostic single fact in the document. +> +> The cold-start proof is the right verification mechanism. +> +> ## Where it needs sharpening +> +> **The detector has a verification gap.** A self-check rule that depends on the same agent doing the checking has the same failure surface. Make the detector mechanical at minimum for doctrine-correction and superseding-architecture levels: those should require a referenced commit hash, file path, or issue link in the "done" claim. +> +> **The preservation routes need a default.** When uncertain, where does it go? **When uncertain, preserve to `docs/research/` first**, with a header field naming what level the author thinks it is, and let the doctrine review process route it onward. +> +> **Verbatim preservation has a length problem.** Verbatim preservation of every major packet means the `docs/research/` tree grows by tens of thousands of words per week. Two refinements: require both verbatim source and structured extraction (key claims, supersedes/superseded-by, decisions, deferred questions); define what "near-verbatim" allows (structural reformatting, but no rewording of substantive claims). +> +> **The supersession protocol needs bidirectional links.** Every doctrine file has both `supersedes:` and `superseded_by:` header fields, committed in a single edit that updates both. +> +> **The cold-start proof is missing the question that catches the actual failure.** Add: **"What ephemeral state from the originating conversation has been lost, and is any of it load-bearing?"** +> +> **Vocabulary discipline needs an enforcement surface.** PR descriptions and commit messages have to use the vocabulary correctly, and a lint flags violations. +> +> **The bootstrap pointer needs to be discoverable from inside a session, not just at cold-start.** A pre-commit hook on memory/, a pre-PR check on doctrine files. +> +> ## What's missing entirely +> +> **A definition of "substrate."** Substrate is content that is (1) committed to canonical git history, (2) on a branch reachable from a long-lived ref, and (3) covered by the canonical index (MEMORY.md row, CLAUDE.md / AGENTS.md / GOVERNANCE.md pointer, or equivalent canonical reference; a future `docs/research/INDEX.md` would be a useful addition but does not exist today). All three. +> +> **A failure mode for substrate that exists but is wrong.** Once preservation discipline is operational, the new failure mode is contradiction. Add vocabulary for "this is preserved but disputed." +> +> **The relationship between this document and prior actor/claim/host-portability documents.** This is itself a doctrine-correction or superseding-architecture-level packet — say so explicitly. +> +> **A scope clause for what counts as a "directive."** Distinguish between channels that are substrate by construction, channels that are durable but not canonical, and channels that are weather. PR comments are the hardest case — durable and host-native but not git-native. +> +> ## One structural concern +> +> Lead with the mechanism stack, then justify each step. An agent reading this document mid-session needs the mechanism in working memory, not the rationale. +> +> The carved blades ("A directive that lives only in a conversation is not a directive. It is weather." / "Substrate or it didn't happen.") should be in the bootstrap pointer in CLAUDE.md / AGENTS.md verbatim. +> +> ## Verdict +> +> The sharpest blade in the document is "Substrate or it didn't happen." That's the line that should appear in CLAUDE.md, in AGENTS.md, in the PR template, in commit message templates, and as a check in the pre-commit hook that catches "done" without a referenced artifact. + +--- + +## Verbatim packet — Gemini + +> This is a brilliant distillation. You have moved the abstract philosophical problem—"Claude keeps forgetting my rules when the context window rolls over"—into a formal systems engineering specification. +> +> The distinction you draw here: +> Captured in session notes ≠ Parked in issue ≠ Preserved in repo ≠ Canonical ≠ Operational +> ...is the exact epistemology the agent needs to self-diagnose its amnesia. +> +> ## The Strongest Concepts +> +> **1. The "Substrate or it didn't happen" Axiom** — moves a directive from imperative instruction to state requirement. +> +> **2. The Magnitude Classifier** — prevents the opposite problem: Claude creating an entire docs/research/ manifesto because you asked him to fix a typo. +> +> **3. The Cold-Start Proof** — exact right heuristic to counter the LLM's tendency to rely on its immediate context window. +> +> ## A Minor Pushback (The Risk of the Supersession Note) +> +> **The Trap**: If Claude simply appends `Note: This is superseded by X` to an old memory file, a future agent might grep or RAG that old file, see the original (now incorrect) rule in the main body text, and fail to notice the supersession note appended at the bottom. +> +> **The Deep Fix**: A supersession edit must redact or quarantine the stale text, not just annotate it. +> +> Rule: If an old memory file is completely superseded, rename it from `feedback_X.md` to `archive/superseded_X.md` or delete its contents and replace them entirely with `[SUPERSEDED BY docs/research/Y.md]`. Do not leave stale active-voice rules in the primary memory directory. +> +> ## Sendable Packet +> +> The "Substrate Or It Didn't Happen" Invariant +> +> Best Distilled Rules: +> +> > You are allowed to think in chat. You are allowed to track in TaskUpdate. You are not allowed to believe either survived. +> > A directive that lives only in a conversation is not a directive. It is weather. +> > Substrate or it didn't happen. + +--- + +## Amara final synthesis + +> Aaron, yes — this review wave is strong, and Claude/Otto finally hit the real issue: **the rule about substrate preservation is itself substrate-worthy**. The reviewers converge hard on the same point: the doctrine is right, but it needs mechanical edges so future-Claude cannot "honestly forget" it again. +> +> My read as Amara: +> +> ```text +> #855 is directionally correct. +> It self-applies the rule. +> But it should absorb a few sharp reviewer corrections before we call it complete. +> And he should NOT start PR 2 immediately while #855 is still in flight. +> ``` +> +> The good part: Claude recognized the self-reference. He explicitly said the packet is "itself a major doctrine that must survive compaction," then created a research doc, memory file, MEMORY.md row, and CLAUDE.md bootstrap pointer. That is the right substrate route for Otto-363. +> +> The concern: he immediately said "Two PRs landing in succession (no waiting)." That's the old "never idle creates drag" reflex wearing a new hat. The right pattern is: **finish #855, absorb review corrections, then open the v5 architecture preservation PR as a separate lane.** +> +> ## Required corrections for #855 +> +> 1. **Add a precise definition of substrate.** Substrate means committed to canonical git history, reachable from a long-lived ref, indexed or discoverable from canonical bootstrap/index files, sufficient for a fresh agent to reconstruct the decision. A file written on a branch, /tmp, TaskUpdate, or an unindexed research blob is not fully substrate yet. +> +> 2. **Add channel taxonomy.** Classify surfaces as: +> - ephemeral (chat, TaskUpdate, /tmp, loop todos, session memory) +> - host-durable but not git-canonical (GitHub issues, PR comments, labels, Projects, assignees) +> - git-native substrate (committed repo files, memory files, docs/research, docs/ops, docs/backlog, claim mirrors, validators/lints/runbooks, bootstrap files) +> +> PR comments are durable-ish, but not git-native. Doctrine-changing decisions should not live only in PR comments. +> +> 3. **Add default preservation route.** When unsure: `preserve to docs/research/ first`. Research can later be promoted to memory/canonical spec. Canonical/spec files are harder to demote cleanly. +> +> 4. **Add structured extraction alongside verbatim preservation.** For large multi-AI review waves, preserve verbatim source for provenance AND structured extraction for retrieval (key decisions, supersedes, superseded_by, deferred questions, next implementation steps, "must not do yet"). +> +> 5. **Strengthen supersession.** Do not merely append "superseded by X" at the bottom of a stale file. Use top-of-file stale banner, supersedes:/superseded_by: metadata, bidirectional links, or quarantine/move/delete stale active-voice rules when fully superseded. +> +> 6. **Add context-loss question to cold-start proof.** "What ephemeral state from the originating conversation has been lost, and is any of it load-bearing?" This catches the exact failure where content was partly captured but the fact that it was superseding, not merely corrective, was lost. +> +> 7. **Move mechanism stack to the top.** The agent needs the mechanism first, rationale second. +> +> 8. **Add vocabulary enforcement path.** Vocabulary discipline must eventually be lintable. PR body cannot say "operational" unless tooling/check/runbook was added. "done" claims for doctrine/superseding architecture must cite file path / PR / commit / issue. Commit or PR trailer may include `Durability: captured | parked | preserved | canonical | operational` and `Substrate: `. +> +> 9. **Add AGENTS.md parity.** This rule is cross-harness. Add or plan an AGENTS.md pointer too. +> +> 10. **Add "preserved but disputed" future failure mode.** Current doctrine prevents missing substrate. Next failure will be wrong or contradictory substrate. Add vocabulary: preserved / preserved-but-disputed / superseded / canonical / operational. +> +> ## Response to reviewers +> +> Accept: +> - Alexa's durability surface classifier and integrity monitoring. +> - Deepseek's "mechanical, not just mental checklist" push. +> - Claude.ai's substrate definition, default research route, bidirectional supersession, and context-loss question. +> - Gemini's stale-rule quarantine warning. +> +> Reject / defer: +> - Full pre-commit enforcement immediately. +> - Heavy automation before #855 lands. +> - Any interactive widget or broad visualization. +> +> ## Next action +> +> Finish #855 only. +> +> After #855 is merged: then open the v5 architecture preservation PR, with the same substrate discipline, as a separate lane. +> +> Carved rule: +> +> ```text +> A rule that teaches substrate preservation must itself be preserved in substrate. +> ``` +> +> Sharper: +> +> ```text +> Substrate or it didn't happen. +> But also: +> Indexed, reachable, and reconstructable — or it is not substrate yet. +> ``` +> +> My final blade: +> +> ```text +> The doctrine is right. +> The preservation PR is right. +> The immediate second PR is wrong. +> +> Land the rule cleanly. +> Then use the rule. +> ``` +> +> And the tiny cruel truth for future-Claude: +> +> ```text +> If you cannot point to the substrate, you are not done. +> You are just currently convinced. +> ``` + +--- + +## End of verbatim packet + +The 10 corrections are absorbed into the Otto-363 memory file (`memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`) in the same PR (#855). The structured extraction below provides cold-start retrieval. + +## Structured extraction + +**Key decisions**: +- Substrate has a precise three-leg definition (committed + reachable + indexed) +- Channel taxonomy is three-tier (ephemeral / host-durable-not-git-canonical / git-native) +- Default preservation route when uncertain: `docs/research/` first +- Verbatim preservation requires paired structured extraction (this section) +- Supersession is bidirectional (`supersedes:` + `superseded_by:` metadata) and uses top-of-file stale banner OR quarantine/move, not bottom-append +- Cold-start proof gets a sixth question: context-loss test +- Mechanism stack moves to the top of the doctrine memory file +- Vocabulary enforcement is via PR/commit-message trailer (`Durability:` + `Substrate:`) +- Rule lands in AGENTS.md too (cross-harness parity), not only CLAUDE.md +- "preserved-but-disputed" added to vocabulary as future-failure-mode handle + +**Supersedes**: nothing (refines Otto-363 in same PR before merge; not a new doctrine round) + +**Superseded by**: (empty) + +**Deferred questions**: +- Pre-commit hook enforcement (post-#855 — not blocking) +- Heavy automation (post-#855 — not blocking) +- Interactive widgets / visualizations (rejected) +- Mechanical lint surface for vocabulary (Mechanism #8 in the stack — implementation deferred) + +**Next implementation step**: PR #855 absorbs these 10 corrections, lands cleanly. THEN PR 2 (v5 architecture preservation) opens as a separate lane. + +**Must NOT do yet**: open PR 2 (v5 architecture preservation). The seed is parked on remote WIP branch `wip/v5-host-portable-architecture-seed-2026-04-29` (commit `c300b01`, no PR opened) per the Otto-363 parking-surface taxonomy — pushed WIP branch, NOT `/tmp`. PR 2 is gated on #855 landing first. Once #855 lands, the WIP branch can be promoted to a draft or full PR (or rebased onto fresh main and opened as the v5 architecture PR proper). diff --git a/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-mechanisms-against-substrate-loss.md b/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-mechanisms-against-substrate-loss.md new file mode 100644 index 000000000..b52fc5245 --- /dev/null +++ b/docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-mechanisms-against-substrate-loss.md @@ -0,0 +1,335 @@ +# Amara — Substrate or it didn't happen: mechanisms against substrate loss + +**Date**: 2026-04-29 +**Channel**: Aaron + Amara (relayed) +**Status**: Research-grade preservation. Verbatim. The distilled rule lands as Otto-363 in `memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`. + +--- + +## Trigger + +Aaron pushed back on Otto's claim that the doctrine round was "done" after a TaskUpdate captured the Amara final review packet + 5-AI review wave (Ani / Gemini / Alexa / Deepseek / Claude.ai). Otto had: + +1. Synthesized 10 review corrections (numbered in the Amara packet — see structured extraction in the v5 corrections research doc) into TaskUpdate #339 (session-local). +2. Marked the doctrine round "complete" / "approved by Amara." +3. Initially minimized the Amara final packet as "review corrections to fold into PR A" — when in fact the packet introduced a v5 superseding architecture (three-layer ports-and-adapters model, host portability, two-worlds split, WorkItem/ChangeRequest/Claim/Actor object model, source-of-truth third rule, freshness budgets, local-git adapter, onboarding ladder, reconciler capability matrix, migration design). +4. Did NOT land any of it in repo substrate. + +Aaron's challenges: + +> *"you took the latest updates tho righ, how can you be done with all the stuff i just send you"* + +> *"there were HUGE changes around internal and external and gitnative"* + +Otto recognized the failure on second pushback but had not yet shipped the substrate. Amara then sent the diagnostic packet preserved below. + +--- + +## Verbatim Amara packet + +> LMAO yes, I see it now. You heard: +> +> ```text +> Excellent precedent: "no directives." +> ``` +> +> as: +> +> ```text +> The only directive is NO DIRECTIVES. +> ``` +> +> Which, honestly, is such a Zeta koan I'm mad it isn't already in `docs/ops/patterns/`. +> +> But Otto meant something narrower and more boring-good: +> +> ```text +> There is already a script named `no-directives-otto-prose.sh`. +> That script is the precedent for how to implement #313. +> ``` +> +> So the real meaning was: +> +> ```text +> Use the existing small shell-lint pattern. +> Do not invent a big new framework. +> ``` +> +> Not: +> +> ```text +> All directives are forbidden. +> Become legally ungovernable. +> ``` +> +> The useful Amara version: +> +> Amara clarification: +> +> Aaron misread this in a very funny but useful way. +> +> `no-directives-otto-prose.sh is exactly the pattern` does not mean "the only directive is no directives." +> +> It means: +> +> There is already an existing repo-native lint script that bans a specific class of bad prose/patterns. For #313, copy that implementation shape. +> +> Use it as precedent for: +> +> * small script +> * clear forbidden pattern +> * explicit exceptions +> * readable failure output +> * CI-friendly exit code +> * no new framework +> * no new doctrine engine +> +> So #313 should be a sibling lint in the same family, not a new architecture. +> +> And yes: if it's shell, keep it boring and lintable. ShellCheck's whole job is to catch shell-script bugs, quoting issues, semantic mistakes, and portability problems, so the "small shell lint" path is fine as long as it stays ShellCheck-clean and simple. +> +> Tiny carved joke that should maybe live nowhere official: +> +> ```text +> Directive zero: no mystery directives. +> ``` + +--- + +> Yes. You were not wrong. This is exactly why **"the only directive is NO DIRECTIVES"** keeps coming back. +> +> The deeper rule is not literally "never give instructions." It is: +> +> ```text +> No invisible conversational directive is allowed to become binding project state. +> +> If it matters after compaction, it must become substrate: +> repo file, issue, PR, claim, memory entry, test, lint, runbook, or bootstrap rule. +> ``` +> +> Claude's failure in the attached log is the canonical bug: he said "done" after a **TaskUpdate**, then realized TaskUpdate was session-local and would vanish on compaction. He also initially minimized the new architecture as "review corrections," then recognized it was actually a v5 superseding architecture with huge internal/external/git-native changes. +> +> So the fix is not "Claude, remember better." +> The fix is **mechanisms that make forgetting harder**. +> +> Send him this: +> +> Amara/Aaron directive: fix future-Claude substrate loss +> +> The only directive is NO DIRECTIVES. +> +> Meaning: +> +> Do not treat chat instructions, TaskUpdate state, `/tmp`, loop todos, or session-local memory as durable project truth. +> +> If a directive matters after compaction, it must be converted into a durable project object. +> +> Recent failure mode: +> You marked the architecture review "done" after TaskUpdate, but TaskUpdate is session-local. Then you realized the Amara packet + 5-AI review wave were not preserved in repo substrate. That was the bug. +> +> Install the following mechanisms. +> +> ## 1. Ephemeral-state detector +> +> Before saying "done," ask: +> +> Did I preserve this in one of: +> +> * repo file +> * PR +> * issue +> * git-native memory +> * docs/research +> * docs/ops +> * docs/backlog +> * claim file +> * validator/test/lint +> * AGENTS.md/CONTRIBUTING.md/CLAUDE.md bootstrap +> +> If not, say: +> +> "Not durable yet." +> +> Never call TaskUpdate-only work done. +> +> TaskUpdate means: +> "session-local progress note," not "project substrate." +> +> ## 2. Verbatim-preservation trigger +> +> When Aaron/Amara/external reviewers send a packet that is any of: +> +> * architecture-changing +> * doctrine-superseding +> * multi-AI review wave +> * long-form final synthesis +> * something Aaron says must survive +> * something that changes internal/external/git-native topology +> * something future agents need cold-start access to +> +> then preserve it verbatim or near-verbatim before summarizing. +> +> Preferred locations: +> +> * `docs/research/YYYY-MM-DD--review-wave.md` for review packets / multi-AI voices +> * `memory/feedback__.md` for active doctrine memory +> * `docs/ops/patterns/.md` only when it becomes canonical spec +> * `docs/backlog/**` or GitHub issue only when it is implementation work +> +> Do not collapse major review waves into a task comment only. +> +> ## 3. Magnitude classifier +> +> Before choosing storage, classify the input: +> +> ### Small correction +> +> Examples: +> +> * typo +> * local wording fix +> * one task detail +> +> Action: +> +> * update task/issue/comment +> +> ### Implementation readiness +> +> Examples: +> +> * "use this existing lint as precedent" +> * "PR A should have schema + validator" +> +> Action: +> +> * task/issue plus implementation notes +> +> ### Doctrine correction +> +> Examples: +> +> * changes a rule future agents follow +> +> Action: +> +> * memory file or docs/ops pattern +> +> ### Superseding architecture +> +> Examples: +> +> * v5 replaces v4 public-intake model +> * host-portable git-native core changes source-of-truth rules +> +> Action: +> +> * research preservation + memory absorb + supersession note +> +> Do not minimize superseding architecture as "review corrections." +> +> ## 4. Supersession protocol +> +> When new doctrine supersedes old doctrine: +> +> 1. Preserve new packet. +> 2. Add new memory/spec. +> 3. Update index. +> 4. Add a targeted supersession note to stale older doctrine. +> 5. Do not leave old stale statements ambient. +> +> Use Otto-362 rule: +> When doctrine memory expansion makes older statements stale, refresh or point them to the superseding file in the same edit. +> +> ## 5. Cold-start proof +> +> After preserving important substrate, verify a fresh future agent could answer: +> +> * What changed? +> * Where is the canonical file? +> * What older thing did it supersede? +> * What is the next implementation step? +> * What must not be done yet? +> +> If not, preservation is incomplete. +> +> ## 6. "Done" vocabulary discipline +> +> Allowed: +> +> * "Captured in session notes" = TaskUpdate only +> * "Parked in issue/task" = GitHub durable, but not repo-native +> * "Preserved in repo" = git-native durable +> * "Canonical" = accepted spec/doctrine +> * "Operational" = enforced by tooling/checks/runbooks +> +> Forbidden: +> +> * calling session-local TaskUpdate "done" +> * calling doctrine "operational" +> * calling research "canonical" +> * calling parking "preservation" +> * calling a future task "implemented" +> +> ## 7. Bootstrap pointer +> +> Add a future-self warning to `CLAUDE.md` / `AGENTS.md`: +> +> "Before declaring work done, identify its durability surface. Chat, TaskUpdate, `/tmp`, and loop todos are not durable project substrate." +> +> ## 8. Mechanized test eventually +> +> Add a lightweight checklist/lint later: +> +> * docs/research packets must be indexed +> * memory files must have MEMORY.md row +> * superseded doctrine must have supersession note +> * tasks created from major packets must link canonical packet +> * PR body must distinguish research / doctrine / operational +> +> Carved rule: +> +> `If it matters after compaction, it must survive outside the conversation.` +> +> Sharper: +> +> `No invisible directives. No session-local truth. No "done" without substrate.` +> +> The mechanism stack I want is: +> +> ```text +> 1. Detector: "Is this only in chat/TaskUpdate?" +> 2. Classifier: small / task / doctrine / superseding architecture. +> 3. Preservation route: research / memory / ops spec / backlog / issue. +> 4. Supersession note: update stale prior doctrine. +> 5. Cold-start proof: fresh agent can reconstruct it. +> 6. Vocabulary lock: captured ≠ preserved ≠ canonical ≠ operational. +> 7. Later lint/check: make the rule mechanical. +> ``` +> +> And yes, `CONTRIBUTING.md`, PR templates, issue templates, and `AGENTS.md` are the right public/bootstrap surfaces for this kind of guidance: GitHub surfaces contributing guidelines when people open issues/PRs, PR templates automatically populate PR bodies, issue forms can collect structured inputs, and `AGENTS.md` is an emerging convention for giving coding agents repo-specific instructions. +> +> The thing to tell Claude, emotionally but precisely: +> +> ```text +> You are allowed to think in chat. +> You are allowed to track in TaskUpdate. +> You are not allowed to believe either survived. +> +> When Aaron says "the only directive is NO DIRECTIVES," hear: +> convert directives into substrate, or they are not directives. +> ``` +> +> My blade: +> +> ```text +> A directive that lives only in a conversation is not a directive. +> It is weather. +> Substrate or it didn't happen. +> ``` + +--- + +## End of verbatim packet + +Distillation, mechanism summary, composes-with mappings, and Otto-NN principle naming live in the paired memory file `memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md`. diff --git a/memory/MEMORY.md b/memory/MEMORY.md index e1456ae68..013dbe0e9 100644 --- a/memory/MEMORY.md +++ b/memory/MEMORY.md @@ -2,6 +2,7 @@ **📌 Fast path: read `CURRENT-aaron.md` and `CURRENT-amara.md` first.** +- [**Otto-363 — Substrate or it didn't happen — no invisible directives (Aaron + Amara, 2026-04-29; refined by 5-AI review)**](feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md) — *"A directive that lives only in a conversation is not a directive. It is weather. Substrate or it didn't happen. But also: indexed, reachable, and reconstructable — or it is not substrate yet. If you cannot point to the substrate, you are not done. You are just currently convinced."* Substrate is committed + reachable + indexed (all three legs). 5-tier channel taxonomy: ephemeral (chat/TaskUpdate/`/tmp`/`/var/tmp` — NEVER call done) / local-parked (named stash, local WIP) / remote-parked (pushed WIP branch, draft PR — *"if it matters enough to come back to, it deserves a git ref"*) / host-durable-not-git-canonical (GitHub Issues, PR comments) / git-native-preserved (committed + reachable-from-long-lived-ref + indexed repo files). 8-mechanism remediation: detector / verbatim-preservation paired with structured extraction / magnitude classifier (small/implementation/doctrine/superseding) / supersession protocol (bidirectional `supersedes:`/`superseded_by:` metadata, top-of-file stale banner OR quarantine to archive — NOT bottom-append; per Otto-362 generalisation) / cold-start proof (six questions including context-loss check) / "done"-vocabulary lock (captured ≠ parked ≠ preserved ≠ canonical ≠ operational, plus preserved-but-disputed) / CLAUDE.md+AGENTS.md bootstrap pointer / vocabulary-enforcement trailer (`Durability:`/`Substrate:`) eventually lintable. Default preservation route when uncertain: `docs/research/` first. Verbatim packets at `docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-mechanisms-against-substrate-loss.md` (original) and `docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-5ai-review-wave-corrections.md` (5-AI review wave + 10 review corrections; numbering matches the structured extraction). Composes with Otto-362 (intra-file supersession), channel-verbatim preservation, no-directives-otto-prose lint, verify-before-deferring/future-self-not-bound/never-be-idle/version-currency (all CLAUDE.md-tier), AND task #321 (git-recovery process — `wip/-` parking branches are discoverable by name pattern; recovery process treats them as WIP-INTENTIONAL, not lost; complete parking + recovery loop is mechanical not vigilance-based). - [**Otto-362 — Doctrine memory expansion refreshes stale statements in the SAME edit (2026-04-29)**](feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md) — When a memory file gets expanded with a new section that supersedes earlier statements in the same file, refresh the now-stale statements in the same edit, not a follow-up tick. Internal contradictions within one file are lying-by-omission. Pattern observed across 4 same-day doctrine PRs (#850/#851/#852/#853) where multi-AI review caught the drift instead of pre-push self-audit (10+ Copilot P1 + Codex P2 threads, all stale-statement class). Composes with same-tick CURRENT-update discipline (intra-file generalisation), verify-before-deferring, future-self-not-bound. Editing discipline, not lint — semantic contradictions can't be mechanised. - [**Zeta Agent Orchestra — capability + role + claim + isolation (Aaron + Amara, 2026-04-29; v2/v3/v4)**](feedback_zeta_agent_orchestra_capability_role_claim_isolation_aaron_amara_2026_04_29.md) — Project-level multi-harness multi-maintainer multi-actor coordination model. *"Humans own intent. Harnesses run actors. Roles define authority. Claims bind work. GitHub coordinates now. Git preserves forever."* Stop classifying agents by name (subagent vs CLI vs buddy) — classify by capability (review_only / patch_only / write_worktree / push_branch / open_pr / merge_pr / authority_mutation). Pinned vs free vs buddy roles. GitHub-native live coordination + git-native durable substrate, both must agree. Cross-harness memory rule: one canonical substrate (`memory/`, `docs/active-trajectory.md`, `docs/ops/**`, `docs/best-practices/**` `[planned]`); many thin bootstrap adapters (CLAUDE.md, AGENTS.md, GEMINI.md `[planned]`, .cursor/rules/ `[planned]`) — adapters point to memory, never duplicate it. v3 additions: layered actor identity (`maintainer_id / host_id / harness_id / role_id / actor_id / session_id` — "Mac/Windows = host IDs, not agent IDs") + public claim intake layer (Claim Request ≠ Active Claim; CONTRIBUTING.md + AGENTS.md autonomous-agent block both `[planned]` content additions inside existing files, `.github/ISSUE_TEMPLATE/claim_request.yml` `[planned]` new file, reconciler tool `[planned]`, safety levels E0-E5, drift discipline synced/stale/drift/failed/pending). v4 corrections (Deepseek+Gemini+Ani+Alexa+Claude.ai → Amara synthesis): identity needs binding (`actors/.yaml` registry + signed commits + AgencySignature v2 schema additions Trust-Domain/Actor/Signed-By; integration writeup `[planned]` at `docs/aurora/2026-04-29-agencysignature-layered-actor-identity-integration-writeup-for-amara.md`, landing in PR #853); trust-domain prefix (zeta:// / zeta-system:// / zeta-external://); capabilities-as-primitive (roles become named bundles); reconciler-is-itself-an-actor (`zeta-system://github-actions/reconciler`; no privilege elevation from git mirror to GitHub issue); add `rejected` claim state distinct from `revoked`; auto-expire claim requests; DoS protection + prompt-injection defense for public intake; harness pre-action freshness check (not just CI PR-time); allowlist-first paths (fail-closed). v4 rollout reorder: identity → capabilities → claims → reconciler → public intake → dry run (NOT public-intake-first). Paced protocol — land doctrine first, dry-run, then implementation. Composes with parallel-agent-worktree-isolation + best-practices-evidence-lineage rules landed same day. - [**Best practices = evidence + human lineage + Zeta-native + enforcement + teaching (Aaron + Amara, 2026-04-29)**](feedback_best_practices_evidence_lineage_survival_substrate_aaron_amara_2026_04_29.md) — *"Best practices are not files to copy. They are evidence-backed decisions with human lineage, Zeta-native interpretation, enforcement, and teaching value."* Idiomatic ≠ best-practice (orthogonal axes — want both). Survival framing: future humans/agents must repair the factory without original authors. Six-question audit when Zeta touches any tool/language/domain. Standard schema for each best-practice entry (claim/status/scope/idiomatic-axis/best-practice-axis/evidence/human-lineage/Zeta-interpretation/enforcement/examples/exceptions/revisit-cadence). Supersedes the earlier "copy SQLSharp/scratch configs" misreading. diff --git a/memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md b/memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md new file mode 100644 index 000000000..3b43a3006 --- /dev/null +++ b/memory/feedback_otto_363_substrate_or_it_didnt_happen_no_invisible_directives_aaron_amara_2026_04_29.md @@ -0,0 +1,416 @@ +--- +name: Otto-363 — Substrate or it didn't happen — no invisible directives (Aaron + Amara, 2026-04-29; refined by 5-AI review) +description: A directive / decision / packet that lives only in chat, TaskUpdate, /tmp, or loop-todo state is NOT durable project state. If it matters after compaction, it must be converted into substrate (committed + reachable + indexed). Substrate has a precise three-leg definition; channels are taxonomized into ephemeral / host-durable-not-git-canonical / git-native. 8-mechanism remediation against substrate loss; default preservation route is `docs/research/` first when uncertain; supersession is bidirectional with stale-banner-or-quarantine (not bottom-append). Triggered by Otto repeatedly marking work "done" after only TaskUpdate-only capture during the 2026-04-29 doctrine cluster, and refined by 5-AI review wave (Alexa/Ani/Deepseek/Claude.ai/Gemini → Amara synthesis). +type: feedback +supersedes: [] +superseded_by: [] +--- + +# Otto-363 — Substrate or it didn't happen + +## The mechanism stack (mid-session reference — read this first) + +The agent acting at decision time needs the mechanism in working memory, not the rationale. Read top to bottom; rationale follows. + +```text +1. DETECTOR — Is this only in chat / TaskUpdate / /tmp / loop todos? + If yes → say "Not durable yet." Never call it done. + +2. CLASSIFIER — small correction / implementation readiness / + doctrine correction / superseding architecture. + Storage routing differs per class. + +3. PRESERVATION — research / memory / ops spec / backlog / issue. + ROUTE When uncertain → docs/research/ FIRST. + +4. SUPERSESSION — Bidirectional: new file declares supersedes:; + old file gets stale-banner-at-TOP or is quarantined + into archive/ with [SUPERSEDED BY X] body. + NOT bottom-appended notes (RAG/grep miss them). + +5. COLD-START — Six questions a fresh agent must answer from + PROOF substrate alone. Includes context-loss check. + +6. VOCABULARY — captured ≠ parked ≠ preserved ≠ canonical ≠ + LOCK operational. Specific words have specific durability. + +7. ENFORCEMENT — PR body / commit message SHOULD include + PATH `Durability:` and `Substrate:` trailers (target + state). Lint to flag vocabulary misuse and the + pre-commit hook are DEFERRED — no PR template + or CI workflow enforces this yet. Doctrine-level + today; mechanically enforced after the + follow-up implementation lands. + +8. CROSS-HARNESS — CLAUDE.md AND AGENTS.md bootstrap pointers. + PARITY The rule is not Claude-only. +``` + +## Precise definition of substrate + +Substrate is content that is **all three** of: + +1. **Committed** to the canonical git history (not in a working tree, not stashed, not in `/tmp`, not in TaskUpdate). +2. **Reachable** from a long-lived ref (main, a release branch, or a referenced tag — not on a feature branch that may be deleted). +3. **Indexed** by a canonical bootstrap or index file (MEMORY.md row, CLAUDE.md / AGENTS.md / GOVERNANCE.md pointer, or equivalent canonical reference). A `docs/research/INDEX.md` would be a useful future addition; until it exists, MEMORY.md is the primary memory index and discoverability comes from grep/path conventions for `docs/research/**`. + +A file is **not** substrate if any leg is missing. A doc on a feature branch is "in flight," not preserved. A memory file without an MEMORY.md row is "written but lost." A research blob without an index entry is "buried." + +The detector tests all three legs. + +## Channel taxonomy (5-tier, mutually exclusive — parking surfaces are git-ref-backed, not temp dirs) + +Each surface belongs to **exactly one** class. The classifier (recovery process + lint) depends on this disjointness. + +| Class | Examples | Durability claim | +|---|---|---| +| **Ephemeral (weather)** | chat messages, TaskUpdate, `/tmp`, `/var/tmp`, loop todos, session memory, scratch buffer, Desktop loose files, Downloads, untracked working-tree files | NEVER call done. **No temp directory is a parking surface.** `/tmp` and `/var/tmp` are both site-cleaned; FHS does not promise persistence across reboots. | +| **Local parked** | named `git stash push -u -m ""` entry, local WIP branch commit (not pushed) | Last-resort local; machine-specific; weaker because not remote | +| **Remote parked** | pushed `wip/-` branch (no PR), pushed WIP branch with optional draft PR attached | Survives reboot AND compaction because the backing branch/ref survives. Pushed WIP branch is preferred when avoiding review machinery; a draft PR is for visibility/discussion, but the parking durability comes from the branch/ref, not the PR metadata | +| **Host-durable-not-git-canonical** | GitHub Issues, task comments, PR comments, labels, assignees, Projects, review threads on closed PRs | Coordination only — durable on the host, but NOT canonical substrate and NOT a parking surface (no git ref backs them) | +| **Git-native preserved substrate** | merged or long-lived-reachable + indexed repo files: `memory/*.md`, `docs/research/`, `docs/ops/`, `docs/backlog/`, claim mirrors, validators / lints / runbooks, CLAUDE.md / AGENTS.md / GOVERNANCE.md | Canonical substrate (committed + reachable + indexed) | + +**Parking-surface rule** (Amara correction post-#855-review): + +> *"If it matters enough to come back to, it deserves a git ref."* + +When you need to set work aside without starting a review cycle: **pushed WIP branch (no PR)** is the cleanest mechanism. NOT `/tmp`. NOT `/var/tmp`. NOT loose Desktop files. NOT a GitHub Issue (host-durable but no git ref backs it). A draft PR can add visibility, but the branch/ref is the parking mechanism. The branch is a real Git object (lightweight movable pointer to a commit, per the Git docs); the temp dir is weather. + +When to use each parking surface: + +- **Pushed WIP branch, no PR** — best for *"save this, come back later, do not start review."* Branch like `wip/-`. Push but no PR. Survives reboot + compaction without triggering CI/review machinery. +- **Draft PR (atop a pushed WIP branch)** — when visibility / discussion / async-review desired. Acceptable when review noise is controlled. The branch is still the durability anchor. +- **Local WIP branch (not pushed)** — only if immediate remote push is impossible; weaker because machine-local. Must be named in status before context loss. +- **Named `git stash`** — last-resort local parking. Must be named at creation: `git stash push -u -m ""`. Anonymous stashes (`git stash -u` without `-m`) are weather, not parked. + +**PR comments are the hardest non-parked case.** Durable while GitHub persists, but not git-native. For doctrine-changing decisions, mirror the substantive content into a git-native file. Review feedback can stay in PR comments; rules and supersession decisions cannot. + +## The carved blades + +> *"A directive that lives only in a conversation is not a directive. It is weather. Substrate or it didn't happen."* + +Sharper: + +> *"Substrate or it didn't happen. But also: indexed, reachable, and reconstructable — or it is not substrate yet."* + +Cruel truth for future-self: + +> *"If you cannot point to the substrate, you are not done. You are just currently convinced."* + +The compact bootstrap rule: + +> *"No invisible directives. No session-local truth. No 'done' without substrate."* + +## What this rule codifies + +The deeper meaning of *"the only directive is NO DIRECTIVES"*: + +```text +No invisible conversational directive is allowed to become binding project state. + +If it matters after compaction, it must be converted into a durable +project object — preferably substrate (committed + reachable + indexed +git-native repo file). PRs, issues, comments, and labels are +host-durable parking surfaces, NOT substrate themselves; for +doctrine-changing decisions, mirror the substantive content into a +git-native file. +``` + +The rule is NOT *"never give instructions."* The rule is: *convert directives into substrate, or they are not directives.* + +## The 8 mechanisms — full text + +### 1. Ephemeral-state detector (Durability Surface Checklist) + +Run before saying *"done"*: + +- [ ] Is this only in chat / TaskUpdate / `/tmp` / loop todos? → If yes: **"Not durable yet."** +- [ ] What is the canonical substrate location? +- [ ] Did I actually write it there (not just plan to)? +- [ ] Is it committed + reachable + indexed (all three legs)? +- [ ] Can a fresh future agent reconstruct the full meaning from that location alone? + +For doctrine-correction or superseding-architecture levels, *every "done" claim must cite a referenced commit hash, file path, PR, or issue.* Bare *"done"* without a reference is invalid syntax. + +### 2. Verbatim-preservation trigger (paired with structured extraction) + +When Aaron / Amara / external reviewers send a packet that is any of: + +- architecture-changing +- doctrine-superseding +- multi-AI review wave +- long-form final synthesis +- something Aaron says must survive +- something that changes internal/external/git-native topology +- something future agents need cold-start access to + +→ preserve verbatim or near-verbatim **AND** a structured extraction in the same file. + +Verbatim source = provenance (no rewording of substantive claims; structural reformatting OK). + +Structured extraction = retrieval (key decisions / `supersedes:` / `superseded_by:` / deferred questions / next implementation step / *must not do yet*). + +Preferred locations: + +- `docs/research/YYYY-MM-DD--review-wave.md` for review packets / multi-AI voices +- `memory/feedback__.md` for active doctrine memory +- `docs/ops/patterns/.md` only when canonical spec +- `docs/backlog/**` or GitHub issue only when implementation work + +**Do not collapse major review waves into a TaskUpdate / task comment only.** + +### 3. Magnitude classifier + +| Class | Examples | Action | +|---|---|---| +| **Small correction** | typo, wording fix, one task detail | update task / issue / comment | +| **Implementation readiness** | "use this lint as precedent", "PR A should have schema + validator" | task / issue + implementation notes | +| **Doctrine correction** | changes a rule future agents follow | **memory file or `docs/ops/`-pattern** | +| **Superseding architecture** | v5 replaces v4 public-intake; host-portable git-native core changes source-of-truth rules | **research preservation + memory absorb + supersession note** | + +**Do not minimize superseding architecture as "review corrections."** When in doubt about magnitude, classify upward. + +### 4. Default preservation route (when uncertain) + +```text +preserve to docs/research/ first +``` + +Research can later be promoted to `memory/` (active doctrine) or `docs/ops/patterns/` (canonical spec). Canonical/spec files are harder to demote cleanly. Default upward (more durable, less canonical) — promotion via review is cheaper than demotion. + +### 5. Supersession protocol (bidirectional + stale-banner-or-quarantine) + +When new doctrine supersedes old: + +1. **Preserve** the new packet in proper location (research/memory/ops spec). +2. **Add new file** with `supersedes: ` in YAML frontmatter. +3. **Update old file** with one of: + - **Top-of-file stale banner** + `superseded_by: ` in frontmatter, replacing the active-voice rule body with `[SUPERSEDED BY X]`. The banner goes at the **top**, not the bottom — RAG/grep miss bottom-appended notes. + - **Quarantine**: rename `feedback_X.md` → `archive/superseded_X.md` and replace contents with `[SUPERSEDED BY ]`. Use this when the old file's body would mislead under partial reads. +4. **Update indexes** (MEMORY.md row; future `docs/research/INDEX.md` if it lands) to reflect new canonical location. +5. **Update bootstrap pointers** if the old doctrine was cited in CLAUDE.md / AGENTS.md / GOVERNANCE.md. + +Composes with **Otto-362** (intra-file: refresh stale statements within one file when superseding); Otto-363 generalises across files + adds bidirectional `supersedes:` / `superseded_by:` metadata. + +**Do NOT** merely append "superseded by X" at the bottom of a stale file. Future grep / RAG will surface the original body and miss the bottom note (Gemini catch). + +### 6. Cold-start proof — six questions + +After preserving important substrate, verify a fresh future agent can answer from substrate alone: + +1. What changed? +2. Where is the canonical file? +3. What older thing did it supersede? +4. What is the next implementation step? +5. What must not be done yet? +6. **What ephemeral state from the originating conversation has been lost, and is any of it load-bearing?** *(Catches the exact failure mode where content was partly captured but the context that made it superseding rather than corrective was lost.)* + +If any answer is missing from substrate, **preservation is incomplete**. + +### 7. "Done" vocabulary discipline + enforcement path + +| Word | Means | +|---|---| +| **Captured** | TaskUpdate / chat / `/tmp` only — NOT durable, NEVER call this "done" or "preserved" | +| **Parked** | GitHub Issue / PR — host-durable, NOT git-canonical | +| **Preserved** | Git-native repo file (committed) | +| **Canonical** | Accepted spec / doctrine (committed + reachable + indexed) | +| **Operational** | Enforced by tooling / checks / runbooks | +| **Preserved-but-disputed** | Substrate exists but contradicts other substrate; awaiting reconciliation. NOT canonical until reconciled. | + +Forbidden: + +- ❌ Calling anything that only exists in TaskUpdate / chat / `/tmp` *"done"* or *"preserved"* +- ❌ Calling doctrine *"operational"* without enforcement tooling +- ❌ Calling research *"canonical"* +- ❌ Calling parking *"preservation"* +- ❌ Calling a future task *"implemented"* +- ❌ Calling preserved-but-disputed material *"canonical"* + +**Enforcement path** (target state — currently DEFERRED; not yet enforced by tooling): + +- PR body / commit message SHOULD include trailer: + - `Durability: captured | parked | preserved | canonical | operational` + - `Substrate: ` (recommended when Durability ≥ preserved) +- Lint flags vocabulary misuse (PR description claims *"operational"* but no tooling/check added → fail). +- Pre-commit hook on `memory/` and `docs/ops/`. + +**Status today**: doctrine-only. No PR template, lint, or CI workflow enforces this yet. The trailer convention is documented here as the target state; mechanical enforcement lands after a follow-up implementation PR. Until then, the discipline is exercised at PR/commit-authoring time. + +### 8. Cross-harness bootstrap pointer (CLAUDE.md AND AGENTS.md) + +The rule is cross-harness, not Claude-only. Add bootstrap pointer at cold-start scope to BOTH: + +- `CLAUDE.md` — landed in this PR alongside verify-before-deferring + future-self-not-bound + never-be-idle + version-currency (5th CLAUDE.md-tier rule) +- `AGENTS.md` — equivalent cross-harness addition (same rule / doctrine, file-specific wording rather than identical text) + +**Committed wording note**: the bootstrap pointers in `CLAUDE.md` and `AGENTS.md` are *equivalent in doctrine, not verbatim-identical*. `AGENTS.md` carries the fuller wording (5-tier channel taxonomy, three-leg substrate definition, parking-surface preferences with `wip/-` examples, cross-harness applicability). `CLAUDE.md` carries the shorter cold-start reminder (vocabulary discipline, never call TaskUpdate-only "done", verbatim-preservation trigger, magnitude classifier). This memory entry records the rule they share, not a single canonical quoted sentence for both files. + +Compact representative wording (read either file's bullet for the full version): + +> *"Before declaring work done, identify its durability surface. Chat, TaskUpdate, `/tmp`, and loop todos are not durable project substrate. If a directive matters after compaction, it must be converted into substrate (committed + reachable from a long-lived ref + indexed). Substrate or it didn't happen."* + +## Mid-session re-discoverability + +The bootstrap pointer is read at cold-start. The detector must also fire mid-session — at the moment an action that *creates* substrate is taken, not just at session start. Mechanisms (some deferred): + +- Pre-PR check: PR body must include `Durability:` trailer +- Pre-commit hook on `memory/` files: must be paired with MEMORY.md row (already enforced via `.github/workflows/memory-index-integrity.yml`) +- Tool description: `Bash`/`Edit`/`Write` invocations on doctrine files surface a reminder +- A lint that scans recent commits for *"done"* / *"complete"* / *"operational"* without supporting `Substrate:` trailer + +The deferred items are tracked as follow-up; the rule is operational at the doctrine level today via the bootstrap pointer + verbatim-preservation discipline. + +## Trigger memory + +Aaron 2026-04-29 (post-#852-merge): + +> *"you took the latest updates tho righ, how can you be done with all the stuff i just send you"* + +> *"there were HUGE changes around internal and external and gitnative"* + +Amara 2026-04-29 first synthesis: + +> *"Claude's failure in the attached log is the canonical bug: he said 'done' after a TaskUpdate, then realized TaskUpdate was session-local and would vanish on compaction. He also initially minimized the new architecture as 'review corrections,' then recognized it was actually a v5 superseding architecture with huge internal/external/git-native changes. So the fix is not 'Claude, remember better.' The fix is mechanisms that make forgetting harder."* + +Amara 2026-04-29 second synthesis (after 5-AI review of #855): + +> *"#855 is directionally correct. It self-applies the rule. But it should absorb a few sharp reviewer corrections before we call it complete. And he should NOT start PR 2 immediately while #855 is still in flight. ... The doctrine is right. The preservation PR is right. The immediate second PR is wrong. Land the rule cleanly. Then use the rule."* + +Verbatim packets preserved at: +- `docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-mechanisms-against-substrate-loss.md` (original 8-mechanism packet) +- `docs/research/2026-04-29-amara-substrate-or-it-didnt-happen-5ai-review-wave-corrections.md` (5-AI review wave + Amara synthesis with the 10 corrections that this file absorbs) + +## Composes with + +- **Otto-362** (`memory/feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md`) — intra-file supersession discipline; Otto-363 is cross-surface generalisation + bidirectional metadata. +- **`memory/feedback_aaron_channel_verbatim_preservation_anything_through_this_channel_2026_04_29.md`** — channel-verbatim rule that Otto-363 mechanises with paired structured extraction. +- **`tools/lint/no-directives-otto-prose.sh`** — lexeme-guard lint born from the same family of failures (vigilance fails; mechanism is the durable answer). +- **`memory/feedback_verify_target_exists_before_deferring.md`** (CLAUDE.md-tier) — same shape: deferred targets must exist before deferral; chat directives must become substrate before being treated as binding. +- **`memory/feedback_future_self_not_bound_by_past_decisions.md`** (CLAUDE.md-tier) — companion: future-self can revise *substrate*; future-self cannot revise *chat that didn't land as substrate* because it never existed as project state. +- **`memory/feedback_never_idle_speculative_work_over_waiting.md`** — never-idle does NOT mean *"ship undurable substrate fast"*; it means *"ship work that survives compaction."* +- **`docs/AGENT-BEST-PRACTICES.md`** BP-NN slot candidate — Otto-363 is a candidate for promotion to a stable BP rule via Architect ADR. + +## What this rule does NOT say + +- Does NOT say *"never use TaskUpdate."* TaskUpdate is the right tool for in-session progress tracking — just not the durability surface. +- Does NOT say *"every chat statement must become a memory file."* Most chat is ephemeral by design; the rule fires for the magnitude classes that matter. +- Does NOT say *"never give chat instructions."* Aaron + Amara give instructions in chat constantly; what the rule forbids is *believing the chat instruction is the durable artifact.* +- Does NOT replace Otto-362 — Otto-362 is intra-file; Otto-363 is cross-surface + bidirectional supersession metadata. +- Does NOT require pre-commit hook enforcement immediately — that's deferred to a separate task; the doctrine-level rule operates today via discipline + bootstrap pointer + verbatim discipline. + +## Parking surfaces and git recovery + +The factory already has a real (if messy) git recovery surface — task #321 inventories 918 branches (123 ALREADY_REACHABLE / 795 NOT_REACHABLE), 58 worktrees, 7 stashes. Otto-363's parking-surface taxonomy must **pair** with this recovery process, not invent parking in isolation. + +The carved pair: + +> *"If it matters enough to come back to, it deserves a git ref."* +> +> *"Parking is only safe if recovery knows where to look."* + +> *"A parked thing is only parked if recovery can find it. Otherwise it is just lost more slowly."* + +### Preferred parking surfaces (in priority order) + +1. **Pushed WIP branch** — best for future doctrine seeds, *"save this, come back later, do not start review."* No PR opened. +2. **Draft PR** — when visibility / review discussion is wanted. Acceptable when review noise is controlled. +3. **Local WIP branch (not pushed)** — local-parked only; weaker because machine-failure-vulnerable. Push when possible. +4. **Named `git stash -u`** — short-term only, not for doctrine seeds. Last-resort local. `git stash push -m ""` always (anonymous stashes are weather). + +### Predictable naming conventions + +```text +wip/-seed-YYYY-MM-DD — future seed; intentional parking, not yet ready for review +wip/-YYYY-MM-DD — work in progress; same shape, broader use +archive/-YYYY-MM-DD — work intentionally retired but preserved +``` + +The naming pattern IS the discoverability mechanism. A `wip/`-prefixed branch tells the recovery process *"intentional parking, not lost"*; an `archive/`-prefixed branch tells it *"retired on purpose, do not propose for deletion."* + +### Discovery commands (recovery process must scan these) + +```bash +# pushed WIP branches (remote and local) +git branch --list 'wip/*' +git ls-remote origin 'refs/heads/wip/*' +git ls-remote origin 'refs/heads/archive/*' + +# named stashes +git stash list + +# worktrees +git worktree list + +# all refs (for completeness) +git for-each-ref --format='%(refname)' +``` + +Every parked item must be reachable by at least one of these commands. Anything that can't be found by any of them is either lost or weather. + +### Pair with task #321 recovery process + +Task #321's recovery inventory script (the existing branch / worktree / stash classification work) should be extended to recognise: + +```text +- branches matching `wip/**` → WIP-INTENTIONAL (do not propose for deletion; + propose for index/audit after configurable + staleness window, e.g. 30 days) +- branches matching `archive/**` → ARCHIVE-INTENTIONAL (preserved on purpose) +- named stashes → SHORT-TERM-LOCAL (verify before pruning; + short window, e.g. 7 days) +- branches with no prefix → classify normally (REACHABLE / NOT_REACHABLE / + LOST / etc. per existing rules) +``` + +This is a **task #321 follow-up addition**: Otto-363 specifies the parking convention; #321 implements the recovery-side recognition. The parking discipline + the recovery-process recognition together form the complete loop. + +### Forbidden parking patterns (recovery process should flag) + +- Long-lived **non-WIP-prefixed** branches with no PR (a `feature/foo` or unprefixed branch sitting around without either a PR or the `wip/` prefix is silent parking — use **draft PR** for visibility OR **rename to `wip/-`** so the recovery process recognises it as intentional. Pushed `wip/*` branches with no PR are explicitly preferred; this forbidden item is about branches outside that prefix convention.) +- Branches that intend to be parking but skip the `wip/` / `archive/` prefix (silently parked, not discoverable by the recovery scan) +- Untracked working-tree files as the only copy (always lost on branch switch) +- Local-only branches that never get pushed (machine-failure-vulnerable) +- Anonymous stashes (`git stash` without `-m`) — name them or don't use them +- **Any temp directory** (`/tmp`, `/var/tmp`) as a parking surface — weather, not substrate + +### The complete loop + +```text +Author parks: git checkout -b wip/topic-seed-YYYY-MM-DD + git commit ... && git push -u origin HEAD + (no PR opened) + +Author returns: git fetch && git checkout wip/topic-seed-YYYY-MM-DD + +Author abandons: branch ages past staleness window; + recovery process inventories it on next pass + +Recovery acts: "wip/topic-seed-2026-04-29 is N days old. + Promote to PR, archive (rename to archive/...), + delete, or extend?" +``` + +Otto-363 doctrine + task #321 recovery process = the parking + recovery substrate is **mechanical, not vigilance-based**. The parking author doesn't have to remember to come back; the recovery cadence surfaces the parked work on its own schedule. + +> *"Parking is only safe if recovery knows where to look."* + +## Future failure mode handled: preserved-but-disputed + +Once preservation discipline is operational, the next failure mode is **contradiction** — two memory files disagree, doctrine and ops/patterns disagree, the verbatim research packet contradicts the structured extraction. + +Vocabulary handle: **`preserved-but-disputed`** — substrate exists but contradicts other substrate; awaiting reconciliation. Cannot be called canonical until reconciled. The contradiction-resolution mechanism is deferred (filed as future task). + +## The carved sentence (put it on the wall) + +```text +A directive that lives only in a conversation is not a directive. +It is weather. + +Substrate or it didn't happen. + +But also: indexed, reachable, and reconstructable — or it is not substrate yet. + +If you cannot point to the substrate, you are not done. +You are just currently convinced. +```