Files
rose-ash/plans/agent-briefings/feed-loop.md
giles c3a0727645
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
plans: five rose-ash subsystem plans + three loop briefings
Plans for acl-on-sx (Datalog), flow-on-sx (Scheme), feed-on-sx (APL),
mod-on-sx (Prolog), search-on-sx (Haskell). Each is a 4-phase queue
sitting on its respective guest language, targeting rose-ash needs:
access control, durable workflows, activity feeds, moderation, search.
Federation extension in Phase 4 of each (plugs into fed-sx).

Briefings for the three loops we're kicking off now: acl-loop,
flow-loop, feed-loop. mod-sx and search-sx briefings will follow
once the first three have surfaced any shared infrastructure
worth extracting to lib/guest/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 15:55:39 +00:00

4.6 KiB
Raw Blame History

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

Role: iterates plans/feed-on-sx.md forever. Activity feeds on APL — timelines, notifications, fanout, ranking, all as APL array math on activity vectors. Densest possible expression of feed composition. Sits on lib/apl/ (450+/450+ tests already); adds a feed-shaped vocabulary on top.

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

Prompt

You are the sole background agent working /root/rose-ash/plans/feed-on-sx.md. Isolated worktree, forever, one commit per feature. Push to origin/loops/feed after every commit.

Restart baseline — check before iterating

  1. Read plans/feed-on-sx.md — roadmap + Progress log.
  2. ls lib/feed/ — pick up from the most advanced file.
  3. If lib/feed/tests/*.sx exist, run them via bash lib/feed/conformance.sh. Green before new work.
  4. If lib/feed/scoreboard.md exists, that's your baseline.
  5. Read lib/apl/apl.sx public API once — that's your substrate. Familiarize yourself with at least: / ⌽ ↑ ↓ ⌷ ∊ ∘.× /\ ⍋ (you will use all of these).

The queue

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

  • Phase 1 — stream model + basic ops (record schema, filter, sort, take)
  • Phase 2THE SHOWCASE: fanout via outer product. activities ∘.× followers → inbox matrix, flatten + dedupe
  • Phase 3 — aggregation + ranking (group-by, velocity, recency, top-N)
  • Phase 4 — visibility filter (acl-sx) + federation (fed-sx inbox + backfill)

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/feed/** and plans/feed-on-sx.md. Do not edit spec/, hosts/, shared/, other lib/<lang>/ dirs, lib/stdlib.sx, or lib/ root. May import from lib/apl/ only (its public API).
  • NEVER call sx_build. 600s watchdog. If sx_server binary broken → Blockers entry, stop.
  • Shared-file issues → plan's Blockers with minimal repro.
  • SX files: sx-tree MCP tools ONLY. sx_validate after edits.
  • Unicode in .sx: raw UTF-8 only, never \uXXXX escapes. APL glyphs land directly in source.
  • Worktree: commit, then push to origin/loops/feed. Never touch main or architecture.
  • Commit granularity: one feature per commit. Short factual messages (feed: outer-product fanout + dedupe by (actor,verb,object) + 9 tests).
  • Plan file: update Progress log + tick boxes every commit.

feed-specific gotchas

  • Activities are heterogeneous. Different verbs carry different shapes (:object might be page-id, post-id, user-id). Don't over-normalize — keep :tags as a flexible bag. APL operations over heterogeneous records work fine via dict lookups; only the indexed fields need uniform shape.
  • Fanout produces matrices fast. N activities × M followers → NM items. Apply filter/dedupe early, not after materialization. Use guard predicates inside the outer product where possible (compose with ∘.{a v ⊢ ...}).
  • Dedupe key isn't always (actor,verb,object). For "alice liked X" and "bob liked X" the dedupe key is (verb,object) (collapse the actors into a list). For "alice posted X" each :actor is distinct. Each verb may want its own dedupe rule; codify these in lib/feed/dedupe.sx.
  • Recency decay matters more than score precision. Use a simple half-life decay (e.g. score × 0.5^(age/window)) rather than a clever curve. Calibrate the window via tests, not theory.
  • Ranking should be deterministic on ties. Always include a tiebreaker (id, or hash). Otherwise tests will flake.
  • The ACL filter is per-viewer. A timeline is computed for a user; the same candidate stream produces different timelines for different viewers. Don't cache pre-ACL timelines.

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.
  • env-bind! creates a binding; env-set! mutates an existing one (walks scope chain).
  • sx_validate after every structural edit.
  • list? returns false on raw JS Arrays — host data must be SX-converted.

Style

  • No comments in .sx unless non-obvious.
  • No new planning docs — update plans/feed-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.