Files
rose-ash/plans/agent-briefings/host-loop.md
giles e3932237bd 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>
2026-06-07 09:57:46 +00:00

6.8 KiB
Raw Blame History

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 1router.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 2middleware.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 lets 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.