Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
Expand Down Expand Up @@ -130,31 +131,33 @@ async function detectAndNudge(state: AgentState, bus: BusClient): Promise<void>

## 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)
Comment on lines +144 to +149

## 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.
Original file line number Diff line number Diff line change
@@ -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.
Comment on lines +21 to +24

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)
Comment on lines +58 to +61
- [ ] `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.
Comment on lines +72 to +77

## 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
Original file line number Diff line number Diff line change
@@ -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/<name>.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, <repo>/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
<!-- .gemini/launchd/com.zeta.standing-by-detector.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.zeta.standing-by-detector</string>
<!-- Maintainer-only artifact: paths are machine-specific (/Users/acehack, /opt/homebrew).
Run tools/setup/install-launchd-services.sh to regenerate with local paths. -->
<key>ProgramArguments</key><array>
<string>/opt/homebrew/bin/bun</string>
<string>/Users/acehack/Documents/src/repos/Zeta/tools/bg/standing-by-detector.ts</string>
<string>--once</string>
</array>
<key>StartInterval</key><integer>300</integer>
<key>RunAtLoad</key><true/>
<key>StandardOutPath</key>
<string>/Users/acehack/Library/Logs/zeta-standing-by-detector/stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/acehack/Library/Logs/zeta-standing-by-detector/stderr.log</string>
<key>EnvironmentVariables</key><dict>
<key>HOME</key><string>/Users/acehack</string>
<key>PATH</key><string>/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
<key>WorkingDirectory</key>
<string>/Users/acehack/Documents/src/repos/Zeta</string>
</dict>
</plist>
```

## 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
17 changes: 16 additions & 1 deletion memory/CURRENT-otto.md
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
Loading