feat: export continuity hard-gate and watchdog workstream
This commit is contained in:
0
state/approved-plan-continuity/.gitkeep
Normal file
0
state/approved-plan-continuity/.gitkeep
Normal file
62
state/approved-plan-continuity/README.md
Normal file
62
state/approved-plan-continuity/README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Approved Plan Continuity Receipt Storage
|
||||
|
||||
This directory stores file-backed continuity receipts for approved-plan flows.
|
||||
|
||||
## Scope
|
||||
|
||||
This storage definition is intentionally minimal.
|
||||
It defines only the receipt location, minimum receipt shape, and filename convention for continuity receipts.
|
||||
It does **not** implement receipt writing, hook integration, dispatch orchestration, or gate evaluation logic.
|
||||
|
||||
## Receipt file format
|
||||
|
||||
- Format: JSON
|
||||
- Encoding: UTF-8
|
||||
- One receipt per file
|
||||
|
||||
## Minimum receipt shape
|
||||
|
||||
Each continuity receipt file must contain a JSON object with at least these fields:
|
||||
|
||||
- `planId`
|
||||
- `currentTask`
|
||||
- `nextDerivedAction`
|
||||
- `dispatchedAt`
|
||||
- `dispatchRunId`
|
||||
- `childSessionKey`
|
||||
- `replyClosureState`
|
||||
|
||||
### Minimal example
|
||||
|
||||
```json
|
||||
{
|
||||
"planId": "plan_2026_04_24_example",
|
||||
"currentTask": "Task 15",
|
||||
"nextDerivedAction": "dispatch next approved-plan task",
|
||||
"dispatchedAt": "2026-04-24T12:00:00.000+08:00",
|
||||
"dispatchRunId": "dispatch_2026_04_24_example",
|
||||
"childSessionKey": "agent:engineering:subtask-example",
|
||||
"replyClosureState": "open"
|
||||
}
|
||||
```
|
||||
|
||||
## Filename convention
|
||||
|
||||
Continuity receipt filenames must follow this pattern:
|
||||
|
||||
```text
|
||||
receipt-<planId>-<dispatchRunId>.json
|
||||
```
|
||||
|
||||
## Naming rules
|
||||
|
||||
- `<planId>` should match the receipt `planId`
|
||||
- `<dispatchRunId>` should match the receipt `dispatchRunId`
|
||||
- Use lowercase kebab-case or other filesystem-safe identifiers
|
||||
- Do not reuse one file for multiple dispatch runs
|
||||
|
||||
## State interpretation
|
||||
|
||||
- A receipt in this directory represents a persisted continuity dispatch record for one approved-plan dispatch run.
|
||||
- `replyClosureState` is stored alongside the dispatch linkage so later tasks can distinguish an active dispatch record from an allowed non-dispatch closure state.
|
||||
- Legal non-dispatch closure values are defined by the plan/runbook logic outside this storage README.
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"planId": "plan_2026_04_24_example",
|
||||
"currentTask": "task-16",
|
||||
"nextDerivedAction": {
|
||||
"type": "message_subagent",
|
||||
"task": "continue with task-17"
|
||||
},
|
||||
"dispatchedAt": "2026-04-24T12:24:00.000+08:00",
|
||||
"dispatchRunId": "dispatch_2026_04_24_example",
|
||||
"childSessionKey": "agent:engineering:subtask-example",
|
||||
"replyClosureState": "open"
|
||||
}
|
||||
0
state/subagent-delivery-watchdog/.gitkeep
Normal file
0
state/subagent-delivery-watchdog/.gitkeep
Normal file
81
state/subagent-delivery-watchdog/README.md
Normal file
81
state/subagent-delivery-watchdog/README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Subagent Delivery Watchdog State Shape
|
||||
|
||||
This directory is reserved for file-backed state used by the subagent delivery watchdog.
|
||||
|
||||
## Purpose
|
||||
|
||||
The watchdog tracks whether a subagent dispatch has a matching completion receipt and whether the main thread has enough evidence to classify the run state without guessing.
|
||||
|
||||
This task defines the **state JSON shape only**. It does **not** implement receipt write logic, status recomputation, recovery behavior, or live integration.
|
||||
|
||||
## Suggested file model
|
||||
|
||||
One JSON document per dispatched subagent run.
|
||||
|
||||
Example path pattern:
|
||||
|
||||
- `state/subagent-delivery-watchdog/<runId>.json`
|
||||
|
||||
## State JSON shape
|
||||
|
||||
```json
|
||||
{
|
||||
"runId": "run_2026_04_24_abc123",
|
||||
"childSessionKey": "agent:engineering:subagent:cd236af1-7d4a-4f4e-bccd-04e4f9a96c02",
|
||||
"dispatchAt": "2026-04-24T10:40:00+08:00",
|
||||
"expectedBy": "2026-04-24T10:50:00+08:00",
|
||||
"completionReceivedAt": null,
|
||||
"forwardedToMain": false,
|
||||
"resultSource": null,
|
||||
"status": "active",
|
||||
"statusUpdatedAt": "2026-04-24T10:40:00+08:00",
|
||||
"statusReason": "Dispatch receipt exists and SLA has not been crossed.",
|
||||
"recoveryAction": null,
|
||||
"recoveryAttemptCount": 0,
|
||||
"lastRecoveryAt": null,
|
||||
"notes": []
|
||||
}
|
||||
```
|
||||
|
||||
## Receipt fields
|
||||
|
||||
### Dispatch receipt fields
|
||||
|
||||
- `runId`: unique identifier for the dispatched subagent run.
|
||||
- `childSessionKey`: session key or stable child-session identifier used to correlate the run.
|
||||
- `dispatchAt`: ISO-8601 timestamp for when the subagent was dispatched.
|
||||
- `expectedBy`: ISO-8601 timestamp for the watchdog SLA / expected completion deadline.
|
||||
|
||||
### Completion receipt fields
|
||||
|
||||
- `completionReceivedAt`: ISO-8601 timestamp for when a completion receipt was observed by the owner thread; `null` if not yet observed.
|
||||
- `forwardedToMain`: boolean indicating whether the completion/result was confirmed forwarded back to the main thread.
|
||||
- `resultSource`: source label for the result evidence, for example `completion_event`, `history_fetch`, or `manual_recovery`; `null` if no completion evidence exists yet.
|
||||
|
||||
## Status fields
|
||||
|
||||
- `status`: current watchdog classification. Expected values include:
|
||||
- `active`
|
||||
- `suspect_delivery_failure`
|
||||
- `done_but_not_forwarded`
|
||||
- `completed`
|
||||
- `recovered`
|
||||
- `blocked`
|
||||
- `statusUpdatedAt`: ISO-8601 timestamp of the latest status evaluation/update.
|
||||
- `statusReason`: short human-readable explanation for why the current status was assigned.
|
||||
|
||||
## Optional supporting fields
|
||||
|
||||
These fields are not a substitute for the required receipt/status fields, but they can support later tasks safely.
|
||||
|
||||
- `recoveryAction`: pending or last recovery decision, if any.
|
||||
- `recoveryAttemptCount`: number of recovery attempts already made.
|
||||
- `lastRecoveryAt`: ISO-8601 timestamp of the last recovery attempt.
|
||||
- `notes`: append-only diagnostic notes.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Receipt fields and status fields must remain explicit in stored state.
|
||||
- `completionReceivedAt`, `resultSource`, and recovery-related fields may be `null` before any completion signal exists.
|
||||
- `forwardedToMain` should remain `false` until the return path to the main thread is actually confirmed.
|
||||
- Status must be derived from evidence; later implementation should not infer success without a receipt or equivalent recovery proof.
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"runId": "fixture-run-active-before-sla",
|
||||
"childSessionKey": "session:active-before-sla",
|
||||
"dispatchAt": "2026-04-24T10:00:00.000Z",
|
||||
"expectedBy": "2026-04-24T10:10:00.000Z"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"runId": "fixture-run-completed",
|
||||
"childSessionKey": "session:completed",
|
||||
"dispatchAt": "2026-04-24T10:00:00.000Z",
|
||||
"expectedBy": "2026-04-24T10:10:00.000Z",
|
||||
"completionReceivedAt": "2026-04-24T10:04:00.000Z"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"runId": "fixture-run-done-not-forwarded",
|
||||
"childSessionKey": "session:done-not-forwarded",
|
||||
"dispatchAt": "2026-04-24T10:00:00.000Z",
|
||||
"expectedBy": "2026-04-24T10:10:00.000Z"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"runId": "fixture-run-suspect-delivery-failure",
|
||||
"childSessionKey": "session:suspect-delivery-failure",
|
||||
"dispatchAt": "2026-04-24T10:00:00.000Z",
|
||||
"expectedBy": "2026-04-24T10:10:00.000Z"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"runId": "preview-completion-write",
|
||||
"childSessionKey": "session:preview",
|
||||
"dispatchAt": "2026-04-24T10:00:00.000Z",
|
||||
"expectedBy": "2026-04-24T10:10:00.000Z",
|
||||
"completionReceivedAt": "2026-04-24T10:04:00.000Z",
|
||||
"forwardedToMain": false,
|
||||
"resultSource": "child_history"
|
||||
}
|
||||
Reference in New Issue
Block a user