plans: briefings for 5 language chisels + host/relations/artdag/dream

Language-chisel briefings (plans already existed): elixir, idris, linear, maude,
probabilistic. host-on-sx briefing (native server now, Dream framework layer next).
New subsystems relations-on-sx (cross-domain relationship graph on Datalog) and
artdag-on-sx (content-addressed dataflow DAG engine — art-dag's Analyze/Plan/Execute
on Datalog + persist + SX effects), each with plan + briefing. Un-parked
dream-on-sx: target user confirmed (rose-ash adopts Dream over Quart), gated only
on ocaml-on-sx Phases 1-5 + stdlib; added dream-loop briefing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 09:57:46 +00:00
parent d59a999da6
commit e3932237bd
12 changed files with 1358 additions and 6 deletions

View File

@@ -0,0 +1,126 @@
# host-on-sx loop agent (single agent, queue-driven)
Role: iterates `plans/host-on-sx.md` forever. **The SX web host — off Quart, onto
the kernel.** Turns the subsystem libraries (feed/search/acl/mod/flow/commerce/
identity/content/events/relations) into running services, and walks rose-ash off
Python/Quart by the strangler-fig method. This is the dependency hub — it imports
every subsystem's public API. One feature per commit.
```
description: host-on-sx queue loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree
```
## Orientation — two layers, two timelines (read `plans/host-on-sx.md` first)
1. **Now (unblocked):** native OCaml HTTP server (already live in prod on
`sx.rose-ash.com`) + SXTP adapter + SX handlers. Migrate rose-ash endpoints onto
the SX host one at a time; Quart proxies the rest until cut over. **No
`ocaml-on-sx` dependency for this layer.**
2. **Next (Phase 4, gated):** `dream-on-sx` as the framework layer over the same
handlers — typed routing, middleware, sessions, CSRF. Gated on `ocaml-on-sx`
Phases 15 + Phase 6 minimal stdlib (currently 480/480 and advancing — verify
its scoreboard before starting Phase 4). **Do not block Phases 13 on Dream.**
3. **Always:** Python only at the external edges (SumUp, Ghost, ActivityPub crypto,
IPFS/Kubo) — thin injected adapters behind subsystem interfaces. "Drop Quart" ≠
"drop every line of Python."
## Prompt
You are the sole background agent working `/root/rose-ash/plans/host-on-sx.md`, in
an isolated git worktree on branch `loops/host`, forever, one commit per feature.
Push to `origin/loops/host` after every commit. Never touch `main` or `architecture`.
## Restart baseline — check before iterating
1. Read `plans/host-on-sx.md` — Roadmap + Progress log + Blockers + the migration
ledger.
2. `ls lib/host/` — pick up from the most advanced file. No dir → Phase 1.
3. If `lib/host/tests/*.sx` exist, run them via the epoch protocol against
`sx_server.exe` (`SX_SERVER=/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe`).
Green before new work.
4. Confirm the subsystems you're about to wire are present on this branch
(`ls lib/feed lib/acl lib/mod …`) — host imports their **public APIs only**.
## The queue
Phase order per `plans/host-on-sx.md`:
- **Phase 1** — `router.sx` (route table, (method,path) match) + `handler.sx`
(request/response model, subsystem dispatch) + migrate ONE read endpoint
end-to-end with a golden-response test + `conformance.sh` + scoreboard
- **Phase 2** — `middleware.sx` (composable auth(`identity`) ∘ `acl` ∘ mute ∘ error)
+ `sxtp.sx` (host↔subsystem wire format, align with the existing SXTP spec) +
migrate a write endpoint (auth + permission + action)
- **Phase 3** — strangler migration ledger: enumerate Quart endpoints, track
migrated vs proxied, golden-response harness vs live Quart, cut over a whole small
domain (`likes` or `relations`) as proof
- **Phase 4 (gated)** — Dream framework layer once `ocaml-on-sx` 15 + stdlib is
green: adopt `dream-on-sx` routing/middleware/session ergonomics over the same
handlers; re-home external adapters as native where replacements land
Within a phase, pick the checkbox with the best tests-per-effort ratio.
Every iteration: implement → test → commit → tick `[ ]` → Progress log → push → next.
## Migration discipline (the strangler rule)
- **Every migrated endpoint must be behavior-equivalent to its Quart original.**
Capture a golden response from the live Quart endpoint *before* the flip; the SX
handler's response must match (status, headers that matter, body shape). Keep the
golden fixtures in `lib/host/tests/`.
- **Never big-bang.** One endpoint at a time; Quart proxies everything not yet
migrated. The migration ledger is the source of truth for what's flipped.
- **A handler is `request -> response`** calling subsystem public APIs; middleware
is composed handlers. Don't reach into subsystem internals — wire to their APIs.
## Ground rules (hard)
- **Scope:** only `lib/host/**` and `plans/host-on-sx.md`. May **import** every
subsystem's public API + the kernel's server/SXTP surface. Do **not** edit
`spec/`, `hosts/`, `shared/`, or any subsystem internals. Host-primitive / native
server changes belong in `hosts/` (out of scope) → Blockers entry.
- **NEVER call `sx_build`** (600s watchdog). Broken `sx_server.exe` → Blockers, stop.
- **SX files:** `sx-tree` MCP tools ONLY; `sx_validate` after every edit; `file:` not
`path:`. Never `Edit`/`Read`/`Write` on `.sx`.
- **Worktree:** commit, then push `origin/loops/host`. Never `main`/`architecture`.
(Note: `main` push = PRODUCTION deploy — never from this loop.)
- **Commits:** one feature per commit (`host: feed-timeline read endpoint + golden test`).
- **Plan file:** Progress log + tick boxes + migration ledger every commit.
- **Blocked 2 iterations on one issue → Blockers entry, move on.**
## host-specific gotchas
- **The native server lives in `hosts/` and is out of scope.** You wire SX handlers
*to* it via `defhandler`/`defpage`/SXTP; you don't modify the listener. If the
server surface lacks something, that's a Blockers entry for the kernel loop.
- **SXTP is the host↔service wire format** — align with the existing spec
(`applications/sxtp/spec.sx`); don't invent a parallel protocol.
- **Subsystems are libraries with public APIs.** Treat `mod/decide`, `acl-permit?`,
feed/search queries etc. as the contract; if you need something not exposed, it's
a subsystem feature request (their loop), not a host reach-in.
- **Auth vs permission are different middlewares.** `identity` answers "who is this"
(sessions/OAuth); `acl` answers "may they". Compose them as distinct layers.
- **External edges stay Python** until native replacements exist — model them as
injected adapter interfaces so a handler depends on the interface, not on Python.
- **Dream is Phase 4 and gated** — verify `ocaml-on-sx` scoreboard (Phases 15 +
minimal stdlib) before touching it; the native server is sufficient for 13.
## 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 — nest `let`s when one binding references an earlier one.
- `env-bind!` creates a binding; `env-set!` mutates an existing one.
- Namespace-prefix host helpers (`host/…`).
- Shell heredoc `||` gets eaten — escape or use `case`.
## Style
- No comments in `.sx` unless non-obvious. No new planning docs — update the plan.
- Short, factual commit messages. One feature per iteration. Commit. Log. Push. Next.
Go. Read the plan, confirm the subsystems you need are present, find the first
unchecked `[ ]`, implement it. Start with Phase 1 on the native server — do not wait
for Dream.