Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
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>
4.6 KiB
4.6 KiB
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
- Read
plans/feed-on-sx.md— roadmap + Progress log. ls lib/feed/— pick up from the most advanced file.- If
lib/feed/tests/*.sxexist, run them viabash lib/feed/conformance.sh. Green before new work. - If
lib/feed/scoreboard.mdexists, that's your baseline. - Read
lib/apl/apl.sxpublic 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 2 — THE 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/**andplans/feed-on-sx.md. Do not editspec/,hosts/,shared/, otherlib/<lang>/dirs,lib/stdlib.sx, orlib/root. May import fromlib/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-treeMCP tools ONLY.sx_validateafter edits. - Unicode in
.sx: raw UTF-8 only, never\uXXXXescapes. APL glyphs land directly in source. - Worktree: commit, then push to
origin/loops/feed. Never touchmainorarchitecture. - 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
(
:objectmight be page-id, post-id, user-id). Don't over-normalize — keep:tagsas 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:actoris distinct. Each verb may want its own dedupe rule; codify these inlib/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. Usebeginfor multi-expr sequences. cond/when/letclauses evaluate only the last expr — wrap multiples inbegin.env-bind!creates a binding;env-set!mutates an existing one (walks scope chain).sx_validateafter every structural edit.list?returns false on raw JS Arrays — host data must be SX-converted.
Style
- No comments in
.sxunless non-obvious. - No new planning docs — update
plans/feed-on-sx.mdinline. - Short, factual commit messages.
- One feature per iteration. Commit. Log. Push. Next.
Go. Start by reading the plan; find the first unchecked [ ]; implement it.