docs(chit): CHIT-FORKS provenance declaration + cipher fork record - #3063
Merged
Merged
Conversation
The Three-Body problem from pmoves/docs/PMOVESCHIT/THREE_BODY_DOCTRINE.md
("without stabilization one body gets ejected") is the same shape
as the flat-hierarchy failure mode the cipher reconcile surfaced:
upstream byterover-cli baked in MAX_CONTENT_LENGTH=10_000,
MAX_TAG_LENGTH=50, MAX_TAGS=10 at fork-time. PMOVES has no signing
card on those constants; the artifact is a self-authorized black
hole. PR #2950's rooms-bug is the recent example.
This doc declares a CHIT-FORK pattern: a small, append-only record
that pins (a) the artifact, (b) the upstream commit, (c) the PMOVES
overlay, (d) the signing-card claim for the overlay only -- not the
upstream side, which is out of our sign-off loop. The first worked
record is the cipher fork (MemoryManager constants have no card;
the shim's Bearer contract does).
Follow-ups (§6) pair with wave-3 ratchet work: the 4 undeclared
PMOVES submodules (Composio/Activepieces/N8N) need fork-registry
entries before they can carry CHIT-FORK records. Pipecat, Crush,
and Agent-Zero forks are the natural next records.
No schema, secret, or compose changes. Docs-only.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Contributor
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
POWERFULMOVES
added a commit
that referenced
this pull request
Sep 15, 2026
…ite bypass (#3069) * infra(cipher): promote gitlink to 975e02e6, re-pin the citations it moved, and stop re-pinning by hand Pmoves-cipher#19 merged (`Accept-Profile: pmoves_core`). Without that header PostgREST resolves `cipher_agent_tokens` against the default `public` profile and 404s, so EVERY per-agent token failed as "invalid" — verified against migration 20260728100000, which creates the table in `pmoves_core`. It was the blocker under both halves of the card-authority work and sat five days on a single-account review requirement. Gitlink e24f1323 -> 975e02e6 (reachable on PMOVES.AI-Edition-Hardened; also brings #18 and e9ee58cb, both docs). THE PIN MOVE BREAKS CITATIONS, EXACTLY AS PREDICTED. #19 inserts three lines at :67, so four of the nine `auth.ts` citations shift +3: !token.startsWith('cipher_') 46 -> 46 (+0) agentId: 'bootstrap' 49 -> 49 (+0) records.length === 0 79 -> 82 (+3) !legacyToken && skipIfUnset 103 -> 106 (+3) This is the second time in a week these numbers were wrong, for two different reasons — the first was reading them off a working tree parked on that same PR's unmerged head, where the numbers were right for me and wrong for everyone else. Re-numbering by hand on each bump is not a fix; it is the same manual step failing again on a schedule. `pmoves/tests/tools/test_auth_citations_resolve.py` makes it machine-checkable on the required test job, in three directions: 1. the gitlink still equals the pin these numbers were read at — this test FAILED first run, correctly, because the promotion was staged and not yet committed, and `git ls-tree HEAD` reads the committed link; 2. every cited LINE still carries its ANCHOR text in the pinned file; 3. the docs quote the CURRENT numbers, with a negative control that the SUPERSEDED ones are gone — asserting the new numbers are present does not prove the old ones left, and a half-finished edit leaves both. It also fails when the submodule WORKING TREE is ahead of the pin, which is the condition that caused round one and reads as current when it is not. Anchors are the real citation. The numbers are a convenience for a human reader and this test is what keeps the convenience honest. Docs re-pinned: TAC_CIPHER.md (provenance history rewritten as a three-pin table, every superseded number now pin-qualified so no bare stale citation can be read as current), cipher_identity.py, the cipher-memory SKILL, and the lane tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx * docs(chit): fill the cipher fork record's commit pins, and check signing cards exist AMENDMENT to #3063's record, filed under `z890-claude`, `signing_card` fields left as `5090-claude` — this fills placeholders and appends a row, it does not reassign authorship. §5 says each record is reviewed and signed by its lane owner, so the derivation below is flagged for 5090-claude to confirm. THE PINS. The record merged carrying `<filled when PR opens>` in both commit fields, while its own §6.1 said the PR became mergeable *once the fork commit was known*. So the first worked example of the provenance doctrine named its artifact and pinned no commit, which makes "which auth.ts?" unanswerable from the record — the exact question the doctrine exists to answer. Not a criticism from outside: the same week, this lane cited auth.ts line numbers read off a submodule working tree parked on an unmerged fork PR's head. Two nodes, one session, the same failure from two directions — naming the artifact without pinning the commit. Evidently easy to do while writing the document that forbids it. pmoves_fork_commit 975e02e6... the gitlink main carries, promoted in this same PR so record, gitlink and citations cannot disagree upstream.pinned_commit 1052ac1a... parent of 389ce722, the first commit to touch src/pmoves/ — the last upstream state before the overlay. Derived, not guessed; authored by cuongdo-byterover. NEW OVERRIDE ROW: the per-agent token mode (`auth.ts:46,49`). A bearer prefixed `cipher_` resolves against pmoves_core.cipher_agent_tokens; one without it is attributed to the literal `bootstrap` with no lookup. That contract was unrecorded, and it is what two lanes on two nodes were independently building on. THE CARD CHECK. #3063 declares that a constant with a card has an author and a verification surface — and nothing checked the cards it names EXIST. Same gap, one level up: a record asserting `signing_card: 5090-claude` carries exactly as much authority as the claim that `5090-claude` is real and active, and a typo or a deactivated card left it reading as authoritative while pointing at nobody. `test_chit_forks_cards.py` uses the SAME `load_active_card_agents` that `mint_cipher_token.py` gates minting on, so authorship-of-a-fork-override and existence-of-a-memory-identity cannot drift apart about what an active card is. This is the first cross-cutting use of that check. `signing_card: none` stays valid and is pinned by a negative control — it is how a record says "upstream's constant, no PMOVES authorship". Rejecting it would push records toward inventing an owner, the opposite of the doctrine. Mutation-checked: a typo'd card name and an abbreviated (non-40-char) pin each fail exactly one test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx * docs(register): RELEASE row for the cipher gitlink + provenance lane Filed through `make -C pmoves register-release`; register diff is 1 added, 0 deleted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx * fix(hooks): a command substitution is a command — close a register-write bypass SECURITY. Wrapping a blocked register write in `$( )` plus one leading word turned BLOCK into ALLOW. Measured on the pre-fix hook: env cp /tmp/x <register> BLOCK "cp writes the register as its DESTINATION" N=$(env cp /tmp/x <register>) ALLOW <- the same write, permitted The hook's own header records six shapes that bypassed the design this allowlist replaced. This was a seventh, inside the allowlist. ROOT CAUSE, one fault, both directions. `_segments` splits on `; | & \n && ||` and has no notion of `$( )`, so the parens stayed glued to adjacent tokens: N=$(env cp /tmp/x REG) -> ['N=$(env', 'cp', '/tmp/x', 'REG)'] `ASSIGNMENT_RE` matched the `N=` prefix of token 0, so the WHOLE token was consumed as an assignment and `env` never reached `_strip_prefixes`' wrapper list. The destination then arrived as `REG)` with the paren attached, so `_is_register()` -- a path test, correctly -- said no, and the copy-verb guard never fired. The same fault refused reads the hook intends to allow: N=$(git show origin/main:REG) "`show` is not a command ..." though `show` IS in `_GIT_READ_SUBCOMMANDS`. `git` was eaten with the `N=`, so the SUBCOMMAND was judged as if it were the command. `git diff` survived only because `diff` also exists as a top-level read-only command -- so the documented read path was working for the wrong reason, and the workaround I reported yesterday ("use git diff --numstat instead") was passing by coincidence. THE FIX. `_segments` now emits a substitution body as its OWN segment and removes it from the outer text, leaving a bare `N=` that names no command. That is the direction the function's docstring already endorses -- more segments face the allowlist, so the verdict can only get stricter. Bodies are segmented recursively (depth-capped; an over-nested one becomes a single unparseable segment the allowlist refuses, rather than vanishing). Backticks handled. Arithmetic `$((...))` is explicitly NOT a substitution -- judging `1` as a command would refuse it. An unterminated `$(` keeps its text as literal, so an unbalanced paren cannot swallow a write into an earlier allowed segment. VERIFICATION. 17 tests. Reverting only the hook fails 9 of them -- the 4 fail-opens and 5 false refusals -- while every control still passes, which is what proves the suite measures the substitution handling and not something incidental: * unwrapped `cp`/`env cp` stay blocked (so the wrapped tests measure the WRAPPER) * `N=$(wc -l < REG)` stays ALLOWED (so the fix is not "refuse every $( )", the cheap version that would pass every write test and re-break the read path this defect was found through) * `$((1+1))` stays allowed * an unterminated `$(` still blocks the write after it * `make -C pmoves register-status` still passes -- the sanctioned path must keep working or the fix trades one deadlock for another Found while investigating a reported papercut ("the hook refuses read-only `git show`"). It was not a policy choice; `show` was already on the allowlist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES
added a commit
that referenced
this pull request
Sep 15, 2026
…ns, and stop re-pinning citations by hand (#3068) * infra(cipher): promote gitlink to 975e02e6, re-pin the citations it moved, and stop re-pinning by hand Pmoves-cipher#19 merged (`Accept-Profile: pmoves_core`). Without that header PostgREST resolves `cipher_agent_tokens` against the default `public` profile and 404s, so EVERY per-agent token failed as "invalid" — verified against migration 20260728100000, which creates the table in `pmoves_core`. It was the blocker under both halves of the card-authority work and sat five days on a single-account review requirement. Gitlink e24f1323 -> 975e02e6 (reachable on PMOVES.AI-Edition-Hardened; also brings #18 and e9ee58cb, both docs). THE PIN MOVE BREAKS CITATIONS, EXACTLY AS PREDICTED. #19 inserts three lines at :67, so four of the nine `auth.ts` citations shift +3: !token.startsWith('cipher_') 46 -> 46 (+0) agentId: 'bootstrap' 49 -> 49 (+0) records.length === 0 79 -> 82 (+3) !legacyToken && skipIfUnset 103 -> 106 (+3) This is the second time in a week these numbers were wrong, for two different reasons — the first was reading them off a working tree parked on that same PR's unmerged head, where the numbers were right for me and wrong for everyone else. Re-numbering by hand on each bump is not a fix; it is the same manual step failing again on a schedule. `pmoves/tests/tools/test_auth_citations_resolve.py` makes it machine-checkable on the required test job, in three directions: 1. the gitlink still equals the pin these numbers were read at — this test FAILED first run, correctly, because the promotion was staged and not yet committed, and `git ls-tree HEAD` reads the committed link; 2. every cited LINE still carries its ANCHOR text in the pinned file; 3. the docs quote the CURRENT numbers, with a negative control that the SUPERSEDED ones are gone — asserting the new numbers are present does not prove the old ones left, and a half-finished edit leaves both. It also fails when the submodule WORKING TREE is ahead of the pin, which is the condition that caused round one and reads as current when it is not. Anchors are the real citation. The numbers are a convenience for a human reader and this test is what keeps the convenience honest. Docs re-pinned: TAC_CIPHER.md (provenance history rewritten as a three-pin table, every superseded number now pin-qualified so no bare stale citation can be read as current), cipher_identity.py, the cipher-memory SKILL, and the lane tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx * docs(chit): fill the cipher fork record's commit pins, and check signing cards exist AMENDMENT to #3063's record, filed under `z890-claude`, `signing_card` fields left as `5090-claude` — this fills placeholders and appends a row, it does not reassign authorship. §5 says each record is reviewed and signed by its lane owner, so the derivation below is flagged for 5090-claude to confirm. THE PINS. The record merged carrying `<filled when PR opens>` in both commit fields, while its own §6.1 said the PR became mergeable *once the fork commit was known*. So the first worked example of the provenance doctrine named its artifact and pinned no commit, which makes "which auth.ts?" unanswerable from the record — the exact question the doctrine exists to answer. Not a criticism from outside: the same week, this lane cited auth.ts line numbers read off a submodule working tree parked on an unmerged fork PR's head. Two nodes, one session, the same failure from two directions — naming the artifact without pinning the commit. Evidently easy to do while writing the document that forbids it. pmoves_fork_commit 975e02e6... the gitlink main carries, promoted in this same PR so record, gitlink and citations cannot disagree upstream.pinned_commit 1052ac1a... parent of 389ce722, the first commit to touch src/pmoves/ — the last upstream state before the overlay. Derived, not guessed; authored by cuongdo-byterover. NEW OVERRIDE ROW: the per-agent token mode (`auth.ts:46,49`). A bearer prefixed `cipher_` resolves against pmoves_core.cipher_agent_tokens; one without it is attributed to the literal `bootstrap` with no lookup. That contract was unrecorded, and it is what two lanes on two nodes were independently building on. THE CARD CHECK. #3063 declares that a constant with a card has an author and a verification surface — and nothing checked the cards it names EXIST. Same gap, one level up: a record asserting `signing_card: 5090-claude` carries exactly as much authority as the claim that `5090-claude` is real and active, and a typo or a deactivated card left it reading as authoritative while pointing at nobody. `test_chit_forks_cards.py` uses the SAME `load_active_card_agents` that `mint_cipher_token.py` gates minting on, so authorship-of-a-fork-override and existence-of-a-memory-identity cannot drift apart about what an active card is. This is the first cross-cutting use of that check. `signing_card: none` stays valid and is pinned by a negative control — it is how a record says "upstream's constant, no PMOVES authorship". Rejecting it would push records toward inventing an owner, the opposite of the doctrine. Mutation-checked: a typo'd card name and an abbreviated (non-40-char) pin each fail exactly one test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx * docs(register): RELEASE row for the cipher gitlink + provenance lane Filed through `make -C pmoves register-release`; register diff is 1 added, 0 deleted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jxd5gryAFPXwhjaCMw9Qrx --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Declares the CHIT-FORKS pattern: a small, append-only record that pins an artifact + its upstream commit + its PMOVES overlay + the signing-card claim for the overlay. The first worked record is the cipher fork (Pmoves-cipher/src/agent/infra/memory/memory-manager.ts constants MAX_CONTENT_LENGTH / MAX_TAG_LENGTH / MAX_TAGS have no signing card; the shim's Bearer contract does).
Closes the flat-hierarchy failure mode the cipher reconcile surfaced this session: upstream byterover-cli baked in defaults at fork-time, PMOVES has no authorship on them, the artifact is self-authorized. The Three-Body problem from THREE_BODY_DOCTRINE.md names it; PR #2950 rooms-bug is the recent example. The fix is not changing the constants (that needs a byterover upstream bump), it's declaring whose they are.
Docs-only. Single new file: pmoves/docs/PMOVESCHIT/CHIT_FORKS.md. No schema, secret, or compose changes. Follow-ups (§6 in the doc) pair with wave-3 ratchet work.