Skip to content

feat(agent-harness): persist authoritative state in SQLite - #5675

Open
iscekic wants to merge 1 commit into
shared-agent-harness-3bb0-s9from
shared-agent-harness-3bb0-s10
Open

feat(agent-harness): persist authoritative state in SQLite#5675
iscekic wants to merge 1 commit into
shared-agent-harness-3bb0-s9from
shared-agent-harness-3bb0-s10

Conversation

@iscekic

@iscekic iscekic commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

No new behavior — this change prepares data storage without changing how people use the product.


Summary

The new conversation, messages, commands, runs, checkpoints, calls, interactions, grants, attempts, clientActions, events, snapshots, and projectionWork tables persist authoritative conversation state.
ConversationStore.transition commits state, increasing event sequences, and CommandReply results atomically; matching command retries replay the original reply, while changed inputs return command_conflict.
bindExistingConversation requires authenticated PostgreSQL identity and rejects ownership or context changes; the permission_mode storage default is ask.

Files
  • services/agent-harness/src/db/sqlite-schema.ts — Source, added (+171/-0 lines). Defines 13 tables with singleton checks, reference constraints, history and queue indexes, and unique positions, active slots, and generations. Stores full message parts and command replies separately from replay events. Persists permission_revision, sequence, compacted_through, active_run_id, legacy_cursor, run step, and record revisions. Keeps definition_versions, input_digest, policy, and intent with execution records; retains outcome and provider_reference for attempts. Tracks projection work through message_id, due_at, acknowledged_at, and revision.

transitionWithWake serializes preparation and commits through blockConcurrencyWhile, then prearms the earliest durable alarm before the synchronous transaction.
AlarmStorage failures raise retryable StoreError('storage_unavailable') without committing; wakeAt: null is reserved for wait-only changes.
Runnable run events and active-run release with queued work require a wake, including terminal transitions and callback writes; commit callbacks cannot return promises.

Files
  • services/agent-harness/src/db/wake.ts — Source, added (+54/-0 lines). Adds injectable alarm storage, synchronous preparation and commit, safe-integer deadlines, and earliest-alarm preservation. Calls transactionSync immediately after alarm scheduling, with no intervening asynchronous operation. Rejects thenable commit results and rethrows expected errors outside the concurrency gate to avoid resetting the object. Keeps an armed alarm if the commit fails.

applyEvent and compareAndSetActiveRun preserve identity, permission revisions, queue order, one active run, and final interaction resolutions.
CheckpointSchema, insertCall, insertGrant, and insertAttempt retain validated dispatch inputs and intent; partial or failed checkpoints cannot authorize execution.
compareAndSetCall rejects stale revisions, settled-call changes, and execution without durable intent; waiting runs keep the active slot and block later runs.

Files
  • services/agent-harness/src/db/records.ts — Source, added (+318/-0 lines). Adds StoreDatabase, record validation, pageLimit from 1 to 200, and compare-and-set helpers. Materializes conversation, message, run, interaction, and client-action events within the caller's transaction. Preserves conversation ownership and context, message identity, and run identity; changed permissions require the next revision. New runs start queued; terminal run states and resolved interactions cannot change. Call insertion requires a complete checkpoint for the same run, a matching definition version, and the conversation context. Grants must match the call, owner, conversation, client, digest, and definition version; attempts must match the grant generation. Persists the call, digest, policy, and grant before execution. Client attempts require a grant; call updates require the current revision, and executing calls require a stored attempt.

ConversationStore adds atomic snapshots, paged history, bounded replay, and legacy import; pendingProjections and acknowledgeProjection use due times and revisions for acknowledgments.
eventsAfter limits replay to 200 events and 256 kibibytes (KiB); expired cursors or an oversized first legacy delta return cursor_expired.
compactEvents retains command results, canonical messages, and unresolved work; importLegacy accepts valid large text, deduplicates message identifiers, and advances the legacy cursor.

Files
  • services/agent-harness/src/db/store.ts — Source, added (+401/-0 lines). Adds openStore, conversation binding, command lookup, and atomic transitions with monotonically increasing event sequences. Requires matching command and reply identifiers; matching retries return stored replies without another write. Rejects runnable events without a wake and rejects active-run release when queued work remains without a wake, including callback writes. Reads snapshots and their event cursors together; includes 50 recent messages, the active run, queued runs, unresolved interactions, and pending client actions. Snapshot reads fail rather than hide any queue, interaction, or action list longer than 200. Orders history by creation time and identifier; bounds history, queue, call, event, and projection pages to 200 records. Reads events strictly after the cursor, checks the serialized response size, and rejects oversized non-legacy events. Old or future cursors expire; an oversized legacy event requires snapshot recovery when it cannot fit first in a replay page. Compaction stores a snapshot before deleting bounded event batches; it retains original replies, canonical message parts, checkpoints, and unresolved records. Legacy import deduplicates message identifiers and advances the ingestion cursor atomically. pendingProjections returns due, unacknowledged work; acknowledgeProjection compares and increments the revision, so stale or repeated acknowledgments return false.

openStore runs pending Drizzle migrations before serving operations; callers must initialize it within the Durable Object constructor's concurrency gate.
The SQLite migration configuration uses the durable-sqlite driver, and the migrations declaration derives its type from the maintained migrate contract.
Two tracked migrations create the authoritative tables and projection work; each instance upgrades on access, without a centralized migration command.

Files
  • services/agent-harness/drizzle.config.ts — Source, added (+8/-0 lines). Configures SQLite schema generation with the Durable Object driver and tracked migration output.
  • services/agent-harness/drizzle/migrations.d.ts — Source, added (+4/-0 lines). Types the generated migration bundle with Parameters<typeof migrate>[1].
  • services/agent-harness/drizzle/0000_authoritative_store.sql — Generated, added (+116/-0 lines). Adds the authoritative-store migration.
  • services/agent-harness/drizzle/0001_projection_work.sql — Generated, added (+10/-0 lines). Adds the projection-work migration.
  • services/agent-harness/drizzle/meta/0000_snapshot.json — Generated, added (+758/-0 lines). Adds the initial schema snapshot.
  • services/agent-harness/drizzle/meta/0001_snapshot.json — Generated, added (+821/-0 lines). Adds the next schema snapshot.
  • services/agent-harness/drizzle/meta/_journal.json — Generated, added (+20/-0 lines). Adds the migration journal.
  • services/agent-harness/drizzle/migrations.js — Generated, added (+11/-0 lines). Adds the migration loader.

The STORE and OLD_STORE bindings run storage tests against real SQLite Durable Objects, including empty and older schemas.
The test harness replaces conditional Wrangler discovery with a test-only entrypoint and raw SQL imports, so production bindings and environment files stay unloaded.
remoteBindings remains disabled; this configuration validates storage without providing a production Worker or an alarm handler.

Files
  • services/agent-harness/vitest.config.ts — Source, modified (+11/-6 lines). Selects TestStore and OldTestStore through STORE and OLD_STORE; enables SQLite and raw SQL imports without loading deployment configuration.
  • services/agent-harness/src/db/store.test.ts — Test, added (+1370/-0 lines). Adds real Worker storage coverage, including large legacy text and wake retention after terminal transitions.
  • services/agent-harness/src/db/test-worker.ts — Test, added (+64/-0 lines). Adds the test-only Worker and storage fixtures for current and older schemas.
  • services/agent-harness/src/db/test-env.d.ts — Test, added (+1/-0 line). Adds the test environment declaration.

Tests: 3 files added — store.test.ts (+1370 lines), test-worker.ts (+64 lines), and test-env.d.ts (+1 line).
Generated: 6 files added — 0000_authoritative_store.sql (+116 lines), 0001_projection_work.sql (+10 lines), 0000_snapshot.json (+758 lines), 0001_snapshot.json (+821 lines), _journal.json (+20 lines), and migrations.js (+11 lines).


Verification

Manual runtime verification did not run because this level adds storage without production Worker composition or an alarm handler.

Visual Changes

Visual Changes: N/A

Reviewer Notes

Human steps

  • before merge — After the section passes its completion gate, merge the stack from the lowest level upward.
  • No additional setup, secret, or manual migration step is required for this level.

Scope

  • Repository: Kilo-Org/cloud.
  • Worktree: /Users/igor/Projects/.worktrees/shared-agent-harness-3bb0.
  • Level 10 only: shared-agent-harness-3bb0-s9 to shared-agent-harness-3bb0-s10.
  • The production scheduler, synchronization, tool dispatch, Worker composition, and alarm handler remain later levels.
  • This change does not establish live end-to-end recovery, deployed Worker readiness, or complete runtime composition.

Notes

No manual runtime verification ran for this level. Full backend, browser, iOS, and Android verification remains required on the completed stack tip.

The focused SQLite suite passed 39 real Worker tests. Production Worker composition and the alarm handler remain later stack levels.

Stacked PRs — merge bottom to top. Each level shows only its own diff.

Runtime verification (E2E, user advocacy, simplify) runs on the tip PR over every level.
Every level keeps its own checks, its own bot review, and its own threads; each one is answered on its own PR.
Each level is its own deliverable: it builds and passes its own checks alone.
A finding on a level is repaired on that level, then carried upward with stack.sh forward.

  1. shared-agent-harness-3bb0chore(agent-harness): register workspaces and enforce CI boundaries #5632
  2. shared-agent-harness-3bb0-s2feat(agent-harness): define portable domain and snapshots #5637
  3. shared-agent-harness-3bb0-s3feat(agent-harness): define commands tools and permission policy #5639
  4. shared-agent-harness-3bb0-s4feat(agent-harness): share client state and cursor recovery #5643
  5. shared-agent-harness-3bb0-s5feat(agent-harness): persist command intents and execution receipts #5647
  6. shared-agent-harness-3bb0-s6feat(db): add harness ingress grants and retirement fences #5655
  7. shared-agent-harness-3bb0-s7feat(agent-harness): deliver legacy history and project durable text #5659
  8. shared-agent-harness-3bb0-s8feat(agent-harness): authorize durable grants and registered clients #5662
  9. shared-agent-harness-3bb0-s9feat(agent-harness): fence retirement and retry payload cleanup #5667
  10. shared-agent-harness-3bb0-s10feat(agent-harness): persist authoritative state in SQLite #5675 ← this PR
  11. shared-agent-harness-3bb0-s11feat(agent-harness): admit durable runs and revisioned commands #5678 (tip)

@kilo-code-bot

kilo-code-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (16 files)
  • services/agent-harness/drizzle.config.ts
  • services/agent-harness/drizzle/0000_authoritative_store.sql
  • services/agent-harness/drizzle/0001_projection_work.sql
  • services/agent-harness/drizzle/meta/0000_snapshot.json
  • services/agent-harness/drizzle/meta/0001_snapshot.json
  • services/agent-harness/drizzle/meta/_journal.json
  • services/agent-harness/drizzle/migrations.d.ts
  • services/agent-harness/drizzle/migrations.js
  • services/agent-harness/src/db/records.ts
  • services/agent-harness/src/db/sqlite-schema.ts
  • services/agent-harness/src/db/store.test.ts
  • services/agent-harness/src/db/store.ts
  • services/agent-harness/src/db/test-env.d.ts
  • services/agent-harness/src/db/test-worker.ts
  • services/agent-harness/src/db/wake.ts
  • services/agent-harness/vitest.config.ts

Reviewed by grok-4.6 · Input: 281.6K · Output: 28.4K · Cached: 715.4K

Review guidance: REVIEW.md from base branch shared-agent-harness-3bb0-s9

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