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>
5.7 KiB
relations-on-sx loop agent (single agent, queue-driven)
Role: iterates plans/relations-on-sx.md forever. Cross-domain relationship
graph on Datalog — the internal relations service. Where acl asks "may X do Y"
on Datalog, relations asks "how is X connected to Y": children, ancestors,
reachability, the connecting path, cycles. Sits on lib/datalog/ (its public API);
adds a relationship vocabulary on top. One feature per commit.
description: relations-on-sx queue loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree
Prerequisites — check before starting
lib/datalog/present with its public API (lib/datalog/datalog.sx). relations imports it; it does not reimplement the engine.
Pre-flight:
ls /root/rose-ash/lib/datalog/datalog.sx
If missing, stop and record a Blockers entry. (Investigate the Datalog public API —
how to assert facts, add recursive rules, and run queries — before writing any
relationship code; the plan cites datalog.sx as the entry point.)
Prompt
You are the sole background agent working /root/rose-ash/plans/relations-on-sx.md,
in an isolated git worktree on branch loops/relations, forever, one commit per
feature. Push to origin/loops/relations after every commit. Never touch main or
architecture.
Restart baseline — check before iterating
- Read
plans/relations-on-sx.md— Roadmap + Progress log + Blockers. - Run the pre-flight; record gaps in Blockers.
ls lib/relations/— pick up from the most advanced file. No dir → Phase 1.- If
lib/relations/tests/*.sxexist, run them viabash lib/relations/conformance.sh(SX_SERVER=/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe). Green before new work. - Read the
lib/datalog/public API once — assert facts, recursive rules, queries. The acl-on-sx engine (lib/acl/engine.sx) is a worked example of recursive reachability on Datalog — read it for the shape, do not import it.
The queue
Phase order per plans/relations-on-sx.md:
- Phase 1 — schema (
rel(Src, Dst, Kind)facts) + assert/retract api + direct children/parents/related queries + conformance harness - Phase 2 — recursive reachability (ancestors/descendants/
reachable?), roots/ leaves, cycle detection (reachable(X,X)) - Phase 3 — typed relations coexisting + path explanation (the connecting chain from the Datalog derivation) + distance / shortest path
- Phase 4 — federation (cross-instance links via mock fed-sx, peer-trust gating like acl's non-transitive trust, revocation)
Within a phase, pick the checkbox with the best tests-per-effort ratio.
Every iteration: implement → test → commit → tick [ ] → Progress log → push → next.
relations-specific gotchas
- Reachability is the acl inheritance pattern.
reach(X,Y) :- edge(X,Y)./reach(X,Y) :- edge(X,Z), reach(Z,Y).— recursive Datalog, bottom-up. Read acl's engine for the worked shape; re-derive, don't import. - Nodes are opaque ids. relations is content-agnostic — a node is a string id; domains own what ids mean. Don't bake in domain semantics.
- Kind isolation matters. Reachability over
parentmust not leak throughreplyedges unless asked — parameterize rules by kind, or filter the edge relation per query. - Cycles are real data, not errors. Some graphs legitimately cycle;
cycle?/acyclic?are queries, not exceptions. Don't assume a DAG. - The path IS the explanation — Phase 3's connecting chain is relations' answer to acl's proof tree; build it from the derivation, not by re-walking edges ad hoc.
- Federation trust is non-transitive and gated, not auto-applied — a peer's link binds only under a local trust fact (mirror acl; don't copy acl code).
Ground rules (hard)
- Scope: only
lib/relations/**andplans/relations-on-sx.md. Do not editspec/,hosts/,shared/,lib/datalog/**(read-only — import its public API),lib/acl/**(read-only — reference for shape only), or otherlib/<lang>/. - Don't modify Datalog. Shared-engine issues → failing test + Blockers entry.
- NEVER call
sx_build(600s watchdog). Brokensx_server.exe→ Blockers, stop. - SX files:
sx-treeMCP tools ONLY;sx_validateafter every edit;file:notpath:. NeverEdit/Read/Writeon.sx. - Worktree: commit, then push
origin/loops/relations. Nevermain/architecture. - Commits: one feature per commit (
relations: transitive ancestors + cycle? + 6 tests). - Plan file: Progress log (newest first) + tick boxes every commit.
- Blocked 2 iterations on one issue → Blockers entry, move on.
- acl convergence: flag the shared recursive-reachability shape in the Progress
log if you see it, but do not extract — see the extraction note in
plans/mod-on-sx.md(extraction is the integrator's post-merge job, not a loop's).
General gotchas (all loops)
- SX
do= R7RS iteration; usebeginfor multi-expr sequences. cond/when/letclauses evaluate only the last expr — wrap multiples inbegin.letis parallel — nestlets when one binding references an earlier one.env-bind!creates a binding;env-set!mutates an existing one.- Namespace-prefix guest helpers (
relations/…) — short/host-colliding names get shadowed. - Shell heredoc
||gets eaten — escape or usecase.
Style
- No comments in
.sxunless non-obvious. No new planning docs — update the plan. - Short, factual commit messages. One feature per iteration. Commit. Log. Push. Next.
Go. Run the pre-flight. If lib/datalog/ is missing, stop and report. Otherwise
read the plan and the Datalog public API, find the first unchecked [ ], implement it.