fix: harden the PCM ledger — structural conflict-freedom, forgery resistance, idempotent import#26
Merged
CodeWithJuber merged 1 commit intoJul 7, 2026
Conversation
…istance, idempotent import Findings from an 8-angle adversarial review of the P1 merge, all fixed: - claim files now hold pure content (kind/body/scope/v) so the same id is byte-identical on every replica; provenance and tombstones move into per-claim append-only logs (hash-deduped, union-merged like evidence) — the semilattice merge property now holds for ALL state, including concurrent mints and concurrent retractions (property-tested) - val() takes oracle weights from the ORACLES table, never the stored record, and ignores unknown oracles; forge ledger verify recomputes every record's content hash and flags forgery/ghost oracles/inflated weights (previously a hand-edited log line could buy val ~0.98) - forge ledger import: claims already tracked live are skipped entirely — no re-synthesized evidence, no double counting, true idempotence - cortex bridge: applyDistillation supersedes (evidence carried to the distilled claim, template tombstoned); evidence refs carry the confirmation counter (same-day session episode-id collisions no longer dedupe real confirmations); regex-detected reverts contradict at the conservative bridge weight, not full-weight human.revert - facts: single CRLF-tolerant parser (recall.readFact) + trimmed bodies so the shadow path and import path mint one id; same-name updates supersede the old claim; recall consolidate reconciles deletions into tombstones - putClaim repairs corrupt/truncated claim files instead of trusting existsSync; forge ledger show resolves via its shard; --personal reaches the personal ledger; forge init emits the union-merge .gitattributes rule into consumer repos; SCOPE_WEIGHT single-sourced in the ledger core - readLog returns records in (t, h) order so views never depend on on-disk line order after a union merge 270/270 tests (17 new/extended), biome + tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
CodeWithJuber
marked this pull request as ready for review
July 7, 2026 16:27
This was referenced Jul 7, 2026
Merged
Merged
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.
What & why
The production-readiness pass on the P1 ledger (#25). An adversarial 8-angle review (line-scan, removed-behavior, cross-file trace, reuse, simplification, efficiency, altitude, conventions — each finding independently verified) ran against the merged code and confirmed several real defects. All are fixed here, each with a regression test.
The three serious ones:
mergeStates. Tombstones had the same flaw (single file, first-writer-wins). Now: claim bytes are a pure function of (kind, body, scope) — byte-identical on every replica — and provenance + tombstones move into per-claim append-only logs, hash-deduped and union-merged exactly like evidence. The semilattice property now holds for all state, including concurrent retractions, and the property tests cover it.w: 50on the strongest oracle would previously pushvalto ~0.98 and passforge ledger verify. Nowval()takes weights from the ORACLES table only (storedwis audit metadata), unknown oracles are ignored, andverifyrecomputes every record's content hash — flagging forgery, ghost oracles, and inflated weights.forge ledger importwasn't idempotent. Synthetic outcomes were re-hashed on every run (the legacy counters keep moving) and double-counted confirmations already shadow-written live. Now a claim that's already tracked is skipped entirely — import back-fills pre-ledger history only, and re-running is a proven no-op.Also fixed (each was a verified finding): distillation now supersedes in the ledger (evidence carried to the distilled claim, template tombstoned — previously a lesson's history split across orphaned claims); evidence refs carry the confirmation counter (same-day sessions share episode ids — real confirmations were being silently deduped); regex-detected reverts contradict at the conservative bridge weight instead of full-weight
human.revert(a routinegit restorecould permanently bury a good lesson in the append-only log); fact claims mint one id from both the shadow path and the file-parse path (single CRLF-tolerant parser + trimmed bodies — Windows checkouts forked ids before); same-name fact updates supersede the stale claim andrecall consolidatereconciles deletions into tombstones (no phantom memories at the P2 read-flip);putClaimrepairs corrupt/truncated files instead of trustingexistsSync; log reads return records in (t, h) order so views never depend on post-merge line order;forge ledger showresolves via its shard instead of scanning the ledger;forge ledger --personalreaches the personal ledger (it was write-only);forge initemits the union-merge.gitattributesrule into consumer repos (it only existed in forgekit's own);SCOPE_WEIGHTsingle-sourced in the ledger core; the CLI's shadow-write imports are inside try/catch so a broken bridge can't fail an already-persisted write.Checklist
npm testpasses (270/270 — 17 new/extended tests incl. concurrent-retraction convergence, forged-evidence rejection, corrupt-file repair, import idempotence under live shadow-writes, CRLF parity, supersede-on-distill)npm run checkpasses on changed files (remaining repo diagnostics pre-date this PR)readFact,shadowFact,reconcileFacts,supersedeLessonClaim,getClaimByPrefix,sealRecord,isDormant,shingles,claimText— closing the review's coverage finding)fix:)CHANGELOG.mdupdated under## [Unreleased]docs/plans/substrate-v2/01and02more faithfully than the P1 merge didRisk & rollback
loadStatestill accepts P1-format claim files (the id never covered provenance, so addresses are unchanged).forge/ledger/remains inert dataExtra checks (tick if applicable)
npm run typecheckpasses🤖 Generated with Claude Code
https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
Generated by Claude Code