Skip to content

quilt kernel P6: tidepool — the helper-thread memory ocean joins the ledger - #6

Closed
SuperInstance wants to merge 1 commit into
quilt-kernel-p4-review-fixesfrom
quilt-kernel-p6-tidepool
Closed

SuperInstance wants to merge 1 commit into
quilt-kernel-p4-review-fixesfrom
quilt-kernel-p6-tidepool

Conversation

@SuperInstance

Copy link
Copy Markdown
Owner

Why

The tidepool bench (sibling of hermit, same quilt kernel) proves the helper-thread memory ocean: every write is a dual-write — the ocean markdown is the human-readable memory, the quilt WAL is the replayable ledger. The bench contract lives in /tmp/tidepool/README.md; this PR ports it into hermit as a first-class module.

Import, never duplicate: the port consumes commitProjection from src/quilt/commit.ts and the hash-chain primitives (verifyChain, WalRow) from src/quilt/projection.ts. The fnv1a chain input is byte-identical to hermit's, so tidepool WAL rows share the same quilt_wal table without collision.

What

src/tidepool/ocean.tsTidepoolOcean: markdown ocean + recall index. Deterministic weighted token scoring (helper/question ×2, response/meta ×1), ties to most recently remembered, limit clamped 3..5. stats() audits the rememberBotAction oaths: never modify (no edit/delete API exists), always append-only (re-remember appends a new section; a memory of a memory stays), always timestamps (every section carries rememberedAt).

src/tidepool/stall.tsthreadLengthMonitor as a pure function: detectQuietThreads (windowed flat-run detection, growth resets, unsorted input) and newlyQuietThreads (crossing-only delta for a 30-min cron — silence is remembered once; bench extra, pure composition).

src/tidepool/projection.tsprojectHelperThread BIND-for-BIND with the L1 law honored (channel + helper endpoints bound before the thread links them); projectQuietThread mirrors the P2 .refused negative ledger — a quiet thread is an absence, and the absence is the information. replayThreadIndexFromWal folds WAL-only rows; .quiet state survives alongside remembered threads. readWalRowsByMutation / readWalRowsSince tolerate both SqliteD1 (sync .all()) and Cloudflare D1 (async {results}) shapes.

src/tidepool/index.ts — the six public entry points:
rememberHelperThread, rememberChannelThreads (one mutation for N threads), recallHelperContext, rememberBotAction, drainQuietThreads, plus replayThreadIndexFromWal from projection. Every write dual-writes; WAL failures are caught and counted, never thrown into the helper path.

Migration 0015helper_threads + helper_logs (drizzle-generated, snapshot + journal committed; second generate run confirms "No schema changes"). Per the contract, the WAL is the source of truth — these tables are the materialized view for live reads.

Verification

  • bun run typecheck clean
  • New suite: 11 tests, 55 expects, all pass
  • Full suite: 400 pass / 4 fail — the 4 fails are the pre-existing lobster-artwork failures on base (untouched here); p4 baseline was 393 + 11 = 404 total

Deviations from the README (documented per contract)

  1. Migration number 0015, not 00140014 was already taken by the p4 quilt_wal_lock migration on this base.
  2. replayThreadIndexFromWal is exported from projection.ts, not index.ts — keeps index.ts to the six write/read entry points; same public surface overall.
  3. WAL failure counting uses a local counter in index.ts (getTidepoolWalFailures) — PR quilt kernel P5-ops: the ledger reports its own health #5's ops counters (recordWalFailure("tidepool_projection")) are a 2-line follow-up once quilt kernel P5-ops: the ledger reports its own health #5 lands; this branch is independent of quilt kernel P5-ops: the ledger reports its own health #5 by design.

Merge order

Stacked on quilt-kernel-p4-review-fixes (same base as PR #5). Independent of PR #5 — they touch disjoint files (P5: src/quilt/ops.ts + catch sites in data layer; P6: all-new src/tidepool/*). Both land after #4.

Refs openclaw#48

…ledger

Port of the tidepool v1 bench contract (/tmp/tidepool/README.md is the
spec; the README wins wherever bench implementations diverged).

- src/tidepool/ocean.ts — markdown ocean + recall index; weighted token
  scoring (helper/question x2, response/meta x1), tie to most recent,
  clamp 3..5, deterministic (replay-reproducible, no embeddings)
- src/tidepool/stall.ts — threadLengthMonitor as a pure function; absence
  is the information (P2 negative-ledger pattern)
- src/tidepool/projection.ts — projectHelperThread BIND-for-BIND (L1 law:
  channel + helper endpoints bound before the thread links them);
  projectQuietThread mirrors .refused; replayThreadIndexFromWal folds
  WAL-only rows; readWalRowsByMutation/readWalRowsSince for API read-back
  and tip continuation (tolerant of SqliteD1 sync-all and D1 async-all)
- src/tidepool/index.ts — six public entry points; every write is a
  DUAL-WRITE (ocean markdown + quilt WAL); WAL failures caught and
  counted (local counter, forward-compatible with PR #5 ops counters)
- helper_threads + helper_logs migration 0015 (drizzle-generated with
  snapshot + journal)
- 11 tests: chain verifies with hermit's own verifyChain, L1 link order,
  single-mutation channel sweep, recall scoring/clamp/determinism,
  quiet detection + newlyQuietThreads crossing-only, drain negative
  ledger (helper_threads untouched), WAL-only replay parity, markdown
  reload parity, tip continuation, WAL-failure posture (memory survives,
  failure counted), oath audit (append-only, timestamps)

Refs openclaw#48
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