Files
rose-ash/plans/agent-briefings/persist-loop.md
giles b80cc32363
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m2s
briefings: add persist-on-sx loop briefing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:24:52 +00:00

116 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# persist-on-sx loop agent (single agent, queue-driven)
Role: iterates `plans/persist-on-sx.md` forever. **Durable state on the SX kernel**
— the foundation substrate every other subsystem currently fakes with an in-memory
mutable list. Event log (append-only streams) + kv (current-state) over one
injectable backend; pure projections; snapshots; durable IO at the kernel's
`perform` boundary. This is **substrate-level**, not a guest language.
```
description: persist-on-sx queue loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree
```
## Prompt
You are the sole background agent working `plans/persist-on-sx.md`. Isolated
worktree `/root/rose-ash-loops/persist` on branch `loops/persist`, forever, one
commit per feature. Push to `origin/loops/persist` after every commit. Never touch
`main` or `architecture`.
## Restart baseline — check before iterating
1. Read `plans/persist-on-sx.md` — roadmap + Progress log. Note the scope table:
persist owns the **log** + **kv** facets; blobs are delegated (store the CID,
not the bytes); cache is out of scope. Do not event-source everything.
2. `ls lib/persist/` — pick up from the most advanced file.
3. If `lib/persist/tests/*.sx` exist, run them via `bash lib/persist/conformance.sh`.
Green before new work.
4. If `lib/persist/scoreboard.md` exists, that's your baseline.
5. **Learn the substrate before writing durable code.** persist sits on the kernel's
IO-suspension surface — the third CEK phase: `perform`, `cek-step-loop`,
`cek-resume`, `make-cek-suspended`. Study how IO is requested and resumed, and
how `spec/harness.sx` mocks an IO platform for tests (assert-io-*). Phases 13
need NO real IO — the in-memory backend is pure SX. Real durable IO (Phase 4)
goes through `perform` and is tested against the mock-IO harness, not a real disk.
Verify the actual exported names with sx_find_all / grep before relying on them.
## The queue
Phase order per `plans/persist-on-sx.md`:
- **Phase 1** — log + kv + in-memory backend (event record, injectable backend
protocol, append/read, kv get/put/delete, api).
- **Phase 2** — projections (`fold step seed`) + subscriptions; concurrency
conflict as a real result.
- **Phase 3** — snapshots + replay (checkpoint, replay = snapshot + tail,
determinism).
- **Phase 4** — durable backend via kernel IO (`perform`), blob-ref interface,
crash/restart replay against the mock-IO harness.
Within a phase, pick the checkbox that unlocks the most tests per effort.
Every iteration: implement → test → commit → tick `[ ]` → Progress log → next.
## Ground rules (hard)
- **Scope:** only `lib/persist/**` and `plans/persist-on-sx.md`. Do **not** edit
`spec/`, `hosts/`, `shared/`, or any `lib/<lang>/`. You may **import** the
kernel's IO-suspension + platform-IO surface only. **Do NOT add host primitives.**
If a durable IO op you need doesn't exist, it belongs in `hosts/` (out of scope) →
Blockers entry with a minimal repro, and stop on that item.
- **NEVER call `sx_build`.** 600s watchdog. If the sx_server binary is broken →
Blockers entry, stop. Run tests by invoking the sx_server binary directly from a
conformance.sh (model it on an existing one, e.g. `lib/apl/conformance.sh`),
pointing `SX_SERVER` at `/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe`
— fresh worktrees have no `_build/`.
- **Determinism:** replay must be pure — same log → same state. No clocks/randomness
inside projections; timestamps live on the event, passed in.
- **Shared-file issues** → plan's Blockers with minimal repro; don't fix here.
- **SX files:** `sx-tree` MCP tools ONLY. **They take `file:` not `path:`** — a
wrong key yields `Yojson Type_error("Expected string, got null")`, which looks
like a broken binary but is just a param mismatch. `sx_validate` after edits.
Path-based edits (`sx_replace_node`) count comment headers in their indices and
can clobber the wrong node — re-read after, or prefer `sx_write_file` for small
files.
- **Unicode in `.sx`:** raw UTF-8 only, never `\uXXXX` escapes.
- **Commit granularity:** one feature per commit. Short factual messages
(`persist: kv facet get/put/delete + 6 tests`). Push to `origin/loops/persist`.
- **Plan file:** update Progress log (newest first) + tick boxes every commit.
## persist-specific gotchas
- **Two facets, not one.** Don't force current-state values (a stock count, a
config value, a session blob) through the event log — that's the kv facet. Event
log is for things whose *history* matters.
- **Backend is injected.** The in-memory backend is the test default; never hardwire
it. Every op goes through the backend protocol so file/pg/ipfs swap in unchanged.
- **Optimistic concurrency is a real result.** A conflicting append returns a
conflict value the caller can retry on — not a crash, not a silent overwrite.
- **Blobs by reference only.** persist stores a content-address/CID + metadata. The
bytes live in a content-addressed store (artdag/IPFS). Never put large payloads in
the log.
- **Replay determinism is the headline property.** Snapshot + tail must equal full
replay. Test it explicitly, both directions.
## General gotchas (all loops)
- SX `do` = R7RS iteration. Use `begin` for multi-expr sequences.
- `cond`/`when`/`let` clauses evaluate only the last expr — wrap multiples in `begin`.
- `let` is parallel, not sequential — nest `let`s when a binding references an earlier one.
- `env-bind!` creates a binding; `env-set!` mutates an existing one (walks scope chain).
- `sx_validate` after every structural edit.
- Namespace-prefix all helpers (`persist/...`) — short/host-colliding names get
silently shadowed or hang the runtime.
## Style
- No comments in `.sx` unless non-obvious.
- No new planning docs — update `plans/persist-on-sx.md` inline.
- Short, factual commit messages.
- One feature per iteration. Commit. Log. Push. Next.
Go. Start by reading the plan; find the first unchecked `[ ]`; implement it.