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
8 changes: 4 additions & 4 deletions docs/BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ are closed (status: closed in frontmatter)._
- [x] **[B-0437](backlog/P1/B-0437-demo-ux-of-math-panel-bivector-fingerprints-2026-05-13.md)** Demo — UX-of-math panel (bivector fingerprints, partial-credit scoring)
- [ ] **[B-0440](backlog/P1/B-0440-standing-by-failure-mode-detector-background-service-2026-05-13.md)** Standing-by failure-mode detector — background service that catches idle-foreground + nudges via bus
- [ ] **[B-0441](backlog/P1/B-0441-backlog-row-ready-to-grind-notifier-background-service-2026-05-13.md)** Backlog-row-ready-to-grind notifier — background service that proactively assigns claims when agent queue empty
- [ ] **[B-0442](backlog/P1/B-0442-missed-substrate-cascade-detector-background-service-2026-05-13.md)** Missed-substrate cascade detector — background service that catches branch-vs-merged-PR drift (e.g., Otto-section-missed-PR-2980-by-3-min class)
- [x] **[B-0442](backlog/P1/B-0442-missed-substrate-cascade-detector-background-service-2026-05-13.md)** Missed-substrate cascade detector — background service that catches branch-vs-merged-PR drift (e.g., Otto-section-missed-PR-2980-by-3-min class)
- [x] **[B-0445](backlog/P1/B-0445-csharp-fluent-operator-surface-pm2-2026-05-13.md)** C# fluent operator surface — Map, Filter, Join, Distinct, Window via idiomatic CSharp API
- [ ] **[B-0448](backlog/P1/B-0448-cloud-routines-integration-4th-catch-43-defence-layer-2026-05-13.md)** Cloud Routines integration — 4th catch-43 defence layer via Anthropic-hosted scheduled tasks + API + GitHub event triggers
- [ ] **[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)
Expand Down Expand Up @@ -305,9 +305,9 @@ are closed (status: closed in frontmatter)._
- [ ] **[B-0500](backlog/P1/B-0500-b0441-slice-3-queue-state-guard-poll-once-wiring-2026-05-14.md)** B-0441 slice 3 — wire isAgentQueueEmpty guard into pollOnce
- [ ] **[B-0501](backlog/P1/B-0501-b0441-slice-5-assignment-history-dedup-cooldown-2026-05-14.md)** B-0441 slice 5 — assignment history dedup cooldown (avoid re-assigning same row within short window)
- [ ] **[B-0502](backlog/P1/B-0502-b0441-slice-6-launchd-plist-autonomous-loop-docs-2026-05-14.md)** B-0441 slice 6 — launchd plist for backlog-ready-notifier + AUTONOMOUS-LOOP.md update
- [ ] **[B-0503](backlog/P1/B-0503-b0442-slice5a-open-recovery-pr-core-function-2026-05-14.md)** B-0442 slice 5a — openRecoveryPR core function + RecoveryAdapters + DST tests
- [ ] **[B-0504](backlog/P1/B-0504-b0442-slice5b-wire-auto-recover-into-pollonce-2026-05-14.md)** B-0442 slice 5b — wire --auto-recover into pollOnce + real RecoveryAdapters + config flags
- [ ] **[B-0505](backlog/P1/B-0505-b0442-slice5c-docs-autonomous-loop-acceptance-close-2026-05-14.md)** B-0442 slice 5c — docs update (AUTONOMOUS-LOOP.md + bg/README.md) + B-0442 acceptance close
- [x] **[B-0503](backlog/P1/B-0503-b0442-slice5a-open-recovery-pr-core-function-2026-05-14.md)** B-0442 slice 5a — openRecoveryPR core function + RecoveryAdapters + DST tests
- [x] **[B-0504](backlog/P1/B-0504-b0442-slice5b-wire-auto-recover-into-pollonce-2026-05-14.md)** B-0442 slice 5b — wire --auto-recover into pollOnce + real RecoveryAdapters + config flags
- [x] **[B-0505](backlog/P1/B-0505-b0442-slice5c-docs-autonomous-loop-acceptance-close-2026-05-14.md)** B-0442 slice 5c — docs update (AUTONOMOUS-LOOP.md + bg/README.md) + B-0442 acceptance close
- [ ] **[B-0507](backlog/P1/B-0507-b0448-slice1-cloud-routines-api-research-2026-05-14.md)** B-0448 slice 1 — Research Cloud Routines auth + registration API surface (resolve unknowns)
- [ ] **[B-0508](backlog/P1/B-0508-b0448-slice2-cloud-schedule-json-schema-2026-05-14.md)** B-0448 slice 2 — Define cloud-schedule.json schema for tools/routines/<id>/
- [ ] **[B-0509](backlog/P1/B-0509-b0448-slice3-install-ts-cloud-schedule-extension-2026-05-14.md)** B-0448 slice 3 — Extend tools/routines/install.ts to detect + surface cloud-schedule.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
id: B-0442
priority: P1
status: open
status: closed
Comment thread
AceHack marked this conversation as resolved.
Comment thread
AceHack marked this conversation as resolved.
title: "Missed-substrate cascade detector — background service that catches branch-vs-merged-PR drift (e.g., Otto-section-missed-PR-2980-by-3-min class)"
tier: factory-infrastructure
effort: M
created: 2026-05-13
last_updated: 2026-05-14
last_updated: 2026-05-15
closed: 2026-05-15
closed_by_pr: 3458
depends_on: [B-0400]
composes_with: [B-0402, B-0440, B-0441]
children: [B-0503, B-0504, B-0505]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
id: B-0503
priority: P1
status: open
status: closed
title: "B-0442 slice 5a — openRecoveryPR core function + RecoveryAdapters + DST tests"
tier: factory-infrastructure
effort: S
created: 2026-05-14
last_updated: 2026-05-14
last_updated: 2026-05-15
closed: 2026-05-15
parent: B-0442
depends_on: []
composes_with: [B-0442, B-0504]
Expand Down Expand Up @@ -37,7 +38,7 @@ for opening a recovery PR, independently testable before any wiring into

## Acceptance criteria

- [ ] New file `tools/bg/missed-substrate-recovery.ts` exports:
- [x] New file `tools/bg/missed-substrate-recovery.ts` exports: (landed on origin/main; design sketch below has been reconciled with as-shipped — `buildRecoveryBranchName` simplified to `(prNumber)` per PR #3458 docs)
- `RecoveryAdapters` — interface with five adapters injected by callers:
- `checkRecoveryPRExists(branchName: string) => boolean`
— calls `gh pr list --head <branchName> --state open` to detect existing
Expand All @@ -60,9 +61,8 @@ for opening a recovery PR, independently testable before any wiring into
| { status: "cherry-pick-conflict"; sha: string; attemptedCount: number }
| { status: "error"; reason: string }
```
- `buildRecoveryBranchName(prNumber: number, ts: Date) => string`
— deterministic branch name `recovery/<prNumber>-<YYYYMMDDHHMMSS>`;
pure function; no I/O.
- `buildRecoveryBranchName(prNumber: number) => string`
— deterministic branch name `recovery/<prNumber>`; pure function; no I/O.
- `buildRecoveryPRBody(finding: CascadeFinding) => string`
— markdown body for the recovery PR listing `missingCommits`,
the original `prNumber`, and a note that this was auto-generated.
Expand All @@ -79,7 +79,7 @@ for opening a recovery PR, independently testable before any wiring into
6. `ghPrCreate(title, body, recoveryBranch)` → null → return `error`;
non-null URL → return `opened`.

- [ ] New file `tools/bg/missed-substrate-recovery.test.ts` with tests
- [x] New file `tools/bg/missed-substrate-recovery.test.ts` with tests
covering all `RecoveryResult` arms:
- `"opened"` — fresh finding, no existing PR, no conflicts, push+PR succeed.
- `"already-exists"` — `checkRecoveryPRExists` returns `true`; no mutations.
Expand All @@ -90,8 +90,8 @@ for opening a recovery PR, independently testable before any wiring into
- `buildRecoveryBranchName` — deterministic output matches expected pattern.
- `buildRecoveryPRBody` — contains PR number and commit SHAs.

- [ ] All tests pass: `bun tools/bg/missed-substrate-recovery.test.ts`
- [ ] `bun tools/bg/missed-substrate-detector.test.ts` still passes (no regressions)
- [x] All tests pass: `bun tools/bg/missed-substrate-recovery.test.ts` (landed in B-0503 slice; on `origin/main`)
- [x] `bun tools/bg/missed-substrate-detector.test.ts` still passes (no regressions) (landed in B-0503 slice; on `origin/main`)

## Design sketch

Expand All @@ -114,9 +114,8 @@ export type RecoveryResult =
| { status: "cherry-pick-conflict"; sha: string; attemptedCount: number }
| { status: "error"; reason: string };

export function buildRecoveryBranchName(prNumber: number, ts: Date): string {
const stamp = ts.toISOString().replace(/[-:T]/g, "").slice(0, 14);
return `recovery/${prNumber}-${stamp}`;
export function buildRecoveryBranchName(prNumber: number): string {
return `recovery/${prNumber}`;
}

export function buildRecoveryPRBody(finding: CascadeFinding): string {
Expand All @@ -140,7 +139,7 @@ export function openRecoveryPR(
dryRun: boolean,
adapters: RecoveryAdapters,
): RecoveryResult {
const recoveryBranch = buildRecoveryBranchName(finding.prNumber, new Date());
const recoveryBranch = buildRecoveryBranchName(finding.prNumber);

const exists = adapters.checkRecoveryPRExists(recoveryBranch);
if (exists) {
Expand Down Expand Up @@ -192,15 +191,15 @@ adapter implementations. The real adapters (in B-0504) must validate SHA
inputs from `CascadeFinding.missingCommits` with the same allow-list regex
already used in `compareBranchToMerged`.

## Why `openRecoveryPR` uses `new Date()` internally for the branch name
## Why the recovery branch name is `recovery/<prNumber>` (no timestamp)

The recovery branch name includes a timestamp to ensure uniqueness across
multiple recovery attempts for the same PR number. Using `new Date()` inside
`openRecoveryPR` rather than injecting it via adapters is intentional: the
idempotency gate (`checkRecoveryPRExists`) already prevents duplicate
recovery PRs; the timestamp is not load-bearing for correctness. For tests
that need to verify the branch name, `buildRecoveryBranchName` is exported
and tested separately.
The original sketch included a `<YYYYMMDDHHMMSS>` suffix to guarantee
uniqueness across multiple recovery attempts. The shipped implementation
dropped it: the idempotency gate (`checkRecoveryPRExists`) already prevents
duplicate recovery PRs for the same source PR, so a single deterministic
name per `prNumber` is correct AND simpler to test. Documented in PR #3458's
`docs/AUTONOMOUS-LOOP.md` update — "deterministic branch name
`recovery/<prNumber>`".

## Dependency chain

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
id: B-0504
priority: P1
status: open
status: closed
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reopen B-0504 until its acceptance checklist is complete

This change flips B-0504 to status: closed, but every item in that row’s ## Acceptance criteria block is still unchecked ([ ]). Since backlog tooling and readers treat frontmatter status as completion, this marks the slice as done while its own contract still says it is unfinished, which can suppress follow-up work or misreport progress.

Useful? React with 👍 / 👎.

title: "B-0442 slice 5b — wire --auto-recover into pollOnce + real RecoveryAdapters + config flags"
tier: factory-infrastructure
effort: S
created: 2026-05-14
last_updated: 2026-05-14
last_updated: 2026-05-15
closed: 2026-05-15
closed_by_pr: 3458
parent: B-0442
depends_on: [B-0503]
composes_with: [B-0442, B-0503, B-0505]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
id: B-0505
priority: P1
status: open
status: closed
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reopen B-0505 until the row-level acceptance criteria are met

This row is also marked status: closed even though its ## Acceptance criteria section remains entirely unchecked. Closing the row before its own checklist is reconciled creates an internal contradiction in the backlog artifact and can cause review/automation flows to treat documentation and acceptance-close work as complete when the row still records it as pending.

Useful? React with 👍 / 👎.

title: "B-0442 slice 5c — docs update (AUTONOMOUS-LOOP.md + bg/README.md) + B-0442 acceptance close"
tier: factory-infrastructure
effort: XS
created: 2026-05-14
last_updated: 2026-05-14
last_updated: 2026-05-15
closed: 2026-05-15
closed_by_pr: 3458
parent: B-0442
depends_on: [B-0504]
composes_with: [B-0442, B-0503, B-0504]
Expand Down
Loading