Skip to content

quilt kernel P2: encounter machine shadow + the negative ledger - #2

Closed
SuperInstance wants to merge 1 commit into
quilt-kernel-p1from
quilt-kernel-p2-encounters
Closed

SuperInstance wants to merge 1 commit into
quilt-kernel-p1from
quilt-kernel-p2-encounters

Conversation

@SuperInstance

Copy link
Copy Markdown
Owner

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

createLobsterEncounter gates the insert on changes()=1 across 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:

encounter.<interactionId>.refused = { refusedBy: ["actor"], remaining: [{kind, remainingSeconds}], ts }

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 untouched
  • link/unlink events persist as from->to edge rows (kernel L1 law enforced: bind-before-link) — the cell graph survives the WAL
  • wired: createLobsterEncounter / bindLobsterMessage / markLobsterPublicationFailed / recordLobsterResponse; projection failure logs, never throws
  • retry (existing) → encounter.<ix>.retried; created → attempt LINK encounter (the changes()=1 linkage made traversable)

Verification

  • 6 new tests: created-replay match, refusal ledger one-per-guard-dimension, retry, bind→response lifecycle, publication failure, chain integrity across mixed traffic
  • Full suite: 383 tests, only the 4 pre-existing artwork/env failures (verified identical on clean main), zero regressions
  • tsc --noEmit clean

Refs openclaw#48

…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.
SuperInstance added a commit that referenced this pull request Sep 20, 2026
…etector)

Conflict resolution: kept HEAD's commitNominationVoteProjection
(from PR #11) and the projection.ts structural-event changes
(from PR #2). Added PR #3's reconcile.ts (drift detector) and
the replay tests via auto-merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant