quilt kernel P2: encounter machine shadow + the negative ledger - #2
Closed
SuperInstance wants to merge 1 commit into
Closed
SuperInstance wants to merge 1 commit into
SuperInstance wants to merge 1 commit into
Conversation
…dger
The encounter machine gates inserts on changes()=1 across a quadruple
NOT EXISTS guard (actor/target/channel/already-exists). Most attempts
in the wild are refusals — and refusals leave no rows in live D1.
The negative ledger makes a refusal a first-class WAL row:
encounter.<interaction>.refused = { refusedBy, remaining, ts }
analyzeRefusals() walks the WAL and returns every denied attempt —
a query that is impossible against live D1, since the absences are
the information. H(N) > H(R), operationalized.
Also:
- generalized commitProjection(); nomination projection stays intact
- link/unlink events now persist as edge rows (from->to) so the cell
graph survives the WAL; replay ignores non-bind ops
- dual-write wired into createLobsterEncounter / bindLobsterMessage /
markLobsterPublicationFailed / recordLobsterResponse; projection
failures log-and-never-throw (P1 posture)
- tests/quiltKernelEncounters.test.ts: 6 tests — created-replay match,
refusal ledger per guard dimension, retry row, bind->response
lifecycle, publication failure, chain integrity across mixed traffic
Full suite: 383 tests, 4 pre-existing artwork/env failures (identical
on clean main), zero regressions. typecheck clean.
Refs openclaw#48
SuperInstance
pushed a commit
that referenced
this pull request
Sep 17, 2026
Review finding #2 (code half): every WAL projection failure reduced to a console.warn and nothing in production reads quilt_wal — the mirror could die at deploy and nobody would know for a week. - src/quilt/ops.ts: failure counters per kind (recordWalFailure), rows-committed gauge (recordWalCommit), getWalFailureCounts / getWalRowsCommitted / resetWalOps (test hook), and reconcileTick — a cron-ready wrapper around the reconciliation pass that returns a summary and never throws (a failed tick is itself a counted failure). - All five silent catch sites (nominations.ts, lobsterEncounters.ts x4) now count through recordWalFailure; commit.ts counts lock exhaustion (was a bare warn) and successful rows. - Posture unchanged: the user path never sees a mirror exception — drift is now a NUMBER you can alert on, not a rumor. Alert wiring: failureCounts.reconcile_tick > 0 or mismatchCount > 0 in the ReconcileTickSummary; schedule via wrangler [triggers] crons. Suite: 398 tests (5 new ops proofs incl. the real deploy-time failure mode — WAL table missing, vote still records, counter increments). Only the 4 pre-existing artwork/env failures (identical on clean main). Refs openclaw#48
SuperInstance
added a commit
that referenced
this pull request
Sep 20, 2026
…edger Added commitProjection as a generic projector alongside commitNominationVoteProjection (the vote-specific wrapper from PR #11). The encounters dual-write (P2) uses commitProjection. The vote path (PR #11) continues to use commitNominationVoteProjection which wraps commitProjection with the nomination-specific projection. Conflict resolution: - src/quilt/commit.ts: kept HEAD's commitNominationVoteProjection + CAS guard from PR #11; added commitProjection from PR #2 manually so both coexist.
SuperInstance
added a commit
that referenced
this pull request
Sep 20, 2026
Final commit with the dual-write wiring + tests that didn't make it into the merge commit earlier. Adds commitProjection + encounter projection functions.
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
Stacks on #1 (P1). Dual-writes the lobster encounter machine — the fleet's deepest transactional boundary — into the 5-opcode kernel WAL, and makes its refusals first-class rows.
The negative ledger
createLobsterEncountergates the insert onchanges()=1across a quadruple NOT EXISTS guard (actor 30s / target 90s / channel 12s / already-exists). Most real attempts are refusals — and refusals leave no rows in D1.This PR binds a refusal as:
analyzeRefusals(walRows, guildId?)returns every denied attempt. This query is impossible against live D1 — the absences are the information. The WAL now sees the reef of encounters that never were.Also
commitProjection()generalized; P1 nomination path untouchedfrom->toedge rows (kernel L1 law enforced: bind-before-link) — the cell graph survives the WALcreateLobsterEncounter/bindLobsterMessage/markLobsterPublicationFailed/recordLobsterResponse; projection failure logs, never throwsencounter.<ix>.retried; created → attempt LINK encounter (thechanges()=1linkage made traversable)Verification
main), zero regressionstsc --noEmitcleanRefs openclaw#48