Conversation
…tatements in the SAME edit (2026-04-29) New principle observed and named after 4 same-day doctrine PRs (#850 → #851 → #852 → #853) drove the agent-orchestra doctrine memory from ~100 lines to ~1080 lines through v1 → v2 → v3 → v4 expansions. Pattern observed: - 10+ Copilot P1 + Codex P2 review threads across the four PRs - All caught internal contradictions WITHIN the same file: * "Tracked under follow-up tasks" vs "Untracked follow-up" * "Currently undefined" vs "Now specified" * "task #325-#334" vs "task #325 + #335" + "tasks #335-#338" * "v2 review-driven additions" header vs "v3 packet" content * `request-agent-claim.md` vs `start-agent-claim.md` runbook path * Mapping `Task → claim_id` vs example showing both `Task:` AND `Claim:` - All caught by external AI review; none caught by pre-push self-audit - Fix cadence was fast but the *count* of internal-contradiction threads was disproportionate to the substantive-error count The rule (Otto-362): 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. Composes with: - Same-tick CURRENT-update discipline (CLAUDE.md auto-memory section) — Otto-362 is the intra-file generalisation; CURRENT rule is the cross-file case - verify-before-deferring (CLAUDE.md) — same shape, applied to internal references rather than deferred work - future-self-not-bound (CLAUDE.md) — Otto-362 is the editing counterpart; when superseding past-self's statement, refresh it rather than leave it ambient Why not a CI lint instead: - Internal contradictions are semantic, not syntactic - Existing lints catch path-existence, duplicate-targets, snake_case consistency — but cannot catch "Currently undefined" + "Now specified" co-existing - Editing discipline is the only mechanism for semantic contradictions - Multi-AI review remains the safety net; Otto-362 reduces the count of iterations by catching the stale-statement class before push What this rule does NOT say: - Does NOT say "never expand a memory file across multiple PRs" - Does NOT say "every expansion must rewrite the whole file" - Does NOT say "review iterations are bad" - Does NOT replace multi-AI review safety net — additive, not replacement Files: - memory/feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md - memory/MEMORY.md (paired index entry) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24488c7c81
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…mara markdownlint-cli2 flagged 6 MD032 errors (lists need surrounding blank lines) on the writeup. Inserted blank line after each list-introducing sentence at lines 41, 49, 120 (Under v4 with binding), 146 (we'd:), 151 (By layering), and 176 (Options:). No content changes. Per Otto-362 (just landed in PR #854) — would have caught this pre-push if I'd run markdownlint locally before opening the PR. Filing this commit as the kind of pure-mechanical-CI-fix that Otto-362 cannot prevent (it's a syntactic class, not semantic) — those still need lint coverage at submit-time. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new doctrine memory entry (Otto-362) capturing an editing discipline: when expanding a memory file with new sections that supersede earlier statements, refresh the now-stale statements in the same edit to avoid intra-file contradictions.
Changes:
- Added a new memory file documenting the “same-edit refresh” rule for doctrine/memory expansions.
- Added a corresponding newest-first index entry in
memory/MEMORY.md.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
memory/feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md |
New Otto-362 doctrine memory file describing the same-edit refresh discipline and its rationale/compositions. |
memory/MEMORY.md |
Adds the Otto-362 entry to the memory index (newest-first). |
…t docs/CLAUDE.md Codex P2 + Copilot P1 both caught the same dead path. The auto-memory section + CURRENT-file rule live in CLAUDE.md at the repository root (see CLAUDE.md ~lines 80-110). Updated the Composes-with bullet to point at the correct path so readers can verify the cited rule. Ironic timing: the Otto-362 rule itself is about catching internal contradictions before push — and the rule's own first version had a dead xref. Caught by external review on the meta-rule PR. The fix is exactly the kind of pre-push self-audit Otto-362 advocates for. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…iteup for Amara (2026-04-29) (#853) * docs(aurora): AgencySignature × Layered Actor Identity integration writeup for Amara (2026-04-29) Research-grade integration analysis: how the v4 layered actor-identity model (maintainer_id / host_id / harness_id / role_id / actor_id) composes with the AgencySignature v1 commit-trailer attribution work (ferry-7 spec, tasks #298 + #299 enforcement instruments). Aaron asked for a writeup he can send to Amara. Key claim: the v4 binding requirement that Claude.ai + Deepseek + Gemini + Ani + Alexa flagged on the v3 public-intake design is not a parallel system to AgencySignature — it is the v2 schema for AgencySignature, with three field additions: Trust-Domain: zeta Actor: zeta://aaron-mac/claude-code/coordinator Signed-By: ed25519:abc... v1 readers ignore unknown fields; v2 readers verify the trailer signature against an actors/<actor_id>.yaml registry. Migration is additive — no parallel system, no double-attribution. Three concrete asks for Amara: 1. Confirm the layering shape (additive trailer fields vs trailer-as-pointer) 2. Pick the binding primitive (Ed25519 + registry vs GitHub-native commit verification as MVP fallback vs sigstore/OIDC) 3. Define the v1 → v2 migration window (tight vs loose coupling) If the layering shape lands, the v4 rollout reorders to: 1. Identity model + AgencySignature v2 schema (single composed PR per layer) 2. Capability model 3. Internal claim protocol 4. Reconciler security model 5. Public claim intake 6. External / Windows / roaming-agent dry run Carved blade (proposed, awaiting Amara concurrence): Identity is structured. Identity is bound. AgencySignature is the binding wire format. Trailer fields carry actor + capabilities + claim. Reconciler verifies binding before trusting attribution. No bound identity = no claim authority. Status: research-grade only; not absorbed into doctrine yet. The doctrine memory file (PR #852, currently open) carries the v4 corrections; this file is the integration analysis Aaron requested for the Amara conversation. Composes with: - docs/research/2026-04-26-gemini-deep-think-agencysignature-... - docs/research/2026-04-26-amara-fail-open-with-receipts-... - docs/research/2026-04-26-amara-ferry-9-validation-of-relationship-... - docs/research/2026-04-26-amara-ferry-12-trailer-contiguity-... - tools/hygiene/validate-agencysignature-pr-body.sh - tools/hygiene/audit-agencysignature-main-tip.sh - memory/feedback_zeta_agent_orchestra_capability_role_claim_isolation_aaron_amara_2026_04_29.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(aurora): three Copilot review fixes on AgencySignature × layered-actor writeup PR #853 review threads (all P1/P2 from Copilot, all valid catches): - P1 PRRT_kwDOSF9kNM5-hHf6 (line 45 → enforcement-status accuracy): writeup said trailers are "validated pre-merge" / "missing or malformed = block". Reality: validate-agencysignature-pr-body.sh exists but is NOT yet wired into a required CI check under .github/workflows/. Reworded to say the validator "can be" a pre-merge gate; explicit caveat that wiring is its own follow-up (composes with task #300 squash-merge survival design). Same enforcement-status caveat applied to the post-merge auditor + the fail-open-with-receipts policy paragraph. - P1 PRRT_kwDOSF9kNM5-hHgq (line 151 → forward-compatibility correction): writeup claimed v2 "composes cleanly with v1 readers" because v1 readers "ignore unknown fields". Reality: validate-agencysignature- pr-body.sh requires Agency-Signature-Version=1 exactly AND requires Agent: as a key. So a Version=2 trailer set (and especially replacing Agent: with Actor:) would currently FAIL validation. Reworded to spell out the rollout sequence: (a) update validator to accept Version 1|2, (b) emit Agent: alongside Actor: during migration window, (c) extend auditor's three-state to four-state (LEGACY / CORRECT-V1 / CORRECT-V2 / REGRESSION), (d) drop dual Agent: emission once consumers are v2-aware. - P2 PRRT_kwDOSF9kNM5-hHhM (line 111 → Task vs Claim ambiguity): mapping table said Task → claim_id, but the v2 example had BOTH Task: 286 AND Claim: CLAIM-286. Aligned: Task remains the task / ticket pointer (v1 meaning preserved); Claim is a NEW v2 field that carries claim_id. Updated both the mapping table and the explanation paragraph below the v2 trailer example. These corrections strengthen the writeup before it goes to Amara — the asks Aaron is sending depend on getting the current-state-vs-future- state distinction right (especially around enforcement wiring and v1 forward-compatibility). Status unchanged: research-grade only; Aaron's deliverable for the Amara channel. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(aurora): fix MD032 — blank lines around 6 lists in writeup-for-amara markdownlint-cli2 flagged 6 MD032 errors (lists need surrounding blank lines) on the writeup. Inserted blank line after each list-introducing sentence at lines 41, 49, 120 (Under v4 with binding), 146 (we'd:), 151 (By layering), and 176 (Options:). No content changes. Per Otto-362 (just landed in PR #854) — would have caught this pre-push if I'd run markdownlint locally before opening the PR. Filing this commit as the kind of pure-mechanical-CI-fix that Otto-362 cannot prevent (it's a syntactic class, not semantic) — those still need lint coverage at submit-time. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(aurora): fix Copilot P1 — v2 example shows Agent: alongside Actor: during migration window Copilot caught internal inconsistency: I claimed v2 is a 'strict superset of fields' but the example removed Agent: and replaced it with Actor:. The migration-sequence text correctly says to dual-emit Agent: alongside Actor: during the migration window — but the example didn't show it. Updated the v2 example to retain Agent: alongside Actor:, with inline comment explaining it'\''s for v1-reader compat during migration. Also updated the explanation paragraph below the example to call out the Agent: retention rationale explicitly. Now the example matches the rollout sequence text: v1 validator accepts v2 trailers because Agent: is still present; once all consumers are v2-aware, drop the dual emission. Otto-362 in action — internal-contradiction class, caught by Copilot review since pre-push self-audit missed it. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(aurora): 2 Codex catches — distinguish authenticated-account vs spoofable-trailer + forged-vs-malformed enforcement - Codex P1 PRRT_kwDOSF9kNM5-hZey (line 139, security correction): writeup said E0/E1 actors are bound by 'GitHub authenticates the commit author / PR author'. WRONG: only the GitHub account actor (github.actor / pull_request.user.login) is reliably authenticated. Commit author metadata + Agent: + Credential-Identity: trailer fields are user-supplied and trivially spoofable via 'git commit --author=...'. Updated to: trust only the GitHub account actor at E0/E1; treat trailer fields as intent declarations the reviewer cross-checks before E2+ promotion; registered key binds at E3+. - Codex P2 PRRT_kwDOSF9kNM5-hZe2 (line 159, enforcement-semantics clarification): the writeup had two conflicting enforcement paths — earlier section said signature mismatch BLOCKS, later said forged trailers go through fail-open-with-receipts. These are different classes: malformed-but-honest (parser fail, missing key, etc.) → record + continue forged-or-impersonation (Signed-By doesn't verify) → BLOCK + flag Only malformed-honest takes the fail-open path; binding violations always block. Updated the carryover sentence to spell out the separation explicitly. Both catches matter for the v2 implementation: an ambiguous spec on forgery enforcement would let validator/reconciler implementations diverge. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Names a pattern observed across the same-day cluster of agent-orchestra doctrine PRs (#850 → #851 → #852 → #853): 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.
The trigger
Four PRs in one afternoon (2026-04-29) drove the agent-orchestra doctrine memory from ~100 lines to ~1080 lines through v1 → v2 → v3 → v4 expansions. Each PR triggered Copilot P1 / Codex P2 threads catching internal contradictions like:
request-agent-claim.mdvsstart-agent-claim.mdrunbook pathTask → claim_idvs example showing bothTask:ANDClaim:All caught by external AI review (Copilot + Codex); none caught by pre-push self-audit. Fix cadence was fast (one commit per thread cluster) but the count of internal-contradiction threads was disproportionate to the substantive-error count.
What this rule says
Before pushing a memory expansion that adds a new section:
Composes with
Why not a CI lint
Internal contradictions are semantic, not syntactic. Existing lints catch path-existence, duplicate-targets, snake_case consistency — but cannot catch "Currently undefined" + "Now specified" co-existing. Editing discipline is the only mechanism for semantic contradictions. Multi-AI review remains the safety net; Otto-362 reduces the count of iterations by catching the stale-statement class before push.
What this rule does NOT say
Files
memory/feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md(87 lines new file)memory/MEMORY.md(paired index row)Test plan
🤖 Generated with Claude Code