quilt kernel P4: adversarial-review fixes — D1 claim lock + replay hardening - #4
Closed
SuperInstance wants to merge 1 commit into
Closed
SuperInstance wants to merge 1 commit into
SuperInstance wants to merge 1 commit into
Conversation
…dening, idempotent migrations Findings from the adversarial pass on the P1-P3 stack, fixed: #1 (BLOCKER) concurrency: tip-read and insert were separate D1 batches; two interleaved writers both computed from the same tip and the hash chain self-invalidated permanently, silently. Fix: single-row claim lock in D1 (quilt_wal_lock, migration 0014 via drizzle-kit with proper snapshot). An in-memory mutex cannot hold across Worker isolates; the lock is claimed (holder = mutationId:nonce), tip+insert run under it, release in finally. Stale holders (>30s) are broken automatically. Claim exhaustion SKIPS the projection loudly (mirror posture) instead of corrupting the chain. The reviewer's probe is now a regression test. #3 replay functions sort by seq internally — seq-desc input replays identically to seq-asc (probe: a switched vote flipped back). #4 analyzeRefusals: suffix-strip interactionIds (cell shape is exactly encounter.<ix>.refused; <ix> may contain dots), index attempts by exact cell key in one pass (was O(n^2) and dot-blind), guarded JSON.parse — one corrupt row can no longer kill the analysis. #5 drizzle/meta/0013_snapshot.json hand-derived from 0012 + schema; drizzle-kit generate is now idempotent (was: re-emitted quilt_wal as a duplicate migration). 0014 generated the clean way, snapshot included. #6 dead projectNominationVote removed from projection.ts (single live copy in commit.ts). #7 unbind rows honored in replay (cell deleted, not stale-restored); bare entity binds count as entity markers so unbound-to-empty replays return the entity, not null. #8 THREAT MODEL documented: FNV-1a proves continuity, not tamper- evidence against a table writer; sha256 upgrade path noted, gate for audit-context citation. Suite: 393 tests, 24/24 across the four kernel suites, only the 4 pre-existing artwork/env failures (identical on clean main). tsc clean. Refs openclaw#48
SuperInstance
force-pushed
the
quilt-kernel-p4-review-fixes
branch
from
September 17, 2026 10:56
53ef4d8 to
6b29d99
Compare
This was referenced Sep 17, 2026
SuperInstance
added a commit
that referenced
this pull request
Sep 20, 2026
Took HEAD's commit.ts (with CAS guard + projections) and journal.json. Kept PR #4's schema changes, projection.ts updates, and review-fixes tests.
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.
Why
The adversarial pass on the P1–P3 stack found one BLOCKER: the tip-read and the insert were separate D1 batches — two interleaved writers both computed from the same tip, and the hash chain self-invalidated permanently, silently. Single-writer suites couldn't see it; Discord traffic is not single-writer. This PR fixes every finding.
Fixes
quilt_wal_lock(0014, drizzle-generated): single-row claim lock in D1 — an in-memory mutex can't hold across Worker isolates. Claim → tip+insert → release (finally). Stale holders (>30s TTL) auto-broken. Claim exhaustion skips loudly instead of corrupting. The reviewer's probe is now a regression test.seqinternally;seq descinput replays identicallyanalyzeRefusalscrashed on bad rows, O(n²), dot-blind ids0013_snapshot.json→ next generate re-emitsquilt_waldrizzle-kit generatenow idempotent; 0014 generated cleanlyprojectNominationVoteremoved; single live copyunbindinvisible to replayVerification
main)tsc --noEmitcleanRefs openclaw#48