Skip to content

chore(b-0502): launchd plist for backlog-ready-notifier (B-0441 slice 6)#3221

Merged
AceHack merged 1 commit into
mainfrom
otto/b0502-launchd-plist-backlog-ready-notifier-2026-05-14
May 14, 2026
Merged

chore(b-0502): launchd plist for backlog-ready-notifier (B-0441 slice 6)#3221
AceHack merged 1 commit into
mainfrom
otto/b0502-launchd-plist-backlog-ready-notifier-2026-05-14

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 14, 2026

Summary

Closes B-0441 acceptance #2 ("Runs under existing launchd / cron infrastructure") for backlog-ready-notifier.ts. Atomic XS slice from B-0502.

Changes

  • .gemini/launchd/com.zeta.backlog-ready-notifier.plist (new) — copy-adapted from com.zeta.missed-substrate-detector.plist:
    • Label: com.zeta.backlog-ready-notifier
    • StartInterval: 600 (10 min — matches DEFAULT_CONFIG.pollIntervalMin)
    • ProgramArguments: [bun, .../tools/bg/backlog-ready-notifier.ts, --once]
    • Log paths under ~/Library/Logs/zeta-backlog-ready-notifier/
    • Same maintainer-note re machine-specific paths (audit-aware; flagged by audit-machine-specific-content.ts alongside sibling plists, as expected — plist files are the canonical home for machine-specific paths)
  • docs/AUTONOMOUS-LOOP.md §Related artifacts — bumped from "one launchd-registered" to "two launchd-registered"; remaining gap calls out B-0497 (standing-by-detector) and B-0442 slice 5+ (audit-duplicate-row-ids); adds work-assignment + B-0460 subscriber-handler note per B-0502 AC.
  • tools/bg/README.md §Current services — slice status 1+2+4 live1+2+4+6 live (slice 3 pending B-0500). Slice 3 (queue-state guard, B-0500) has not yet merged, so it stays out of the live set.
  • docs/backlog/P1/B-0441-...md — AC Round 26 — rename tail, §18 memory clarification, three dispatches #2 checkbox ticked with pointer to the new plist.
  • docs/backlog/P1/B-0502-...md — status: openin-progress (closes when this PR merges).

Verification

  • Plist parses (PlistBuddy -c \"Print :Label\" returns com.zeta.backlog-ready-notifier; StartInterval=600; ProgramArguments resolves correctly)
  • npx markdownlint-cli2 on all changed docs exits 0
  • No conflict markers, no empty dirs
  • bun tools/bg/backlog-ready-notifier.ts --once exits 0 (confirmed at start of tick: 233 ready candidates, 3 envelopes published)

Why XS effort

Copy-adapt + 3 doc edits. Per B-0502 row.

Sibling

B-0497 — same pattern for standing-by-detector.ts. Can merge in any order.

Branch-contamination footnote

This commit went through an untangle: between git checkout -b otto/b0502-... and git commit, another Otto process in the same repo checked out a different branch (shard/tick-2018Z-39-candidate-triage-otto-cli-2026-05-14), moving HEAD invisibly. The contaminated branch was reset back to its pre-contamination tip (5bd5697); the commit was cherry-picked to this branch from there. This is the exact pattern B-0519 RCA catalogued. The ZETA_EXPECTED_BRANCH hook didn't fire because env vars don't reliably persist across separate Bash-tool calls — worth a separate row.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Closes B-0441 acceptance #2 ("Runs under existing launchd / cron infrastructure")
for backlog-ready-notifier.ts.

- New plist .gemini/launchd/com.zeta.backlog-ready-notifier.plist
  copy-adapted from missed-substrate-detector.plist:
  - Label: com.zeta.backlog-ready-notifier
  - StartInterval: 600 (10min — matches DEFAULT_CONFIG.pollIntervalMin)
  - Log paths under ~/Library/Logs/zeta-backlog-ready-notifier/
  - Same maintainer-note re machine-specific paths (audit-aware)
- AUTONOMOUS-LOOP.md "Related artifacts" updated to list two
  launchd-registered services (was: one), call out B-0497 for
  standing-by-detector slice 6, add work-assignment + B-0460
  subscriber-handler note.
- tools/bg/README.md slice-status column updated from "1+2+4 live"
  to "1+2+4+6 live (slice 3 pending B-0500)" — B-0500 not yet
  merged so slice 3 stays out of the live set.
- B-0441 AC #2 ticked with pointer to the new plist.
- B-0502 row status: open -> in-progress.

Sibling B-0497 will land the same pattern for standing-by-detector.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 14, 2026 20:23
@AceHack AceHack enabled auto-merge (squash) May 14, 2026 20:23
@AceHack AceHack merged commit eb81404 into main May 14, 2026
29 of 30 checks passed
@AceHack AceHack deleted the otto/b0502-launchd-plist-backlog-ready-notifier-2026-05-14 branch May 14, 2026 20:27
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new macOS launchd plist to run tools/bg/backlog-ready-notifier.ts --once on an interval, and updates the relevant operational/backlog documentation to reflect that the notifier is now launchd-registered.

Changes:

  • Add .gemini/launchd/com.zeta.backlog-ready-notifier.plist for scheduled backlog-ready-notifier execution via launchd.
  • Update docs/AUTONOMOUS-LOOP.md and tools/bg/README.md to reflect the new launchd-registered service and its bus topic relationship.
  • Tick B-0441 AC #2 and advance the B-0502 row metadata.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
.gemini/launchd/com.zeta.backlog-ready-notifier.plist New launchd plist to run backlog-ready-notifier.ts --once every 10 minutes with per-service logs.
docs/AUTONOMOUS-LOOP.md Documents that backlog-ready-notifier is now launchd-registered and references the work-assignment subscriber row.
tools/bg/README.md Updates the service status table to include slice 6 and note slice 3 as pending B-0500.
docs/backlog/P1/B-0441-backlog-row-ready-to-grind-notifier-background-service-2026-05-13.md Ticks AC #2 with a pointer to the new plist.
docs/backlog/P1/B-0502-b0441-slice-6-launchd-plist-autonomous-loop-docs-2026-05-14.md Marks the slice row as in-progress in frontmatter.

id: B-0502
priority: P1
status: open
status: in-progress
<dict>
<key>Label</key><string>com.zeta.backlog-ready-notifier</string>
<!-- Maintainer-only artifact: paths are machine-specific (/Users/acehack, /opt/homebrew).
Run tools/setup/install-launchd-services.sh to regenerate with local paths. -->
Comment thread tools/bg/README.md
|---------|------|--------------|------------------|-----------|
| Standing-by detector | `standing-by-detector.ts` | 1+2+3+4 live | commit-history (HEAD) + PR-activity (repo) via `gh`/`git` | `infinite-backlog-nudge` |
| Backlog-ready notifier | `backlog-ready-notifier.ts` | 1+2+4 live | backlog-row scan (status + deps satisfied) | `work-assignment` |
| Backlog-ready notifier | `backlog-ready-notifier.ts` | 1+2+4+6 live (slice 3 pending B-0500) | backlog-row scan (status + deps satisfied) | `work-assignment` |
AceHack added a commit that referenced this pull request May 14, 2026
…ngle field-test (#3222)

* shard(tick): 2010Z — B-0502 launchd plist for backlog-ready-notifier + branch-contamination untangle

Tick output:
- PR #3221 (chore(b-0502)): new .gemini/launchd/com.zeta.backlog-ready-notifier.plist
  + AUTONOMOUS-LOOP.md + tools/bg/README.md + B-0441/B-0502 row updates. Closes
  B-0441 AC #2 ("Runs under existing launchd / cron infrastructure"). Auto-merge armed.
- This shard.

Branch-state contamination caught + untangled mid-tick:
- Local main had orphan 1856Z shard (9fa74ac) — work already on main via #3187. Reset.
- During B-0502 work, my commit landed on a different Otto's branch (the exact B-0519
  pattern). Untangled via reset + cherry-pick to the correct otto/b0502-... branch.
- ZETA_EXPECTED_BRANCH hook didn't catch the wrong-branch commit (env-var didn't
  persist across separate Bash-tool calls). Worth a follow-up row.

Substrate-or-it-didn't-happen check:
- PR #3221 = B-0502 substrate (will be on main when CI clears)
- This shard = the tick record (substrate-honest visibility of the contamination
  untangle so future-Otto sees the field-test result)

Cron sentinel 12fb713e armed at session start; one entry, recurring.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(tick): MD032 markdownlint — add blank lines around lists in 2010Z shard

Two MD032/blanks-around-lists violations: prose headers before bullet
and numbered lists lacked the required blank separator.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 14, 2026
…/B-0518/B-0519) (#3227)

Tick output:
- PR #3226 (chore(backlog) regen) — fixes the non-required `check
  docs/BACKLOG.md generated-index drift` warning that #3221 surfaced.
  Three on-disk rows (B-0517/B-0518/B-0519) were missing from the
  auto-generated index. Pure regen; no per-row file changes.
- This shard.

Prior-tick PRs:
- #3221 (chore(b-0502) launchd plist) — MERGED as eb81404.
- #3222 (shard 2010Z) — still wait-ci, autoMerge armed.

Branch-state contamination this tick — 2 incidents, both worked around:
- After my push, gh pr create said "not on any branch" — HEAD detached
  at origin/main (parallel Otto's checkout). Fixed: re-checkout my branch.
- Second gh pr create: HEAD now on fix/b-0518-sharpen-... (different Otto's
  branch). Fixed: gh pr create --head <my-branch> explicit flag.

New substrate-honest defenses for multi-Otto-one-checkout topology:
- git branch --show-current immediately before git commit (primary catch)
- gh pr create --head <branch> explicit flag (prevents poisoned current-branch)

Cron sentinel 12fb713e armed; recurring.

Co-authored-by: Claude <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@AceHack AceHack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Antigravity check: Lior clear. Atomic slice confirmed. No drift detected.

AceHack added a commit that referenced this pull request May 14, 2026
…e-specific-content audit (#3239)

* chore(hygiene): exclude .gemini/{launchd,service}/*.plist from machine-specific-content audit

Plist files under .gemini/launchd/ and .gemini/service/ are the CANONICAL
home for machine-specific paths by design. Each carries a maintainer-note
comment explaining the paths must be regenerated per-machine before
`launchctl load`. They are maintainer-only artifacts, not portable
substrate.

Before this change: audit flagged 4 plist files as gaps:
- .gemini/launchd/com.zeta.backlog-ready-notifier.plist (just landed
  via #3221)
- .gemini/launchd/com.zeta.lior-loop.plist
- .gemini/launchd/com.zeta.missed-substrate-detector.plist
- .gemini/service/com.lucent.zeta.lior.plist

Each is a false-positive — flagging them creates ongoing audit noise
without surfacing any actionable gap. Real gaps (e.g.,
tools/hygiene/audit-ci-cache-paths.ts:/home/<name>/, SKILL.md and
memory files with C:\Users\<name>) continue to be flagged.

Before: 50 gaps reported. After: 46 gaps reported. Exact delta = the 4
plist files; no other findings affected.

The exclusion adds `\.gemini\/(launchd|service)\/.*\.plist` to the
EXCLUDE_RE regex + a docstring entry explaining the rationale (so future
contributors understand why these are excluded; cargo-culted exclusion
without rationale is its own technical-debt class).

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(pr3239): tighten plist EXCLUDE_RE regex per Copilot review

Copilot caught: the new `.gemini/(launchd|service)/.*\.plist` branch
wasn't end-anchored. EXCLUDE_RE uses `.test()` (substring match against
prefix-anchored regex), so `foo.plist.bak` or `foo.plist.md` would match
`.*\.plist` and be over-excluded.

Tightened to `\.gemini\/(launchd|service)\/[^/]+\.plist$`:
- `[^/]+` — filename has no slashes (no subdir traversal)
- `\.plist$` — end-anchored (true plist extension, not substring)

Property tests (8/8 pass):
- `.gemini/launchd/com.zeta.foo.plist` → excluded ✓
- `.gemini/service/bar.plist` → excluded ✓
- `.gemini/launchd/foo.plist.bak` → NOT excluded ✓ (Copilot's concern)
- `.gemini/launchd/foo.plist.md` → NOT excluded ✓ (Copilot's concern)
- `.gemini/launchd/sub/dir/foo.plist` → NOT excluded ✓
- `.gemini/other/foo.plist` → NOT excluded ✓
- Existing exclusions (hygiene-history, ROUND-HISTORY) → still excluded ✓

Audit total unchanged at 46 gaps — all 4 real plist files still excluded.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants