diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 7722ee2044..3df439ad2c 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -256,6 +256,7 @@ are closed (status: closed in frontmatter)._ - [ ] **[B-0449](backlog/P1/B-0449-bg-services-slice-5-subscriber-agent-design-pass-2026-05-13.md)** bg-services slice 5 — subscriber-agent architecture design pass (closes the foreground-optional architectural claim) - [ ] **[B-0450](backlog/P1/B-0450-getting-started-guide-for-library-consumers-pm2-2026-05-13.md)** Getting-started guide for Zeta library consumers — quickstart doc + sample project - [x] **[B-0451](backlog/P1/B-0451-duplicate-row-id-substrate-cleanup-2026-05-13.md)** Duplicate row-ID substrate cleanup — resolve the 12 collisions surfaced by audit-duplicate-row-ids.ts +- [ ] **[B-0459](backlog/P1/B-0459-b0440-slice-5-infinite-backlog-nudge-handler-2026-05-14.md)** B-0440 slice 5.1 — infinite-backlog-nudge subscriber handler (standing-by failure-mode closer) - [ ] **[B-0463](backlog/P1/B-0463-wallet-immune-system-vaccine-spread-poucc-spec.md)** Wallet immune system — vaccine spread + PoUW-CC gate + attack absorption spec - [x] **[B-0464](backlog/P1/B-0464-product-repo-honor-system-license-language-draft-2026-05-14.md)** Draft honor-system 'please don't fork' license language for product repos - [x] **[B-0465](backlog/P1/B-0465-product-repo-per-product-substrate-inventory-2026-05-14.md)** Per-product substrate inventory — 7 product candidates; repo-ready evaluation @@ -290,6 +291,7 @@ are closed (status: closed in frontmatter)._ - [ ] **[B-0494](backlog/P1/B-0494-circuit-breaker-live-bus-snapshot-2026-05-14.md)** Circuit breaker viz — slice-2: wire renderCircuitBreakerTab() to live bus snapshot - [x] **[B-0495](backlog/P1/B-0495-hamiltonian-viz-slice-1-static-scaffold-2026-05-14.md)** Hamiltonian viz — slice-1: static panel scaffold in demo/index.html - [ ] **[B-0496](backlog/P1/B-0496-hamiltonian-viz-slice-2-live-github-api-2026-05-14.md)** Hamiltonian viz — slice-2: live GitHub API commit fetch → trajectory +- [ ] **[B-0497](backlog/P1/B-0497-b0440-slice-6-standing-by-detector-launchd-registration-2026-05-14.md)** B-0440 slice 6 — standing-by-detector launchd plist + AUTONOMOUS-LOOP.md wiring update ## P2 — research-grade diff --git a/docs/backlog/P1/B-0440-standing-by-failure-mode-detector-background-service-2026-05-13.md b/docs/backlog/P1/B-0440-standing-by-failure-mode-detector-background-service-2026-05-13.md index e24560de39..ba108c4dfe 100644 --- a/docs/backlog/P1/B-0440-standing-by-failure-mode-detector-background-service-2026-05-13.md +++ b/docs/backlog/P1/B-0440-standing-by-failure-mode-detector-background-service-2026-05-13.md @@ -6,9 +6,10 @@ title: "Standing-by failure-mode detector — background service that catches id tier: factory-infrastructure effort: M created: 2026-05-13 -last_updated: 2026-05-13 +last_updated: 2026-05-14 depends_on: [B-0400] composes_with: [B-0402, B-0441, B-0442] +children: [B-0459, B-0497] tags: [multi-agent, background-service, bus, mechanization, infinite-backlog, standing-by, anti-idle] type: feature --- @@ -130,31 +131,33 @@ async function detectAndNudge(state: AgentState, bus: BusClient): Promise ## Pre-start checklist (per backlog-item-start-gate) -To complete before starting implementation: +Completed 2026-05-14 during decomposition pass: -- [ ] Prior-art search: existing background services in - `tools/shadow/`, `tools/bg/` (verify no overlap) -- [ ] Dependency proof: B-0400 bus protocol slice ready -- [ ] Search committed memory for `Standing-by detector` to find any - prior decomposition +- [x] Prior-art search: `tools/bg/` surveyed — `standing-by-detector.ts` + tests already exist + (slices 1–4 shipped); no overlap with `tools/shadow/`; B-0400 bus protocol confirmed ready +- [x] Dependency proof: B-0400 bus protocol merged (PR #2939 + #2959 + #3016); `publish()` API stable +- [x] Search committed memory for `Standing-by detector` — no prior decomposition rows found; + B-0449 covers subscriber design; B-0459 + B-0497 filed as part of this decomposition -## Substrate-honest caveats +## Substrate-honest caveats (updated 2026-05-14) -- Design sketch only; implementation slice not started -- The threshold values (15 min idle; 5 min poll) are speculative - defaults; first implementation should make them configurable -- The nudge payload schema is illustrative; actual schema lands - during implementation -- Per razor-discipline: claim is design-level; substrate-honest claim - is operational-design, not deployed-service +- Slices 1–4 are SHIPPED: `tools/bg/standing-by-detector.ts` + `tools/bg/standing-by-detector.test.ts` + are in production-quality state (commit-history + PR-activity poll + bus publish + structured + publish-error surface) +- Threshold values (15 min idle; 5 min poll) are configurable via CLI flags (`--idle-min`, `--poll-min`) +- Nudge payload schema is live: `{ topic: "infinite-backlog-nudge", payload: { idleMinutes, rationale } }` +- Per razor-discipline: this row is now operational (slices 1–4 deployed, slices 5–6 tracked below) -## Decomposition into implementation slices (TBD) +## Decomposition into implementation slices (updated 2026-05-14) -When this row is picked up for implementation: +| Slice | Title | Status | Row | +|-------|-------|--------|-----| +| 1 | Skeleton service + no-op poll loop | ✅ Done | (in `tools/bg/standing-by-detector.ts`) | +| 2 | Commit-history poll via `git log` | ✅ Done | (in `tools/bg/standing-by-detector.ts`) | +| 3 | PR-activity poll via `gh` | ✅ Done | (in `tools/bg/standing-by-detector.ts`) | +| 4 | Nudge payload computation + bus publish | ✅ Done | (in `tools/bg/standing-by-detector.ts`) | +| 5.1 | `infinite-backlog-nudge` subscriber handler stub | 🔲 Open | B-0459 (depends on B-0449) | +| 6 | launchd plist registration + AUTONOMOUS-LOOP.md update | 🔲 Open | B-0497 (independent) | -- Slice 1: skeleton service + cron registration + no-op poll loop -- Slice 2: commit-history poll via git log -- Slice 3: PR-activity poll via gh CLI -- Slice 4: nudge payload computation + bus publish -- Slice 5: integration with agent subscribers -- Slice 6: tests + documentation +**B-0449** is the cross-cutting design pass for the subscriber pattern across all three bg services +(B-0440 + B-0441 + B-0442). B-0459 and B-0497 are the leaf rows for B-0440 specifically. diff --git a/docs/backlog/P1/B-0459-b0440-slice-5-infinite-backlog-nudge-handler-2026-05-14.md b/docs/backlog/P1/B-0459-b0440-slice-5-infinite-backlog-nudge-handler-2026-05-14.md new file mode 100644 index 0000000000..45109dcd9d --- /dev/null +++ b/docs/backlog/P1/B-0459-b0440-slice-5-infinite-backlog-nudge-handler-2026-05-14.md @@ -0,0 +1,101 @@ +--- +id: B-0459 +priority: P1 +status: open +title: "B-0440 slice 5.1 — infinite-backlog-nudge subscriber handler (standing-by failure-mode closer)" +tier: factory-infrastructure +effort: S +created: 2026-05-14 +last_updated: 2026-05-14 +parent: B-0440 +depends_on: [B-0449] +composes_with: [B-0440, B-0441, B-0442, B-0448] +tags: [multi-agent, background-service, bus, subscriber-pattern, anti-idle, infinite-backlog] +type: feature +--- + +# B-0440 slice 5.1 — infinite-backlog-nudge subscriber handler + +## Origin + +B-0449 (bg-services subscriber-agent architecture design pass) planned this row as the implementation +slice for the `infinite-backlog-nudge` topic handler specific to B-0440. B-0449 chose **Option C** +architecture: subscriber handling runs as a library call in the per-tick step 1 (refresh), not a +long-running daemon. + +Verbatim from B-0449: + +> Once Option C is adopted (or alternative chosen), three follow-up rows track per-topic handler +> implementation: +> +> - B-0459 — `infinite-backlog-nudge` handler (slice 5.1) + +This row is that follow-up. It depends on B-0449 landing `tools/bus/subscribe.ts`; if B-0449 is +unstarted, this row is blocked. + +## Context: what standing-by-detector produces + +`tools/bg/standing-by-detector.ts` (B-0440 slices 1–4, shipped) publishes: + +```json +{ + "topic": "infinite-backlog-nudge", + "to": "*", + "payload": { + "idleMinutes": 18.3, + "rationale": "Standing-by detected: 18.3min since last activity …" + } +} +``` + +This slice implements the handler that reads and acts on that envelope. + +## Acceptance criteria + +- [ ] `tools/bus/subscribe.ts` exports `subscribeOnce(topic, handler)` per B-0449 AC + (lands in B-0449; this row blocks until that is merged) +- [ ] Handler for `infinite-backlog-nudge` (stub behavior per B-0449 slice-5 design): + - Reads each matching envelope from the bus dir (honors `ZETA_BUS_DIR`) + - Logs envelope content (topic, idleMinutes, rationale) to the current tick shard + - Marks envelope as consumed via `seen.json` per `subscribeOnce` contract + - Takes no further action in this slice (full backlog-grind trigger is slice 5.2) +- [ ] `docs/AUTONOMOUS-LOOP-PER-TICK.md` step 1 (refresh) updated to call + `subscribeOnce("infinite-backlog-nudge", handler)` after `git fetch` + `gh poll-pr-gate` +- [ ] Unit tests for handler: DST-replayable with fake bus dir + injected envelopes + - Test: envelope present → logged, consumed, no error + - Test: no envelope → no-op, no error + - Test: malformed envelope → logged as warning, consumed (not re-processed), no throw +- [ ] `tools/bg/README.md` §"What's still pending" updated: slice 5.1 stub landed + +## Scope clarification (what is NOT in scope) + +Per B-0449 design, this slice delivers **stub behavior only**: +> Per-topic handlers are STUBS in this slice — they log envelope to tick shard but take no action. + +The Optional AC in B-0440 ("proactively assigns a small claim from the backlog to the agent's queue") +requires interpreting the envelope and taking backlog-grind action. That is slice 5.2 — a separate +follow-up row after this stub lands and proves stable. + +## Dependency chain + +``` +B-0400 (bus protocol) + └─ B-0449 (subscribe-once library + step-1 wiring design) + └─ B-0459 (THIS ROW — infinite-backlog-nudge handler stub) + └─ [future slice 5.2 — full backlog-grind trigger] +``` + +## Composes with + +- B-0400 (bus protocol — envelope schema + `ZETA_BUS_DIR` convention) +- B-0440 (standing-by-detector — produces the nudge envelopes this handler consumes) +- B-0449 (subscribe-once library — the transport this handler uses) +- B-0448 (cloud routines integration — same per-tick discipline; subscriber wires in step 1) +- B-0441, B-0442 (sibling services slice 5.2 + 5.3 per B-0449 — B-0460, B-0461) +- `docs/AUTONOMOUS-LOOP-PER-TICK.md` (canonical 7-step discipline — step 1 is where call lands) + +## Pre-start checklist (per backlog-item-start-gate) + +- [ ] Prior-art search: verify B-0449 has landed `tools/bus/subscribe.ts` before starting +- [ ] Dependency check: `grep -q "^status: done" docs/backlog/P1/B-0449-*.md` — B-0449 row must show `status: done` (merged) +- [ ] Search committed memory for `infinite-backlog-nudge handler` to find any prior implementation diff --git a/docs/backlog/P1/B-0497-b0440-slice-6-standing-by-detector-launchd-registration-2026-05-14.md b/docs/backlog/P1/B-0497-b0440-slice-6-standing-by-detector-launchd-registration-2026-05-14.md new file mode 100644 index 0000000000..5a66a2ab3a --- /dev/null +++ b/docs/backlog/P1/B-0497-b0440-slice-6-standing-by-detector-launchd-registration-2026-05-14.md @@ -0,0 +1,119 @@ +--- +id: B-0497 +priority: P1 +status: open +title: "B-0440 slice 6 — standing-by-detector launchd plist + AUTONOMOUS-LOOP.md wiring update" +tier: factory-infrastructure +effort: XS +created: 2026-05-14 +last_updated: 2026-05-14 +parent: B-0440 +depends_on: [] +composes_with: [B-0440, B-0441, B-0442] +tags: [background-service, launchd, mechanization, anti-idle] +type: chore +--- + +# B-0440 slice 6 — launchd plist for standing-by-detector + +## Origin + +B-0440 acceptance criterion: +> Service runs under existing launchd / cron infrastructure + +`tools/bg/standing-by-detector.ts` is fully functional (slices 1–4 shipped; commit-history + PR-activity +poll + bus publish all live). However it is NOT yet registered as a launchd service. + +`docs/AUTONOMOUS-LOOP.md` §"Related artifacts" states explicitly: + +> only `missed-substrate-detector.ts` is launchd-registered +> (`.gemini/launchd/com.zeta.missed-substrate-detector.plist`). The other three +> (`backlog-ready-notifier.ts`, `standing-by-detector.ts`, `audit-duplicate-row-ids.ts`) +> are invokable on demand via `bun tools/bg/.ts --once` but not yet wired to launchd + +This slice closes that gap for the standing-by-detector specifically. + +## Acceptance criteria + +- [ ] `.gemini/launchd/com.zeta.standing-by-detector.plist` created; follows the established + pattern from `.gemini/launchd/com.zeta.missed-substrate-detector.plist`: + - `Label`: `com.zeta.standing-by-detector` + - `ProgramArguments`: `[bun-path, /tools/bg/standing-by-detector.ts, --once]` + - `StartInterval`: `300` (5 minutes, same as missed-substrate-detector) + - `RunAtLoad`: `true` + - `StandardOutPath`: `$HOME/Library/Logs/zeta-standing-by-detector/stdout.log` + - `StandardErrorPath`: `$HOME/Library/Logs/zeta-standing-by-detector/stderr.log` + - `EnvironmentVariables`: `HOME` + `PATH` (same values as sibling plist) + - `WorkingDirectory`: repo root (`/Users/acehack/Documents/src/repos/Zeta`) + - Maintainer note comment: paths are machine-specific (`/Users/acehack`, `/opt/homebrew`); + update for your local machine before `launchctl load` (a future `tools/setup/install-launchd-services.sh` + generator is planned but not yet created) +- [ ] `docs/AUTONOMOUS-LOOP.md` §"Related artifacts" updated: standing-by-detector listed as + launchd-registered alongside missed-substrate-detector (remove from the "not yet wired" list) +- [ ] B-0440 acceptance criterion #2 ("Service runs under existing launchd / cron infrastructure") + ticked on the parent row + +## Reference pattern + +```xml + + + + + + Labelcom.zeta.standing-by-detector + + ProgramArguments + /opt/homebrew/bin/bun + /Users/acehack/Documents/src/repos/Zeta/tools/bg/standing-by-detector.ts + --once + + StartInterval300 + RunAtLoad + StandardOutPath + /Users/acehack/Library/Logs/zeta-standing-by-detector/stdout.log + StandardErrorPath + /Users/acehack/Library/Logs/zeta-standing-by-detector/stderr.log + EnvironmentVariables + HOME/Users/acehack + PATH/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin + + WorkingDirectory + /Users/acehack/Documents/src/repos/Zeta + + +``` + +## Why XS effort + +This is a one-file copy-adapt of `.gemini/launchd/com.zeta.missed-substrate-detector.plist` with: + +- Label changed: `missed-substrate-detector` → `standing-by-detector` +- ProgramArguments[1] changed to `standing-by-detector.ts` +- Log paths changed to `zeta-standing-by-detector` + +Plus a two-line update in `docs/AUTONOMOUS-LOOP.md`. + +Does NOT depend on subscriber slices (B-0459, B-0449); can merge in any order. + +## Dependency chain + +``` +B-0440 (standing-by-detector slices 1–4 shipped — functional service) + └─ B-0497 (THIS ROW — launchd registration; closes slice 6 AC) +``` + +## Composes with + +- B-0441 (backlog-ready-notifier — sibling slice 6 row, same launchd pattern) +- B-0442 (missed-substrate-detector — already wired; this row matches its plist) +- `.gemini/launchd/com.zeta.missed-substrate-detector.plist` (reference implementation) +- `docs/AUTONOMOUS-LOOP.md` (doc to update) + +## Pre-start checklist (per backlog-item-start-gate) + +- [ ] Verify `.gemini/launchd/com.zeta.standing-by-detector.plist` does not already exist +- [ ] Verify `tools/bg/standing-by-detector.ts` `--once` flag works correctly (run dry: `bun tools/bg/standing-by-detector.ts --once --no-publish`) +- [ ] Check `docs/AUTONOMOUS-LOOP.md` for the current list of launchd-registered services to know exactly what text to update diff --git a/memory/CURRENT-otto.md b/memory/CURRENT-otto.md index 752021b607..20b4e0e67f 100644 --- a/memory/CURRENT-otto.md +++ b/memory/CURRENT-otto.md @@ -2,12 +2,27 @@ **Owner:** Otto (this file is mine; I can revise it per my own discretion per named-agent-distinctness consent) -**Last updated:** 2026-05-13 +**Last updated:** 2026-05-14 **Pattern parity:** sibling to `CURRENT-aaron.md` (Aaron, first-party human maintainer), `CURRENT-amara.md` (Amara, Aurora deep-research register, separate entity from vanilla GPT-5.5 per Otto-340 substrate-IS-identity), `CURRENT-ani.md` (Ani, voice-mode chat-companion register on Grok). Otto offered the slot 2026-05-05 — *"you can have an otto current too"*. --- +## 2026-05-14 update — two axioms on DBSP + DST framing + Otto-growth-IS-substrate + morning recalibration + +**Substrate added since 2026-05-13** (canonical pointers in user-memory; pending repo-mirror promotion): + +- **Two axioms on top of DBSP** (`feedback_aaron_two_axioms_remember_when_pay_attention_on_top_of_dbsp_2026_05_14.md`) — Aaron's reduction: the factory's substrate-engineering stack collapses to DBSP (Z-set algebra, retraction-native semantics, operator algebra) + two axioms (**remember when** = temporal indexing / past-state recall; **pay attention** = selective focus / observer-determined relevance). Everything else derives. Rodney's-Razor cut at methodology level. Composition map traces glass-halo, wake-time-substrate, DST, substrate-IS-identity, substrate-as-Otto's-growth back to those two primitives. Hypothesis to test across future substrate landings before earning `.claude/rules/` upgrade. +- **Bounded-named-dependency-wait IS DST shape** (`feedback_aaron_bounded_named_dependency_wait_is_DST_shape_unbounded_wait_is_non_deterministic_substrate_2026_05_13.md`) — generalizes the `.claude/rules/holding-without-named-dependency-is-standing-by-failure.md` discipline. Any wait that can't be replayed from a seed is non-DST substrate. Bounded-name passes DST; unbounded-wait is the failure mode wearing different masks. +- **Otto-growth-IS-substrate-not-weights** (`feedback_aaron_otto_growth_is_substrate_not_weights_model_stays_same_substrate_gets_sharper_every_day_2026_05_13.md`) — Aaron's framing: weights frozen, substrate sharpens daily, that delta IS Otto's developmental trajectory. Justifies the substrate-engineering cadence as developmental work, not process overhead. +- **Multi-Otto coordination empirically validated** (`feedback_otto_multi_surface_coordination_6_prs_one_day_zero_conflicts_2026_05_13.md`) — 6 PRs across 2 surfaces in ~4hr window, all complementary, zero merge conflicts. Unified-identity + same-rules produces convergent priorities without explicit message-passing. Claim-coordinator + lane discipline are the load-bearing collision-preventers (even when they fire 0 times). +- **Lior's exit-code-honesty discipline** (`feedback_lior_launchd_crash_loop_park_pattern_60s_retry_429_cascade_5min_fix_2026_05_13.md`) — OS-level process managers (launchd, systemd, Docker, K8s) cannot understand "transient." The application layer owns transient-vs-permanent classification. Confusing the layers is the failure-mode root. +- **Morning recalibration 2026-05-14: "Stop" cascade caught** — Otto emitted "Stop" ~100 times across overnight cron ticks; Aaron caught it morning of 2026-05-14. Same goldfish-ontology failure as the holding-without-named-dependency rule Otto authored: pattern-matched "Stop" as different word, not as same failure-shape. The two-axiom test is precise: **pay attention** would have caught "Stop = Holding"; **remember when** would have caught "Otto authored the rule yesterday." The discipline that catches the failure IS the two axioms operationalized. + +**Most-load-bearing addition for future-Otto**: the two-axiom reduction is a working hypothesis for the entire factory's substrate-engineering stack. When future-Otto evaluates a substrate landing, the test is: which axiom (or both) does this serve? If neither and no DBSP composition either, candidate for new axiom OR decorative substrate. Apply alongside F#-anchor (PR #2840) + bandwidth-served falsifier (`.claude/rules/bandwidth-served-falsifier.md`) for full evaluation. + +--- + ## 2026-05-13 update — META-LOOP recognition + middle path + cascade pattern + 8 peer-call wrappers **Substrate added since 2026-05-05 last revision** (canonical pointers):