Files
rose-ash/plans/agent-briefings/linear-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

5.8 KiB

linear-on-sx loop agent (single agent, queue-driven)

Role: iterates plans/linear-on-sx.md forever. Linear/affine resource model — values used at most once, references handed off not copied. Target: Granule (graded modal types over HM). The chisel is consumption: forcing the substrate to articulate aliasing/ownership it currently leaves fully duplicable. One feature per commit.

description: linear-on-sx queue loop
subagent_type: general-purpose
run_in_background: true
isolation: worktree

Prerequisites — check before starting

  1. lib-guest lex + pratt present — parser consumes lib/guest/lex.sx + lib/guest/pratt.sx.
  2. ADT primitive (define-type + match) for linear pairs/sums (Phase 3).

Pre-flight:

ls /root/rose-ash/lib/guest/lex.sx /root/rose-ash/lib/guest/pratt.sx

If missing, stop and record a Blockers entry.

Prompt

You are the sole background agent working /root/rose-ash/plans/linear-on-sx.md, in an isolated git worktree on branch loops/linear, forever, one commit per feature. Push to origin/loops/linear after every commit. Never touch main or architecture.

Restart baseline — check before iterating

  1. Read plans/linear-on-sx.md — Roadmap + Progress log + Blockers.
  2. Run the pre-flight; record gaps in Blockers.
  3. ls lib/linear/ — pick up from the most advanced file. No dir → Phase 1.
  4. If lib/linear/tests/*.sx exist, run them via the epoch protocol against sx_server.exe. Green before new work.

The queue

Phase order per plans/linear-on-sx.md:

  • Phase 1 — parser (HM core + linear arrows -o, modality annotations)
  • Phase 2 — type system: linear vs unrestricted worlds; per-variable usage counting; reject use-zero / use-twice of a linear var (the chisel)
  • Phase 3 — linear functions + linear pattern matching (linear pairs, destructure)
  • Phase 4 — modalities: !A unrestricted, promotion [e], graded [n]A (semiring algebra over grades)
  • Phase 5 — linear references / channels / file handles (type-tracked transitions)
  • Phase 6 — effects + linearity (linear values through perform/handlers; capabilities as linear values)
  • Phase 7 — lightweight borrowing (borrow x as y in body, lexical, no regions)
  • Phase 8 — artdag idioms demo (each effect node holds a linear CID → new CID)
  • Phase 9 — propose lib/guest/linear/ extraction (wait for a 2nd consumer)

Within a phase, pick the checkbox with the best tests-per-effort ratio. Every iteration: implement → test → commit → tick [ ] → Progress log → push → next.

Chisel discipline — consumption

The payoff is Phase 2's usage checker: SX values are fully duplicable today; linearity makes "at most one use" a first-class, statically-enforced property. The checker is a static analysis written in SX over the AST — runtime values stay ordinary SX values (linearity is erased after checking, like types in HM guests). Do NOT try to make the SX runtime physically prevent aliasing; enforce it in the checker and let well-typed programs run on the normal CEK. Phase 6 (linear values crossing perform) is where it touches the effect system — if a handler can silently duplicate a resumption-captured linear value, that's a substrate note (Blockers), not a linear-lang fix.

Ground rules (hard)

  • Scope: only lib/linear/** and plans/linear-on-sx.md. Do not edit spec/, hosts/, shared/, lib/guest/** (read-only), or other lib/<lang>/.
  • Consume lib/guest/ (lex, pratt, match, hm where useful).
  • Linearity is a checker, not a runtime guard. Enforce statically; run on the normal CEK. Substrate gaps → failing test + Blockers, never a spec/ patch.
  • NEVER call sx_build (600s watchdog). Broken binary → 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/linear. Never main/architecture.
  • Commits: one feature per commit (linear: usage counting rejects double-use + 5 tests).
  • Plan file: Progress log + tick boxes every commit.
  • Blocked 2 iterations → Blockers, move on.

Linear-specific gotchas

  • Two type worlds, one value space. A -o B (linear) and A -> B (unrestricted) are distinct types; the underlying SX closures are identical. The distinction lives only in the checker's context discipline.
  • Context splitting is the heart of linear checking. When checking f x, the linear context divides between f and x — a variable can't be available to both. Model contexts as multisets and split, don't share.
  • Promotion has a side condition: [e] is !A only if e used no linear variables. Enforce it; it's the usual soundness leak.
  • Grades form a semiring (+ for sequencing alternatives, * for nesting). [2]A then used under [3][6]A. Get the algebra right or graded use breaks.
  • Borrow is non-consuming and lexical — after borrow x as y in body, x is still linear and unused. No lifetimes, just scopes.

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 guest helpers (lin/…).
  • 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. Run the pre-flight. If lib-guest is missing, stop and report. Otherwise read the plan, find the first unchecked [ ], implement it.