feat: export continuity hard-gate and watchdog workstream
This commit is contained in:
410
docs/plans/2026-04-24-approved-plan-continuity-hard-gate.md
Normal file
410
docs/plans/2026-04-24-approved-plan-continuity-hard-gate.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# Approved-Plan Continuity Hard-Gate Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Prevent approved-plan flows from stopping after a task completes by requiring a real next-dispatch receipt unless the workflow explicitly transitions to `waiting_user`, `blocked`, or `pending_verification`.
|
||||
|
||||
**Architecture:** Build this in very small slices. First define continuity receipt fields and failure states, then pin the continuity failure with fail-first tests, then implement a minimal evaluator, then bind planner output to real dispatch receipts, then enforce reply-closure continuity. Keep every slice narrow enough to verify in isolation.
|
||||
|
||||
**Tech Stack:** Node.js, MJS test runners, file-backed JSON receipts, force-recall hook integration
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Define continuity receipt fields
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/runbooks/approved-plan-continuity.md`
|
||||
|
||||
**Step 1: Write only the receipt field list**
|
||||
- Define:
|
||||
- `planId`
|
||||
- `currentTask`
|
||||
- `nextDerivedAction`
|
||||
- `dispatchedAt`
|
||||
|
||||
**Step 2: Verify file exists**
|
||||
Run: `test -f docs/runbooks/approved-plan-continuity.md && echo OK`
|
||||
Expected: `OK`
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/approved-plan-continuity.md
|
||||
git commit -m "docs: define continuity dispatch receipt core fields"
|
||||
```
|
||||
|
||||
### Task 2: Define receipt linkage fields
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/approved-plan-continuity.md`
|
||||
|
||||
**Step 1: Add linkage fields**
|
||||
- Define:
|
||||
- `dispatchRunId`
|
||||
- `childSessionKey`
|
||||
- `replyClosureState`
|
||||
|
||||
**Step 2: Verify field names exist**
|
||||
Run: `grep -n "dispatchRunId\|childSessionKey\|replyClosureState" docs/runbooks/approved-plan-continuity.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/approved-plan-continuity.md
|
||||
git commit -m "docs: define continuity receipt linkage fields"
|
||||
```
|
||||
|
||||
### Task 3: Define legal terminal states
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/approved-plan-continuity.md`
|
||||
|
||||
**Step 1: Add legal closure states**
|
||||
- Define the only legal non-dispatch closures:
|
||||
- `waiting_user`
|
||||
- `blocked`
|
||||
- `pending_verification`
|
||||
|
||||
**Step 2: Verify text exists**
|
||||
Run: `grep -n "waiting_user\|blocked\|pending_verification" docs/runbooks/approved-plan-continuity.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/approved-plan-continuity.md
|
||||
git commit -m "docs: define legal approved-plan terminal states"
|
||||
```
|
||||
|
||||
### Task 4: Create continuity gate script skeleton
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Add CLI skeleton**
|
||||
- Support `--input` and placeholder JSON output.
|
||||
|
||||
**Step 2: Verify it runs**
|
||||
Run: `node scripts/approved_plan_continuity_gate.mjs --compact --input /dev/null || true`
|
||||
Expected: placeholder response or controlled failure
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/approved_plan_continuity_gate.mjs
|
||||
git commit -m "chore: add approved-plan continuity gate skeleton"
|
||||
```
|
||||
|
||||
### Task 5: Create continuity gate test skeleton
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Add test harness skeleton**
|
||||
- Basic runner + fixture helper only.
|
||||
|
||||
**Step 2: Verify it runs**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs || true`
|
||||
Expected: test runner executes
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: add continuity gate test skeleton"
|
||||
```
|
||||
|
||||
### Task 6: Add fail-first test for missing dispatch receipt
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- task complete
|
||||
- next action known
|
||||
- no dispatch receipt
|
||||
- not waiting/blocked/pending_verification
|
||||
- expect continuity failure
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: fail when approved plan step stops without dispatch receipt"
|
||||
```
|
||||
|
||||
### Task 7: Add pass test for existing dispatch receipt
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- task complete
|
||||
- next action known
|
||||
- dispatch receipt exists
|
||||
- expect pass
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL until evaluator exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: allow approved plan step with dispatch receipt"
|
||||
```
|
||||
|
||||
### Task 8: Add pass test for waiting_user closure
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- task complete
|
||||
- next action known
|
||||
- no dispatch receipt
|
||||
- replyClosureState=`waiting_user`
|
||||
- expect pass
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL until evaluator exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: allow waiting_user continuity closure"
|
||||
```
|
||||
|
||||
### Task 9: Add pass test for blocked closure
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- replyClosureState=`blocked`
|
||||
- expect pass
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL until evaluator exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: allow blocked continuity closure"
|
||||
```
|
||||
|
||||
### Task 10: Add pass test for pending_verification closure
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- replyClosureState=`pending_verification`
|
||||
- expect pass
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL until evaluator exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: allow pending verification continuity closure"
|
||||
```
|
||||
|
||||
### Task 11: Implement minimal continuity evaluator
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Add evaluator logic**
|
||||
- Fail only when:
|
||||
- approved plan task complete
|
||||
- next action known
|
||||
- no dispatch receipt
|
||||
- and not in legal terminal state
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: PASS for Tasks 6-10
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/approved_plan_continuity_gate.mjs scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "feat: evaluate approved-plan continuity closure"
|
||||
```
|
||||
|
||||
### Task 12: Create dispatch binding skeleton
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/approved_plan_dispatch_binding.mjs`
|
||||
|
||||
**Step 1: Add CLI skeleton**
|
||||
- Support input parsing and placeholder receipt output.
|
||||
|
||||
**Step 2: Verify it runs**
|
||||
Run: `node scripts/approved_plan_dispatch_binding.mjs --compact --input /dev/null || true`
|
||||
Expected: placeholder response or controlled failure
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/approved_plan_dispatch_binding.mjs
|
||||
git commit -m "chore: add approved-plan dispatch binding skeleton"
|
||||
```
|
||||
|
||||
### Task 13: Add fail-first test for planner action without bound dispatch
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- planner returns `derivedAction`
|
||||
- but no dispatch receipt is written
|
||||
- expect fail
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: fail when derived action has no bound dispatch"
|
||||
```
|
||||
|
||||
### Task 14: Add pass test for planner action with bound dispatch receipt
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- planner returns `derivedAction`
|
||||
- receipt is written
|
||||
- expect pass
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: FAIL until binding exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: pass when derived action is bound to dispatch receipt"
|
||||
```
|
||||
|
||||
### Task 15: Define continuity receipt state storage
|
||||
|
||||
**Files:**
|
||||
- Create: `state/approved-plan-continuity/.gitkeep`
|
||||
- Create: `state/approved-plan-continuity/README.md`
|
||||
|
||||
**Step 1: Write the state shape**
|
||||
- Include receipt filenames and minimum fields.
|
||||
|
||||
**Step 2: Verify files exist**
|
||||
Run: `test -f state/approved-plan-continuity/README.md && test -f state/approved-plan-continuity/.gitkeep && echo OK`
|
||||
Expected: `OK`
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add state/approved-plan-continuity/.gitkeep state/approved-plan-continuity/README.md
|
||||
git commit -m "docs: define approved-plan continuity receipt storage"
|
||||
```
|
||||
|
||||
### Task 16: Implement minimal dispatch receipt writer
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/approved_plan_dispatch_binding.mjs`
|
||||
|
||||
**Step 1: Write dispatch receipts**
|
||||
- When a known action is truly bound, write file-backed receipt.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: binding tests pass
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/approved_plan_dispatch_binding.mjs scripts/test_approved_plan_continuity_gate.mjs state/approved-plan-continuity/.gitkeep state/approved-plan-continuity/README.md
|
||||
git commit -m "feat: write approved-plan continuity dispatch receipts"
|
||||
```
|
||||
|
||||
### Task 17: Add fail-first regression for “task done but stopped”
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Write the regression test**
|
||||
- completed task
|
||||
- next step known
|
||||
- no dispatch receipt
|
||||
- reply tries to close anyway
|
||||
- expect violation
|
||||
|
||||
**Step 2: Run tests to verify it fails if regression exists**
|
||||
Run: `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
Expected: PASS after fix, but must detect regression if broken
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "test: lock regression for task done but stopped"
|
||||
```
|
||||
|
||||
### Task 18: Hook continuity gate into force-recall handler
|
||||
|
||||
**Files:**
|
||||
- Modify: `hooks/force-recall/handler.ts`
|
||||
|
||||
**Step 1: Wire continuity gate into reply closure path**
|
||||
- Enforce continuity before normal closeout.
|
||||
|
||||
**Step 2: Run targeted verification**
|
||||
Run:
|
||||
- `node scripts/test_approved_plan_continuity_gate.mjs`
|
||||
- `node scripts/test_force_recall_long_task_preflight.mjs`
|
||||
- `node --check hooks/force-recall/handler.ts`
|
||||
Expected: PASS
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add hooks/force-recall/handler.ts scripts/approved_plan_continuity_gate.mjs scripts/approved_plan_dispatch_binding.mjs scripts/test_approved_plan_continuity_gate.mjs
|
||||
git commit -m "feat: enforce approved-plan continuity at reply closure"
|
||||
```
|
||||
|
||||
### Task 19: Peer review continuity evaluator and binding
|
||||
|
||||
**Files:**
|
||||
- Review: `scripts/approved_plan_continuity_gate.mjs`
|
||||
- Review: `scripts/approved_plan_dispatch_binding.mjs`
|
||||
- Review: `scripts/test_approved_plan_continuity_gate.mjs`
|
||||
|
||||
**Step 1: Request review**
|
||||
- Focus: does this really fix continuity failure instead of adding prompt-only guidance?
|
||||
|
||||
**Step 2: Record verdict**
|
||||
- Include commands and findings.
|
||||
|
||||
**Step 3: Apply follow-up fixes if needed**
|
||||
```bash
|
||||
# only if reviewer requests changes
|
||||
git add <changed-files>
|
||||
git commit -m "fix: address continuity gate review feedback"
|
||||
```
|
||||
|
||||
### Task 20: Peer review hook integration and handoff
|
||||
|
||||
**Files:**
|
||||
- Review: `hooks/force-recall/handler.ts`
|
||||
- Review: `docs/runbooks/approved-plan-continuity.md`
|
||||
- Review: `state/approved-plan-continuity/README.md`
|
||||
|
||||
**Step 1: Request review**
|
||||
- Focus: can approved-plan task completion still stop without dispatch receipt?
|
||||
|
||||
**Step 2: Record verification output**
|
||||
- Include commands and reviewer verdict.
|
||||
|
||||
**Step 3: Final state**
|
||||
- Leave task in `pending_verification`; do not mark complete.
|
||||
686
docs/plans/2026-04-24-subagent-anti-blackhole-watchdog.md
Normal file
686
docs/plans/2026-04-24-subagent-anti-blackhole-watchdog.md
Normal file
@@ -0,0 +1,686 @@
|
||||
# Subagent Anti-Blackhole / Completion-Delivery Watchdog Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Prevent B-class fake timeouts where a subagent finishes, stalls, or loses its return path off-thread and the main conversation never receives a trustworthy completion update.
|
||||
|
||||
**Architecture:** Build this in very small layers: first define receipts and states, then pin the blackhole cases with fail-first tests, then implement deterministic receipt-state logic, then add done-but-not-forwarded recovery decisions, then add owner-visible reporting rules and scenario simulations. Keep all early slices file-backed and test-driven before touching any live-session integration.
|
||||
|
||||
**Tech Stack:** Node.js, MJS test runners, file-backed JSON state, OpenClaw subagent/session concepts, docs/runbooks
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Define dispatch receipt fields
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Write the receipt field list**
|
||||
- Define only dispatch fields:
|
||||
- `runId`
|
||||
- `childSessionKey`
|
||||
- `dispatchAt`
|
||||
- `expectedBy`
|
||||
|
||||
**Step 2: Verify file contains the new field names**
|
||||
Run: `grep -n "runId\|childSessionKey\|dispatchAt\|expectedBy" docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: define subagent dispatch receipt fields"
|
||||
```
|
||||
|
||||
### Task 2: Define completion receipt fields
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Write the completion field list**
|
||||
- Define only completion fields:
|
||||
- `completionReceivedAt`
|
||||
- `forwardedToMain`
|
||||
- `resultSource`
|
||||
|
||||
**Step 2: Verify file contains the new field names**
|
||||
Run: `grep -n "completionReceivedAt\|forwardedToMain\|resultSource" docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: define subagent completion receipt fields"
|
||||
```
|
||||
|
||||
### Task 3: Define watchdog statuses
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Add the status enum**
|
||||
- Define:
|
||||
- `active`
|
||||
- `suspect_delivery_failure`
|
||||
- `done_but_not_forwarded`
|
||||
- `completed`
|
||||
- `recovered`
|
||||
- `blocked`
|
||||
|
||||
**Step 2: Verify status names exist**
|
||||
Run: `grep -n "suspect_delivery_failure\|done_but_not_forwarded\|recovered" docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: define subagent watchdog statuses"
|
||||
```
|
||||
|
||||
### Task 4: Define B-class failure modes
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Write the failure mode bullets**
|
||||
- Add:
|
||||
- done but not forwarded
|
||||
- no completion event received
|
||||
- session exists but no result bounce
|
||||
- unclear slow-run vs delivery failure
|
||||
|
||||
**Step 2: Verify phrases exist**
|
||||
Run: `grep -n "done but not forwarded\|completion event\|result bounce\|delivery failure" docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: define B-class subagent failure modes"
|
||||
```
|
||||
|
||||
### Task 5: Create watchdog script skeleton
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Create the script shell**
|
||||
- Add CLI parsing and a placeholder JSON response.
|
||||
|
||||
**Step 2: Verify it runs**
|
||||
Run: `node scripts/subagent_delivery_watchdog.mjs --compact --input /dev/null || true`
|
||||
Expected: script exists and is executable enough for next test work
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs
|
||||
git commit -m "chore: add subagent delivery watchdog skeleton"
|
||||
```
|
||||
|
||||
### Task 6: Create watchdog test skeleton
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Create the test shell**
|
||||
- Add basic harness structure and fixture runner.
|
||||
|
||||
**Step 2: Verify test file executes**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs || true`
|
||||
Expected: test runner executes, even if failing
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: add subagent watchdog test skeleton"
|
||||
```
|
||||
|
||||
### Task 7: Add active-before-SLA test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- dispatch exists
|
||||
- no completion receipt yet
|
||||
- current time still before SLA
|
||||
- expect `active`
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on missing logic
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: require active status before SLA breach"
|
||||
```
|
||||
|
||||
### Task 8: Add suspect-delivery-failure test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- dispatch exists
|
||||
- no completion receipt
|
||||
- current time beyond SLA
|
||||
- expect `suspect_delivery_failure`
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on new assertion
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: detect suspected delivery failure after SLA"
|
||||
```
|
||||
|
||||
### Task 9: Add completed-status test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- dispatch exists
|
||||
- completion receipt exists
|
||||
- expect `completed`
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on completed path
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: close watchdog on completion receipt"
|
||||
```
|
||||
|
||||
### Task 10: Add state shape fixture
|
||||
|
||||
**Files:**
|
||||
- Create: `state/subagent-delivery-watchdog/README.md`
|
||||
- Create: `state/subagent-delivery-watchdog/.gitkeep`
|
||||
|
||||
**Step 1: Define the state JSON shape in README**
|
||||
- Include receipt fields and status fields.
|
||||
|
||||
**Step 2: Verify files exist**
|
||||
Run: `test -f state/subagent-delivery-watchdog/README.md && test -f state/subagent-delivery-watchdog/.gitkeep && echo OK`
|
||||
Expected: `OK`
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add state/subagent-delivery-watchdog/README.md state/subagent-delivery-watchdog/.gitkeep
|
||||
git commit -m "docs: define watchdog state storage shape"
|
||||
```
|
||||
|
||||
### Task 11: Implement dispatch receipt write
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add a function to write dispatch receipt state**
|
||||
- Only handle a new dispatch record.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: some tests still fail, but dispatch state path exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: write subagent dispatch receipt state"
|
||||
```
|
||||
|
||||
### Task 12: Implement completion receipt write
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add a function to write completion receipt state**
|
||||
- Only update completion-related fields.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: some tests still fail, but completion data path exists
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: write subagent completion receipt state"
|
||||
```
|
||||
|
||||
### Task 13: Implement status recompute for active/completed/suspect
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add status recompute logic**
|
||||
- Implement only:
|
||||
- `active`
|
||||
- `suspect_delivery_failure`
|
||||
- `completed`
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: Task 7-9 tests pass
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: recompute basic watchdog statuses"
|
||||
```
|
||||
|
||||
### Task 14: Add done-but-not-forwarded test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the test**
|
||||
- child run marked done
|
||||
- no completion receipt in main thread
|
||||
- expect `done_but_not_forwarded`
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on new assertion
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: detect done but not forwarded state"
|
||||
```
|
||||
|
||||
### Task 15: Implement done-but-not-forwarded state
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add done-but-not-forwarded detection**
|
||||
- Use child-done signal + missing completion receipt.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: done-but-not-forwarded test passes
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: detect done without forwarded completion"
|
||||
```
|
||||
|
||||
### Task 16: Add first recovery-action test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write fetch-history recovery test**
|
||||
- done but not forwarded
|
||||
- no prior recovery action
|
||||
- expect recovery decision `fetch_history`
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on recovery decision
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: fetch history after missing forwarded completion"
|
||||
```
|
||||
|
||||
### Task 17: Implement fetch-history recovery decision
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add minimal recovery decision logic**
|
||||
- Return `fetch_history` for first-time done-but-not-forwarded.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: fetch-history recovery test passes
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: recover with history fetch first"
|
||||
```
|
||||
|
||||
### Task 18: Add respawn-escalation test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the respawn test**
|
||||
- recovery already attempted once
|
||||
- still no forwarded completion
|
||||
- expect `respawn`
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on respawn decision
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: escalate to respawn after failed recovery"
|
||||
```
|
||||
|
||||
### Task 19: Implement respawn decision
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add respawn logic**
|
||||
- Return `respawn` when fetch-history path did not recover delivery.
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: respawn test passes
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: respawn after failed delivery recovery"
|
||||
```
|
||||
|
||||
### Task 20: Add blocked-escalation test
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Write the blocked test**
|
||||
- repeated recovery failure
|
||||
- expect `blocked` plus owner-visible reporting requirement
|
||||
|
||||
**Step 2: Run tests to verify it fails**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: FAIL on blocked escalation
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: escalate repeated delivery failures to blocked"
|
||||
```
|
||||
|
||||
### Task 21: Implement blocked escalation
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Add blocked escalation logic**
|
||||
- repeated recovery failure -> `blocked`
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
Expected: blocked escalation test passes
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/subagent_delivery_watchdog.mjs scripts/test_subagent_delivery_watchdog.mjs
|
||||
git commit -m "feat: block repeated subagent delivery failures"
|
||||
```
|
||||
|
||||
### Task 22: Add owner-visible reporting rule for suspect state
|
||||
|
||||
**Files:**
|
||||
- Modify: `WORKFLOW.md`
|
||||
- Modify: `AGENTS.md`
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Add suspect-state reporting rule**
|
||||
- If SLA is crossed with no completion receipt, the owner must be informed.
|
||||
|
||||
**Step 2: Verify text exists**
|
||||
Run: `grep -RIn "SLA\|suspect_delivery_failure" WORKFLOW.md AGENTS.md docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add WORKFLOW.md AGENTS.md docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: require reporting on suspect delivery failure"
|
||||
```
|
||||
|
||||
### Task 23: Add owner-visible reporting rule for done-but-not-forwarded
|
||||
|
||||
**Files:**
|
||||
- Modify: `WORKFLOW.md`
|
||||
- Modify: `AGENTS.md`
|
||||
- Modify: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
|
||||
**Step 1: Add done-but-not-forwarded reporting rule**
|
||||
- Must state that result exists but did not bounce back.
|
||||
|
||||
**Step 2: Verify text exists**
|
||||
Run: `grep -RIn "done but not forwarded\|did not bounce back" WORKFLOW.md AGENTS.md docs/runbooks/subagent-anti-blackhole.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add WORKFLOW.md AGENTS.md docs/runbooks/subagent-anti-blackhole.md
|
||||
git commit -m "docs: require reporting on missing forwarded completion"
|
||||
```
|
||||
|
||||
### Task 24: Add rule to fetch history before respawn
|
||||
|
||||
**Files:**
|
||||
- Modify: `WORKFLOW.md`
|
||||
- Modify: `docs/runbooks/subagent-delivery-recovery.md`
|
||||
|
||||
**Step 1: Add the history-first rule**
|
||||
- Done-but-not-forwarded should prefer `fetch_history` before `respawn`.
|
||||
|
||||
**Step 2: Verify text exists**
|
||||
Run: `grep -RIn "fetch_history\|before respawn" WORKFLOW.md docs/runbooks/subagent-delivery-recovery.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add WORKFLOW.md docs/runbooks/subagent-delivery-recovery.md
|
||||
git commit -m "docs: prefer history fetch before respawn"
|
||||
```
|
||||
|
||||
### Task 25: Add no-silent-waiting-after-SLA rule
|
||||
|
||||
**Files:**
|
||||
- Modify: `WORKFLOW.md`
|
||||
- Modify: `AGENTS.md`
|
||||
|
||||
**Step 1: Add the no-silent-waiting rule**
|
||||
- Once SLA is crossed, silent waiting is forbidden.
|
||||
|
||||
**Step 2: Verify text exists**
|
||||
Run: `grep -RIn "silent waiting\|SLA" WORKFLOW.md AGENTS.md`
|
||||
Expected: matching lines found
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add WORKFLOW.md AGENTS.md
|
||||
git commit -m "docs: forbid silent waiting after subagent SLA"
|
||||
```
|
||||
|
||||
### Task 26: Create blackhole scenario test shell
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Create the scenario test shell**
|
||||
- Add empty scenario harness.
|
||||
|
||||
**Step 2: Verify file runs**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs || true`
|
||||
Expected: file executes, even if not complete
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add subagent blackhole scenario harness"
|
||||
```
|
||||
|
||||
### Task 27: Add normal-completion scenario
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Write the scenario**
|
||||
- dispatch -> completion receipt -> completed
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: scenario still may fail until engine wiring is ready
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add normal subagent completion scenario"
|
||||
```
|
||||
|
||||
### Task 28: Add slow-but-active scenario
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Write the scenario**
|
||||
- dispatch before SLA -> active
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: scenario result captured
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add slow but active subagent scenario"
|
||||
```
|
||||
|
||||
### Task 29: Add done-but-not-forwarded scenario
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Write the scenario**
|
||||
- child done -> no completion receipt -> fetch_history
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: scenario result captured
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add done but not forwarded scenario"
|
||||
```
|
||||
|
||||
### Task 30: Add missing-completion-event scenario
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Write the scenario**
|
||||
- no bounce, no completion receipt, beyond SLA -> suspect delivery failure
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: scenario result captured
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add missing completion event scenario"
|
||||
```
|
||||
|
||||
### Task 31: Add repeated-failure escalation scenario
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Write the scenario**
|
||||
- fetch_history fails -> respawn fails -> blocked
|
||||
|
||||
**Step 2: Run tests**
|
||||
Run: `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: scenario result captured
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_blackhole_scenarios.mjs
|
||||
git commit -m "test: add repeated blackhole escalation scenario"
|
||||
```
|
||||
|
||||
### Task 32: Run the full local watchdog test set
|
||||
|
||||
**Files:**
|
||||
- Modify if needed: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
- Modify if needed: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
|
||||
**Step 1: Run the combined tests**
|
||||
Run:
|
||||
- `node scripts/test_subagent_delivery_watchdog.mjs`
|
||||
- `node scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
Expected: PASS
|
||||
|
||||
**Step 2: Fix only minimal wiring needed for all-pass**
|
||||
- Keep changes scoped to watchdog logic/tests.
|
||||
|
||||
**Step 3: Commit**
|
||||
```bash
|
||||
git add scripts/test_subagent_delivery_watchdog.mjs scripts/test_subagent_blackhole_scenarios.mjs scripts/subagent_delivery_watchdog.mjs
|
||||
git commit -m "test: pass full subagent blackhole watchdog suite"
|
||||
```
|
||||
|
||||
### Task 33: Peer review watchdog state logic
|
||||
|
||||
**Files:**
|
||||
- Review: `scripts/subagent_delivery_watchdog.mjs`
|
||||
- Review: `scripts/test_subagent_delivery_watchdog.mjs`
|
||||
|
||||
**Step 1: Request reviewer focus on receipt state logic**
|
||||
- Verify statuses and transitions match B-class failure goals.
|
||||
|
||||
**Step 2: Record reviewer verdict**
|
||||
- Include commands and findings.
|
||||
|
||||
**Step 3: Commit any follow-up fixes if needed**
|
||||
```bash
|
||||
# only if reviewer requests changes
|
||||
git add <changed-files>
|
||||
git commit -m "fix: address watchdog state review feedback"
|
||||
```
|
||||
|
||||
### Task 34: Peer review recovery decisions
|
||||
|
||||
**Files:**
|
||||
- Review: `scripts/subagent_delivery_watchdog.mjs`
|
||||
- Review: `docs/runbooks/subagent-delivery-recovery.md`
|
||||
|
||||
**Step 1: Request reviewer focus on recovery ordering**
|
||||
- Verify fetch-history before respawn and blocked escalation.
|
||||
|
||||
**Step 2: Record reviewer verdict**
|
||||
- Include commands and findings.
|
||||
|
||||
**Step 3: Commit any follow-up fixes if needed**
|
||||
```bash
|
||||
# only if reviewer requests changes
|
||||
git add <changed-files>
|
||||
git commit -m "fix: address recovery decision review feedback"
|
||||
```
|
||||
|
||||
### Task 35: Peer review scenario coverage and handoff
|
||||
|
||||
**Files:**
|
||||
- Review: `scripts/test_subagent_blackhole_scenarios.mjs`
|
||||
- Review: `docs/runbooks/subagent-anti-blackhole.md`
|
||||
- Review: `docs/runbooks/subagent-delivery-recovery.md`
|
||||
|
||||
**Step 1: Request reviewer focus on blackhole realism**
|
||||
- Confirm this targets fake timeout / no-bounce cases, not just slow work.
|
||||
|
||||
**Step 2: Record verification output**
|
||||
- Include exact commands and reviewer verdict.
|
||||
|
||||
**Step 3: Final state**
|
||||
- Leave task in `pending_verification`; do not mark complete.
|
||||
56
docs/runbooks/approved-plan-continuity.md
Normal file
56
docs/runbooks/approved-plan-continuity.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Approved Plan Continuity
|
||||
|
||||
## Continuity receipt core fields
|
||||
|
||||
### `planId`
|
||||
- The identifier of the approved plan that the continuity receipt belongs to.
|
||||
- Use this field to associate the receipt with one specific approved plan.
|
||||
|
||||
### `currentTask`
|
||||
- The task from the approved plan that is currently being executed or has just completed.
|
||||
- Use this field to record which plan task the receipt is about.
|
||||
|
||||
### `nextDerivedAction`
|
||||
- The next concrete action derived from the current task that should be dispatched to continue the workflow.
|
||||
- Use this field to record the intended follow-up action for continuity.
|
||||
|
||||
### `dispatchedAt`
|
||||
- The timestamp indicating when the next derived action was actually dispatched.
|
||||
- Use this field to record when the continuity handoff occurred.
|
||||
|
||||
## Continuity receipt linkage fields
|
||||
|
||||
### `dispatchRunId`
|
||||
- The unique identifier for the dispatch run that produced or recorded the next-step continuity handoff.
|
||||
- Use this field to link the receipt to one concrete dispatch execution, not just a planned action.
|
||||
- This field is for receipt linkage and traceability only; it does not by itself define continuity-gate pass/fail behavior.
|
||||
|
||||
### `childSessionKey`
|
||||
- The session linkage key for the child session or spawned execution context that receives the dispatched next action.
|
||||
- Use this field to connect the continuity receipt to the specific downstream session that should carry the workflow forward.
|
||||
- This field records linkage identity only; it does not by itself imply hook integration or dispatch binding logic.
|
||||
|
||||
### `replyClosureState`
|
||||
- The closure state recorded at the point the current reply is being closed.
|
||||
- Use this field to state whether the reply closed under a dispatch-linked continuation path or some separately defined terminal closure state.
|
||||
- This field is defined here as a receipt field only; legal closure states and gate enforcement are defined in later tasks.
|
||||
|
||||
|
||||
## Legal terminal states
|
||||
|
||||
These are the only legal non-dispatch terminal states for an approved-plan continuity closure. If a reply closes without a real next-dispatch receipt, `replyClosureState` must be one of the states below.
|
||||
|
||||
### `waiting_user`
|
||||
- Use this state only when the approved-plan workflow cannot continue until the user provides a decision, approval, missing information, or some other explicit user response.
|
||||
- This state means the workflow is intentionally paused on user input, not silently stopped.
|
||||
- Do not use this state when the next step could already be dispatched without further user involvement.
|
||||
|
||||
### `blocked`
|
||||
- Use this state only when the approved-plan workflow cannot proceed because of an external blocker, dependency, permission issue, outage, or other constraint that is not resolved by the current executor.
|
||||
- This state means progress is prevented by a real blocking condition, not by omission of the next dispatch.
|
||||
- Do not use this state to explain away a missing continuity handoff when execution could still continue.
|
||||
|
||||
### `pending_verification`
|
||||
- Use this state only when the implementation or execution step is done enough that the workflow should stop specifically for verification, validation, review, or confirmation of results.
|
||||
- This state means the next meaningful action is to verify what was already produced, rather than to dispatch another implementation step immediately.
|
||||
- Do not use this state for incomplete work that still has an undispatched next action.
|
||||
70
docs/runbooks/subagent-anti-blackhole.md
Normal file
70
docs/runbooks/subagent-anti-blackhole.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Subagent Anti-Blackhole Runbook
|
||||
|
||||
## Dispatch receipt fields
|
||||
|
||||
Dispatch receipt 僅定義子代理派發當下所需的欄位,用來識別本次派發、關聯子 session,以及標記預期完成時限。
|
||||
|
||||
- `runId`: 本次 subagent dispatch 的唯一執行識別碼。用於把同一次任務派發、後續狀態檢查與回報關聯到同一個 run。
|
||||
- `childSessionKey`: 子代理 session 的穩定關聯鍵。用於把 dispatch receipt 對應到實際被派發出去的 child session。
|
||||
- `dispatchAt`: dispatch receipt 寫入時間,也就是主流程實際派發 subagent 的時間戳記。建議使用可排序的標準時間格式。
|
||||
- `expectedBy`: 依照當次任務 SLA 或預估完成時間計算出的期望完成時間戳記。用於判斷目前仍屬正常執行中,或已超過預期等待窗口。
|
||||
|
||||
> 本節僅定義 dispatch receipt 欄位,不涵蓋 completion receipts、watchdog logic、recovery 流程或其他後續 task。
|
||||
|
||||
## Minimal example
|
||||
|
||||
```json
|
||||
{
|
||||
"runId": "run_2026-04-24_001",
|
||||
"childSessionKey": "agent:engineering:subagent:example",
|
||||
"dispatchAt": "2026-04-24T10:00:00+08:00",
|
||||
"expectedBy": "2026-04-24T10:15:00+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
## Completion receipt fields
|
||||
|
||||
Completion receipt 僅定義子代理完成結果被接收到之後所需記錄的欄位,用來區分「子代理已完成」與「結果是否已成功轉交 main conversation」。
|
||||
|
||||
- `completionReceivedAt`: 主流程或監看機制實際收到 completion/result 的時間戳記。用於確認子代理何時已經完成並回傳結果,不再只靠 `expectedBy` 推估。
|
||||
- `forwardedToMain`: 布林欄位,表示該 completion/result 是否已成功轉送到 main conversation。用於區分「已收到結果」與「已完成主線回報」這兩個不同狀態。
|
||||
- `resultSource`: completion/result 的來源標記,例如來自主動 completion push、補抓回來的 session 狀態,或其他明確來源。用於後續判讀結果是正常送達還是經由補救路徑取得。
|
||||
|
||||
> 本節僅定義 completion receipt 欄位,不涵蓋 watchdog logic、recovery 流程、scenario tests 或其他後續 task。
|
||||
|
||||
|
||||
## Watchdog statuses
|
||||
|
||||
Watchdog status 僅定義監看子代理完成投遞狀態時可使用的狀態列舉,用於區分仍在正常等待、疑似投遞失敗、結果已存在但未轉交,以及已完成或已卡住等情況。
|
||||
|
||||
- `active`: dispatch receipt 已存在,且目前仍在 `expectedBy` 之前,也還沒有任何 completion receipt。表示子代理仍在正常等待窗口內,watchdog 只需持續觀察,不應提前視為異常。
|
||||
- `suspect_delivery_failure`: dispatch receipt 已存在、目前已超過 `expectedBy`,但主流程仍未收到 completion receipt。表示尚無法證明子代理失敗或成功,只能判定為疑似 completion delivery 出問題,需進入明確的人工可見關注狀態。
|
||||
- `done_but_not_forwarded`: 已有可信訊號顯示子代理工作其實做完了,但 main thread 仍沒有對應的 forwarded completion receipt。表示結果可能存在於 child session 或其他回傳路徑上,只是沒有成功 bounce 回主線。
|
||||
- `completed`: completion receipt 已被主流程接收,且結果已成功進入主線回報路徑。表示此 run 的 watchdog 可視為正常閉合,不再屬於 blackhole 風險案例。
|
||||
- `recovered`: 先前曾落入 `suspect_delivery_failure` 或 `done_but_not_forwarded`,之後透過後續確認或補抓,已把結果重新接回可追蹤狀態。此狀態只定義「已從異常投遞風險中恢復」的語意,不在本 task 提前定義 recovery logic。
|
||||
- `blocked`: watchdog 已判定目前無法再以被動等待來解釋狀態,且該 run 需要明確升級處理或人工介入。此狀態只定義「已卡住、不可再默默等待」的語意,不在本 task 提前定義 escalation 或處置流程。
|
||||
|
||||
> 本節僅定義 watchdog statuses 的語意與邊界,不提前實作 recovery logic、receipt state code、scenario tests 或其他後續 task。
|
||||
|
||||
|
||||
|
||||
## B-class failure modes
|
||||
|
||||
B-class failure modes 指的是「子代理工作本身不一定真的 timeout,但主線沒有收到可信 completion 回報」的假 timeout 類型。這一類問題的核心不是先判定 child 一定失敗,而是先區分執行端、事件投遞端與主線轉交端哪一段失聯。
|
||||
|
||||
- **done but not forwarded**:child session 內已有可信跡象顯示工作完成,例如子代理已產出最終回報、session 狀態顯示 done,或可確認 completion 已存在於子線;但 main conversation 沒有收到對應的 forwarded result。這類型代表「結果已存在,但沒有被成功轉交到主線」。
|
||||
- **no completion event received**:主流程已完成 dispatch,且等待時間已逼近或超過 `expectedBy`,但主線完全沒有收到任何 completion event。此時不能直接斷言 child 一定還在跑,也不能直接斷言 child 已失敗;只能先明確標記為「主線未收到 completion event」,避免把 delivery 問題誤判成單純執行逾時。
|
||||
- **session exists but no result bounce**:可確認 child session 仍存在、可被查到,甚至可見到該 session 有持續活動或已留下結果內容,但沒有任何 result bounce 回到 main conversation。這類型比前一類更明確指出:session 並未消失,問題在於結果沒有沿正常回傳路徑反彈回主線。
|
||||
- **unclear slow-run vs delivery failure**:目前只知道主線等待已超過預期,但還無法分辨 child 是真的慢、仍在執行,還是其實已完成卻發生 delivery failure。這個 failure mode 的定義重點是保留不確定性:在證據不足時,不應把所有超時都歸類成 slow run,也不應直接假設是 delivery failure。
|
||||
|
||||
> 本節只定義 B-class 假 timeout failure modes 的語意邊界與彼此差異,不提前實作 recovery logic、receipt state code、watchdog script 或 scenario tests。
|
||||
|
||||
## Completion receipt example
|
||||
|
||||
```json
|
||||
{
|
||||
"completionReceivedAt": "2026-04-24T10:12:34+08:00",
|
||||
"forwardedToMain": true,
|
||||
"resultSource": "completion_push"
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user