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>
100 lines
4.6 KiB
Markdown
100 lines
4.6 KiB
Markdown
# 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 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/**` 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.
|