@aperant/framework 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +152 -0
- package/dist/cli/commands/ci-watch.mjs +49 -2
- package/dist/cli/commands/ci-watch.mjs.map +1 -1
- package/dist/cli/commands/commit.mjs +3 -3
- package/dist/cli/commands/commit.mjs.map +1 -1
- package/dist/cli/commands/event.mjs +16 -16
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/merge-integrate.mjs +3 -3
- package/dist/cli/commands/merge-integrate.mjs.map +1 -1
- package/dist/cli/commands/produce.d.mts +9 -0
- package/dist/cli/commands/produce.d.mts.map +1 -0
- package/dist/cli/commands/produce.mjs +1345 -0
- package/dist/cli/commands/produce.mjs.map +1 -0
- package/dist/cli/commands/task.d.mts +16 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +434 -266
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs.map +1 -1
- package/dist/cli/coordination/event-schema.d.mts +5 -3
- package/dist/cli/coordination/event-schema.d.mts.map +1 -1
- package/dist/cli/coordination/event-schema.mjs +245 -21
- package/dist/cli/coordination/event-schema.mjs.map +1 -1
- package/dist/cli/coordination/store.d.mts +2 -2
- package/dist/cli/coordination/store.mjs +4 -4
- package/dist/cli/coordination/store.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +2 -0
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +30 -0
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +2 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/produce/blind-probe.d.mts +85 -0
- package/dist/cli/produce/blind-probe.d.mts.map +1 -0
- package/dist/cli/produce/blind-probe.mjs +217 -0
- package/dist/cli/produce/blind-probe.mjs.map +1 -0
- package/dist/cli/produce/claim.d.mts +188 -0
- package/dist/cli/produce/claim.d.mts.map +1 -0
- package/dist/cli/produce/claim.mjs +518 -0
- package/dist/cli/produce/claim.mjs.map +1 -0
- package/dist/cli/produce/done-gate.d.mts +87 -0
- package/dist/cli/produce/done-gate.d.mts.map +1 -0
- package/dist/cli/produce/done-gate.mjs +200 -0
- package/dist/cli/produce/done-gate.mjs.map +1 -0
- package/dist/cli/produce/events.d.mts +77 -0
- package/dist/cli/produce/events.d.mts.map +1 -0
- package/dist/cli/produce/events.mjs +126 -0
- package/dist/cli/produce/events.mjs.map +1 -0
- package/dist/cli/produce/evidence-oracle.d.mts +63 -0
- package/dist/cli/produce/evidence-oracle.d.mts.map +1 -0
- package/dist/cli/produce/evidence-oracle.mjs +122 -0
- package/dist/cli/produce/evidence-oracle.mjs.map +1 -0
- package/dist/cli/produce/ledger.d.mts +140 -0
- package/dist/cli/produce/ledger.d.mts.map +1 -0
- package/dist/cli/produce/ledger.mjs +272 -0
- package/dist/cli/produce/ledger.mjs.map +1 -0
- package/dist/cli/produce/probe-family.d.mts +53 -0
- package/dist/cli/produce/probe-family.d.mts.map +1 -0
- package/dist/cli/produce/probe-family.mjs +160 -0
- package/dist/cli/produce/probe-family.mjs.map +1 -0
- package/dist/cli/produce/projection.d.mts +55 -0
- package/dist/cli/produce/projection.d.mts.map +1 -0
- package/dist/cli/produce/projection.mjs +97 -0
- package/dist/cli/produce/projection.mjs.map +1 -0
- package/dist/cli/produce/run-id.d.mts +42 -0
- package/dist/cli/produce/run-id.d.mts.map +1 -0
- package/dist/cli/produce/run-id.mjs +79 -0
- package/dist/cli/produce/run-id.mjs.map +1 -0
- package/dist/cli/produce/saga.d.mts +180 -0
- package/dist/cli/produce/saga.d.mts.map +1 -0
- package/dist/cli/produce/saga.mjs +290 -0
- package/dist/cli/produce/saga.mjs.map +1 -0
- package/dist/cli/produce/scheduler.d.mts +165 -0
- package/dist/cli/produce/scheduler.d.mts.map +1 -0
- package/dist/cli/produce/scheduler.mjs +399 -0
- package/dist/cli/produce/scheduler.mjs.map +1 -0
- package/dist/cli/produce/setpoint.d.mts +52 -0
- package/dist/cli/produce/setpoint.d.mts.map +1 -0
- package/dist/cli/produce/setpoint.mjs +113 -0
- package/dist/cli/produce/setpoint.mjs.map +1 -0
- package/dist/cli/produce/verification-ttl.d.mts +75 -0
- package/dist/cli/produce/verification-ttl.d.mts.map +1 -0
- package/dist/cli/produce/verification-ttl.mjs +169 -0
- package/dist/cli/produce/verification-ttl.mjs.map +1 -0
- package/dist/cli/roadmap/{conductor-view.d.mts → showrunner-view.d.mts} +3 -3
- package/dist/cli/roadmap/showrunner-view.d.mts.map +1 -0
- package/dist/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +7 -7
- package/dist/cli/roadmap/showrunner-view.mjs.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/skills/apt/SKILL.md +112 -38
- package/dist/plugin/skills/apt-debug/SKILL.md +14 -24
- package/dist/plugin/skills/apt-fan-out/SKILL.md +4 -4
- package/dist/plugin/skills/apt-handoff/SKILL.md +1 -1
- package/dist/plugin/skills/apt-plan/SKILL.md +5 -5
- package/dist/plugin/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
- package/dist/plugin/skills/apt-produce/SKILL.md +606 -0
- package/dist/plugin/skills/apt-quick/SKILL.md +14 -22
- package/dist/plugin/skills/apt-run/SKILL.md +126 -3
- package/dist/plugin/skills/apt-ship/SKILL.md +2 -0
- package/dist/plugin/skills/apt-spar/SKILL.md +5 -3
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +4 -4
- package/package.json +4 -4
- package/prompts/{conductor-framework-context.md → showrunner-framework-context.md} +1 -1
- package/prompts/{conductor-status-check.md → showrunner-status-check.md} +1 -1
- package/prompts/{conductor-sub-agent.md → showrunner-sub-agent.md} +6 -6
- package/prompts/{conductor-system.md → showrunner-system.md} +8 -8
- package/skills/apt/SKILL.md +112 -38
- package/skills/apt-debug/SKILL.md +14 -24
- package/skills/apt-fan-out/SKILL.md +4 -4
- package/skills/apt-handoff/SKILL.md +1 -1
- package/skills/apt-plan/SKILL.md +5 -5
- package/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
- package/skills/apt-produce/SKILL.md +606 -0
- package/skills/apt-quick/SKILL.md +14 -22
- package/skills/apt-run/SKILL.md +126 -3
- package/skills/apt-ship/SKILL.md +2 -0
- package/skills/apt-spar/SKILL.md +5 -3
- package/skills/apt-watch-ci/SKILL.md +4 -4
- package/src/cli/commands/ci-watch.mjs +51 -2
- package/src/cli/commands/commit.mjs +3 -3
- package/src/cli/commands/event.mjs +16 -16
- package/src/cli/commands/merge-integrate.mjs +3 -3
- package/src/cli/commands/produce.mjs +1466 -0
- package/src/cli/commands/task.mjs +482 -285
- package/src/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
- package/src/cli/coordination/event-schema.d.ts +4 -2
- package/src/cli/coordination/event-schema.mjs +276 -21
- package/src/cli/coordination/store.mjs +4 -4
- package/src/cli/dispatch.mjs +2 -0
- package/src/cli/help.mjs +30 -0
- package/src/cli/install/legacy-paths.mjs +2 -0
- package/src/cli/produce/blind-probe.mjs +245 -0
- package/src/cli/produce/claim.mjs +543 -0
- package/src/cli/produce/done-gate.mjs +238 -0
- package/src/cli/produce/events.mjs +131 -0
- package/src/cli/produce/evidence-oracle.mjs +133 -0
- package/src/cli/produce/ledger.mjs +284 -0
- package/src/cli/produce/probe-family.mjs +168 -0
- package/src/cli/produce/projection.mjs +105 -0
- package/src/cli/produce/run-id.mjs +84 -0
- package/src/cli/produce/saga.mjs +303 -0
- package/src/cli/produce/scheduler.mjs +423 -0
- package/src/cli/produce/setpoint.mjs +122 -0
- package/src/cli/produce/verification-ttl.mjs +191 -0
- package/src/cli/roadmap/showrunner-view.d.ts +10 -0
- package/src/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +6 -6
- package/dist/cli/roadmap/conductor-view.d.mts.map +0 -1
- package/dist/cli/roadmap/conductor-view.mjs.map +0 -1
- package/src/cli/roadmap/conductor-view.d.ts +0 -10
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* auto-emit-artifact-ready.mjs — code-enforced plan-ready signal.
|
|
4
4
|
*
|
|
5
5
|
* Promotes the `artifact.ready{kind:'plan'}` emit from a markdown contract
|
|
6
|
-
* in `skills/apt-plan/adapters/
|
|
7
|
-
* postcondition of `apt-tools commit`. This closes the
|
|
6
|
+
* in `skills/apt-plan/adapters/showrunner.md` to a framework-level
|
|
7
|
+
* postcondition of `apt-tools commit`. This closes the Showrunner v2 gap
|
|
8
8
|
* exposed during live verification 2026-05-15: the planner's QUICK /
|
|
9
9
|
* SIMPLE track is hard-exempt from "new interaction discipline"
|
|
10
10
|
* (Aperant Fast Path Guarantee ID-05), so the markdown emit step was
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* OpenCode, Codex) traverses via `apt-tools commit`
|
|
20
20
|
*
|
|
21
21
|
* Conditions for emit (ALL must hold — otherwise no-op):
|
|
22
|
-
* 1. `APERANT_TERMINAL_ID` is set in process.env (
|
|
22
|
+
* 1. `APERANT_TERMINAL_ID` is set in process.env (Showrunner PTY context).
|
|
23
23
|
* 2. The committed files include a path matching
|
|
24
24
|
* `.aperant/tasks/{task-id}/implementation_plan.json`.
|
|
25
25
|
*
|
|
@@ -32,7 +32,7 @@ import { createHash } from 'node:crypto'
|
|
|
32
32
|
import { appendFileSync, mkdirSync, readFileSync } from 'node:fs'
|
|
33
33
|
import { hostname } from 'node:os'
|
|
34
34
|
import { join } from 'node:path'
|
|
35
|
-
import {
|
|
35
|
+
import { validateShowrunnerEvent } from './event-schema.mjs'
|
|
36
36
|
|
|
37
37
|
const PLAN_PATH_RE = /^(?:\.\/)?\.aperant\/tasks\/([^/]+)\/implementation_plan\.json$/
|
|
38
38
|
|
|
@@ -70,7 +70,7 @@ export function maybeAutoEmitPlanReady({ files, projectRoot }) {
|
|
|
70
70
|
terminal_id: terminalId,
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const validation =
|
|
73
|
+
const validation = validateShowrunnerEvent('artifact.ready', data)
|
|
74
74
|
if (!validation.ok) {
|
|
75
75
|
return { emitted: false, reason: `schema violation: ${validation.error}` }
|
|
76
76
|
}
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
export type ValidateResult = { ok: true } | { ok: false; error: string }
|
|
7
7
|
|
|
8
|
-
export function
|
|
8
|
+
export function validateShowrunnerEvent(
|
|
9
9
|
op: string,
|
|
10
10
|
data: Record<string, unknown> | undefined | null,
|
|
11
11
|
): ValidateResult
|
|
12
12
|
|
|
13
|
-
export const
|
|
13
|
+
export const SHOWRUNNER_VALIDATED_OPS: ReadonlySet<string>
|
|
14
|
+
|
|
15
|
+
export const PRODUCE_VALIDATED_OPS: ReadonlySet<string>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @internal
|
|
3
|
-
* event-schema.mjs — single source of truth for
|
|
3
|
+
* event-schema.mjs — single source of truth for showrunner event payload shapes.
|
|
4
4
|
*
|
|
5
5
|
* Why this lives in `framework`, not `core`:
|
|
6
6
|
* `packages/core` depends on `@aperant/framework`. The schema is shared by
|
|
7
7
|
* the CLI write path (`commands/event.mjs`), the framework lifecycle write
|
|
8
8
|
* seam (`coordination/store.mjs:appendEvent`), and the core IPC write seam
|
|
9
|
-
* (`packages/core/src/runtime/orchestration/
|
|
9
|
+
* (`packages/core/src/runtime/orchestration/showrunner/event-log.ts`).
|
|
10
10
|
* Putting it in the lower layer keeps a single rule table that every
|
|
11
11
|
* writer can import.
|
|
12
12
|
*
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
* - `awaiting-input` / `input-rescinded` MUST carry both terminal_id and
|
|
23
23
|
* request_id so the drawer can pair cards strictly.
|
|
24
24
|
* - `artifact.ready{kind:'plan'}` is the canonical plan-completion signal
|
|
25
|
-
* consumed by the
|
|
25
|
+
* consumed by the showrunner's reviewer queue (Step 5's reviewPlan tool).
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
const
|
|
28
|
+
/** Showrunner ops the schema enforces. Other ops pass through unchanged. */
|
|
29
|
+
const SHOWRUNNER_OPS = new Set([
|
|
30
30
|
'phase.changed',
|
|
31
31
|
'artifact.ready',
|
|
32
32
|
'awaiting-input',
|
|
@@ -35,34 +35,120 @@ const CONDUCTOR_OPS = new Set([
|
|
|
35
35
|
'budget.exceeded',
|
|
36
36
|
'terminal.enrolled',
|
|
37
37
|
'terminal.unenrolled',
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
38
|
+
'showrunner.intent',
|
|
39
|
+
'showrunner.cross_check',
|
|
40
|
+
'showrunner.realignment',
|
|
41
41
|
// c-4 (action-capable) — gate verdict + boot-replay audit trail
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
42
|
+
'showrunner.action.executed',
|
|
43
|
+
'showrunner.action.gate_blocked',
|
|
44
|
+
'showrunner.boot_reconciled',
|
|
45
45
|
// AC21 — MCP-server consent decisions audited to .aperant/events/*.jsonl
|
|
46
46
|
'mcp-consent.approved',
|
|
47
47
|
'mcp-consent.denied',
|
|
48
48
|
'mcp-consent.tofu-reprompt',
|
|
49
49
|
])
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Produce outer-loop ops (M1) — the `/apt:produce` roadmap-mutation vocabulary.
|
|
53
|
+
* Kept as a PARALLEL set (not merged into SHOWRUNNER_OPS) so the two surfaces
|
|
54
|
+
* stay conceptually distinct; both are consulted by the same
|
|
55
|
+
* `validateShowrunnerEvent` entry point that `store.appendEvent` calls, so a
|
|
56
|
+
* malformed produce event is rejected fail-closed on the canonical event log
|
|
57
|
+
* (ID-04 / AC4). Every produce op carries a `run_id` tagging its run.
|
|
58
|
+
*/
|
|
59
|
+
const PRODUCE_OPS = new Set([
|
|
60
|
+
'produce.run.started',
|
|
61
|
+
'produce.setpoint.frozen',
|
|
62
|
+
'produce.roadmap.milestone_added',
|
|
63
|
+
'produce.roadmap.milestone_status_changed',
|
|
64
|
+
'produce.tick',
|
|
65
|
+
// M2 — the oracle + held-out cross-family blind-probe forensic trail. Every
|
|
66
|
+
// oracle/probe decision lands on the same append-only log, fail-closed
|
|
67
|
+
// against malformed entries (US-1 / AC1 / AC12). The probe ops are
|
|
68
|
+
// STRUCTURALLY blind: they carry only a hash/result/family, NEVER the probe
|
|
69
|
+
// content (ID-M2-03). The projection still folds `produce.roadmap.*` ONLY,
|
|
70
|
+
// so these never enter the roadmap the Showrunner re-reads each tick.
|
|
71
|
+
'produce.milestone.implemented',
|
|
72
|
+
'produce.probe.frozen',
|
|
73
|
+
'produce.probe.run',
|
|
74
|
+
'produce.oracle.judged',
|
|
75
|
+
'produce.oracle.verdict',
|
|
76
|
+
'produce.oracle.probe_gap',
|
|
77
|
+
// M3 — the Lyapunov acceptance-criteria ledger + scope-change forensic trail.
|
|
78
|
+
// Every criteria-open / criteria-close / scope-change decision lands on the
|
|
79
|
+
// same append-only log, fail-closed against malformed entries (US-4 / AC1). V
|
|
80
|
+
// (open acceptance criteria) = declared − closed, folded by ledger.mjs. The
|
|
81
|
+
// projection still folds `produce.roadmap.*` ONLY — criteria/scope ops are a
|
|
82
|
+
// SEPARATE fold, so the M1/M2 roadmap-blindness invariant is preserved.
|
|
83
|
+
'produce.criteria.declared',
|
|
84
|
+
'produce.criteria.closed',
|
|
85
|
+
'produce.scope.changed',
|
|
86
|
+
// M4 — the saga + verification-TTL forensic trail. Each plan→execute→verify→
|
|
87
|
+
// review→ship phase transition, every FORWARD compensation, every diverse
|
|
88
|
+
// review verdict, and every TTL re-verify / regression lands on the same
|
|
89
|
+
// append-only log, fail-closed against malformed entries (US-2 / AC1). The
|
|
90
|
+
// saga fold is SEPARATE from the roadmap projection (which still folds
|
|
91
|
+
// `produce.roadmap.*` ONLY), so the M1/M2/M3 blindness invariant holds. The
|
|
92
|
+
// saga-phase ops enforce a closed `phase` vocabulary (ALLOWED_SAGA_PHASES),
|
|
93
|
+
// mirroring the phase.changed.to / artifact.ready.kind allowed-value pattern.
|
|
94
|
+
'produce.saga.phase_entered',
|
|
95
|
+
'produce.saga.phase_completed',
|
|
96
|
+
'produce.saga.compensated',
|
|
97
|
+
'produce.saga.reviewed',
|
|
98
|
+
'produce.ttl.reverified',
|
|
99
|
+
'produce.ttl.regression_detected',
|
|
100
|
+
// M5 — the WSJF/WIP scheduler's audited decision. The wake `tick` emits ONE
|
|
101
|
+
// `produce.schedule.computed` alongside its `produce.tick` so the scheduler's
|
|
102
|
+
// pick is a recorded fact on the append-only log (the event-sourced ethos). It
|
|
103
|
+
// uses the `produce.schedule.*` prefix — the roadmap projection folds
|
|
104
|
+
// `produce.roadmap.*` ONLY, so this op NEVER enters the roadmap the Showrunner
|
|
105
|
+
// re-reads (the M1/M2 blindness invariant holds automatically — ID-M5-06).
|
|
106
|
+
'produce.schedule.computed',
|
|
107
|
+
// M6 — the Claim Envelope lifecycle forensic trail. A claim's CONTENT lives in
|
|
108
|
+
// the frozen `claims/<claim-id>.json` file, referenced by `content_hash` — it
|
|
109
|
+
// NEVER touches the log (ID-M6-07, mirrors produce.probe.frozen /
|
|
110
|
+
// produce.setpoint.frozen). `declared` seeds the claim ledger, `expired` drops
|
|
111
|
+
// it from the active set, `consumed` records a bounded down-projected delta
|
|
112
|
+
// (target_kind value-checked against the closed set). The claim ledger is a
|
|
113
|
+
// SEPARATE fold (projectClaims) — the roadmap projection still folds
|
|
114
|
+
// `produce.roadmap.*` ONLY, so these ops NEVER enter the roadmap the Showrunner
|
|
115
|
+
// re-reads (the M1/M2 blindness invariant holds automatically).
|
|
116
|
+
'produce.claim.declared',
|
|
117
|
+
'produce.claim.expired',
|
|
118
|
+
'produce.claim.consumed',
|
|
119
|
+
])
|
|
120
|
+
|
|
51
121
|
/** Allowed values for `phase.changed.to` — PTY busy/idle only. */
|
|
52
122
|
const ALLOWED_PHASE_VALUES = new Set(['busy', 'idle'])
|
|
53
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Allowed values for the saga `phase` on `produce.saga.phase_entered` /
|
|
126
|
+
* `produce.saga.phase_completed` / `produce.saga.compensated` (M4). The saga
|
|
127
|
+
* models plan→execute→verify→review→ship; an out-of-vocabulary phase is rejected
|
|
128
|
+
* fail-closed, mirroring the ALLOWED_PHASE_VALUES value check for phase.changed.
|
|
129
|
+
*/
|
|
130
|
+
const ALLOWED_SAGA_PHASES = new Set(['plan', 'execute', 'verify', 'review', 'ship'])
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Allowed values for the claim `target_kind` on `produce.claim.consumed` (M6).
|
|
134
|
+
* Consumption is a DELTA down-projection onto ONE acceptance-criterion / subtask /
|
|
135
|
+
* proof-obligation (ID-M6-06); an out-of-vocabulary kind is rejected fail-closed,
|
|
136
|
+
* mirroring the ALLOWED_SAGA_PHASES value check for the saga-phase ops.
|
|
137
|
+
*/
|
|
138
|
+
const ALLOWED_CLAIM_TARGET_KINDS = new Set(['acceptance_criterion', 'subtask', 'proof_obligation'])
|
|
139
|
+
|
|
54
140
|
/** Allowed values for `artifact.ready.kind`. */
|
|
55
141
|
const ALLOWED_ARTIFACT_KINDS = new Set(['plan', 'spec', 'build', 'review'])
|
|
56
142
|
|
|
57
143
|
/**
|
|
58
|
-
* Validate the data payload of a
|
|
144
|
+
* Validate the data payload of a showrunner event against the op's contract.
|
|
59
145
|
*
|
|
60
146
|
* @param {string} op
|
|
61
147
|
* @param {Record<string, unknown> | undefined | null} data
|
|
62
148
|
* @returns {{ ok: true } | { ok: false, error: string }}
|
|
63
149
|
*/
|
|
64
|
-
export function
|
|
65
|
-
if (!
|
|
150
|
+
export function validateShowrunnerEvent(op, data) {
|
|
151
|
+
if (!SHOWRUNNER_OPS.has(op) && !PRODUCE_OPS.has(op)) return { ok: true }
|
|
66
152
|
const d = data && typeof data === 'object' ? data : {}
|
|
67
153
|
|
|
68
154
|
switch (op) {
|
|
@@ -105,13 +191,13 @@ export function validateConductorEvent(op, data) {
|
|
|
105
191
|
return { ok: true }
|
|
106
192
|
}
|
|
107
193
|
|
|
108
|
-
case '
|
|
194
|
+
case 'showrunner.intent':
|
|
109
195
|
return requireFields(op, d, ['terminal_id', 'request_id', 'action', 'reasoning'])
|
|
110
196
|
|
|
111
|
-
case '
|
|
197
|
+
case 'showrunner.cross_check':
|
|
112
198
|
return requireFields(op, d, ['terminal_id', 'request_id'])
|
|
113
199
|
|
|
114
|
-
case '
|
|
200
|
+
case 'showrunner.realignment': {
|
|
115
201
|
const r = requireFields(op, d, ['terminal_id', 'request_id_orig'])
|
|
116
202
|
if (!r.ok) return r
|
|
117
203
|
if (d.attempt_n === undefined || d.attempt_n === null)
|
|
@@ -125,10 +211,10 @@ export function validateConductorEvent(op, data) {
|
|
|
125
211
|
case 'budget.exceeded':
|
|
126
212
|
return requireFields(op, d, ['terminal_id'])
|
|
127
213
|
|
|
128
|
-
case '
|
|
214
|
+
case 'showrunner.action.executed':
|
|
129
215
|
return requireFields(op, d, ['terminal_id', 'request_id', 'action_kind', 'idempotency_key'])
|
|
130
216
|
|
|
131
|
-
case '
|
|
217
|
+
case 'showrunner.action.gate_blocked':
|
|
132
218
|
return requireFields(op, d, [
|
|
133
219
|
'terminal_id',
|
|
134
220
|
'request_id',
|
|
@@ -152,7 +238,130 @@ export function validateConductorEvent(op, data) {
|
|
|
152
238
|
'session_id',
|
|
153
239
|
])
|
|
154
240
|
|
|
155
|
-
|
|
241
|
+
// Produce outer-loop (M1) — roadmap-mutation + tick vocabulary. Every
|
|
242
|
+
// op requires its `run_id`; roadmap ops additionally carry the
|
|
243
|
+
// milestone identity / status the projection folds (ID-04 / AC4).
|
|
244
|
+
case 'produce.run.started':
|
|
245
|
+
return requireFields(op, d, ['run_id', 'setpoint_hash'])
|
|
246
|
+
|
|
247
|
+
case 'produce.setpoint.frozen':
|
|
248
|
+
return requireFields(op, d, ['run_id', 'setpoint_hash', 'setpoint_path'])
|
|
249
|
+
|
|
250
|
+
case 'produce.roadmap.milestone_added':
|
|
251
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'title'])
|
|
252
|
+
|
|
253
|
+
case 'produce.roadmap.milestone_status_changed':
|
|
254
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'status'])
|
|
255
|
+
|
|
256
|
+
case 'produce.tick':
|
|
257
|
+
return requireFields(op, d, ['run_id'])
|
|
258
|
+
|
|
259
|
+
// Produce M2 — oracle + held-out cross-family blind-probe vocabulary.
|
|
260
|
+
// The implementer family is the recorded disjointness anchor (ID-M2-02);
|
|
261
|
+
// the probe ops are content-blind (only hash/result/family — ID-M2-03).
|
|
262
|
+
|
|
263
|
+
// The Showrunner records who implemented a milestone once per milestone;
|
|
264
|
+
// the cross-family rule is enforced against THIS recorded fact.
|
|
265
|
+
case 'produce.milestone.implemented':
|
|
266
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'implementer_family'])
|
|
267
|
+
|
|
268
|
+
// The frozen blind-probe SET is announced by hash + author family ONLY —
|
|
269
|
+
// NEVER the probe content (structural probe-blindness, AC5).
|
|
270
|
+
case 'produce.probe.frozen':
|
|
271
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'probe_set_hash', 'author_family'])
|
|
272
|
+
|
|
273
|
+
// A blind-probe RUN carries only its pass/fail result, the running family,
|
|
274
|
+
// and the HEAD sha it ran against — no probe content.
|
|
275
|
+
case 'produce.probe.run':
|
|
276
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'result', 'probe_family', 'head_sha'])
|
|
277
|
+
|
|
278
|
+
// The independent evidence-quality oracle's verdict over verify-proof's
|
|
279
|
+
// captured evidence, tagged with the (cross-family) oracle family.
|
|
280
|
+
case 'produce.oracle.judged':
|
|
281
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'verdict', 'oracle_family'])
|
|
282
|
+
|
|
283
|
+
// The two-gate done verdict (visible AND blind agree) — the ONLY path to
|
|
284
|
+
// `done` (ID-03: the Showrunner never self-attests).
|
|
285
|
+
case 'produce.oracle.verdict':
|
|
286
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'verdict'])
|
|
287
|
+
|
|
288
|
+
// The reward-hacking canary near-miss: visible gate passed, blind gate
|
|
289
|
+
// failed → the milestone stays open (ID-M2-06 / AC9).
|
|
290
|
+
case 'produce.oracle.probe_gap':
|
|
291
|
+
return requireFields(op, d, ['run_id', 'milestone_id'])
|
|
292
|
+
|
|
293
|
+
// Produce M3 — the Lyapunov acceptance-criteria ledger (V = declared −
|
|
294
|
+
// closed) + the scope-change escape hatch (ID-M3-01 / ID-M3-04 / AC1). A
|
|
295
|
+
// criterion binds to a milestone; it opens on `declared` (V += 1), closes
|
|
296
|
+
// on `closed` (V −= 1). `produce.scope.changed` is the ONLY sanctioned
|
|
297
|
+
// post-descent V increase — `milestone_id` is optional (a scope change may
|
|
298
|
+
// not target one milestone), so only `run_id` + `reason` are required.
|
|
299
|
+
case 'produce.criteria.declared':
|
|
300
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'criterion_id', 'text'])
|
|
301
|
+
|
|
302
|
+
case 'produce.criteria.closed':
|
|
303
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'criterion_id'])
|
|
304
|
+
|
|
305
|
+
case 'produce.scope.changed':
|
|
306
|
+
return requireFields(op, d, ['run_id', 'reason'])
|
|
307
|
+
|
|
308
|
+
// Produce M4 — the saga phase model + FORWARD compensators + verification-TTL.
|
|
309
|
+
// The saga-phase ops (entered/completed/compensated) enforce the closed
|
|
310
|
+
// `phase` vocabulary (ALLOWED_SAGA_PHASES), mirroring the phase.changed.to
|
|
311
|
+
// value check. No op names a probe/review CONTENT field — the roadmap
|
|
312
|
+
// projection still folds `produce.roadmap.*` ONLY (blindness preserved).
|
|
313
|
+
case 'produce.saga.phase_entered':
|
|
314
|
+
case 'produce.saga.phase_completed': {
|
|
315
|
+
const r = requireFields(op, d, ['run_id', 'milestone_id', 'phase'])
|
|
316
|
+
if (!r.ok) return r
|
|
317
|
+
return checkSagaPhase(op, d)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
case 'produce.saga.compensated': {
|
|
321
|
+
const r = requireFields(op, d, ['run_id', 'milestone_id', 'phase', 'compensator'])
|
|
322
|
+
if (!r.ok) return r
|
|
323
|
+
return checkSagaPhase(op, d)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// A diverse-review verdict over the milestone's diff, tagged with the
|
|
327
|
+
// (cross-family) reviewer family. Content-free — verdict + family only.
|
|
328
|
+
case 'produce.saga.reviewed':
|
|
329
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'reviewer_family', 'verdict'])
|
|
330
|
+
|
|
331
|
+
// A scheduled post-`done` TTL re-verify RUN against HEAD — result/head_sha
|
|
332
|
+
// only, never probe content. A regression fires the forward compensator.
|
|
333
|
+
case 'produce.ttl.reverified':
|
|
334
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'head_sha', 'result'])
|
|
335
|
+
|
|
336
|
+
case 'produce.ttl.regression_detected':
|
|
337
|
+
return requireFields(op, d, ['run_id', 'milestone_id', 'head_sha'])
|
|
338
|
+
|
|
339
|
+
// Produce M5 — the WSJF/WIP scheduler's recorded pick. Only `run_id` is
|
|
340
|
+
// required (the `picked` ids + `wip_limit` are optional context); the
|
|
341
|
+
// roadmap projection folds `produce.roadmap.*` ONLY, so it never sees this
|
|
342
|
+
// op (blindness preserved — ID-M5-06).
|
|
343
|
+
case 'produce.schedule.computed':
|
|
344
|
+
return requireFields(op, d, ['run_id'])
|
|
345
|
+
|
|
346
|
+
// Produce M6 — the Claim Envelope lifecycle. `declared` carries a
|
|
347
|
+
// `content_hash` ONLY (the full envelope lives in the frozen
|
|
348
|
+
// claims/<claim-id>.json file — ID-M6-07); `consumed.target_kind` is
|
|
349
|
+
// value-checked against the closed set (mirrors ALLOWED_SAGA_PHASES /
|
|
350
|
+
// checkSagaPhase). No op names a claim-content field — the roadmap
|
|
351
|
+
// projection still folds `produce.roadmap.*` ONLY (blindness preserved).
|
|
352
|
+
case 'produce.claim.declared':
|
|
353
|
+
return requireFields(op, d, ['run_id', 'profile', 'claim_id', 'content_hash'])
|
|
354
|
+
|
|
355
|
+
case 'produce.claim.expired':
|
|
356
|
+
return requireFields(op, d, ['run_id', 'claim_id', 'reason'])
|
|
357
|
+
|
|
358
|
+
case 'produce.claim.consumed': {
|
|
359
|
+
const r = requireFields(op, d, ['run_id', 'claim_id', 'target_kind'])
|
|
360
|
+
if (!r.ok) return r
|
|
361
|
+
return checkClaimTargetKind(op, d)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
case 'showrunner.boot_reconciled': {
|
|
156
365
|
// Fleet-wide event — numeric fields only. All optional but if
|
|
157
366
|
// present must be finite numbers (zero allowed).
|
|
158
367
|
const numFields = ['cleaned_leases', 'replayed', 'start_offset']
|
|
@@ -174,7 +383,10 @@ export function validateConductorEvent(op, data) {
|
|
|
174
383
|
}
|
|
175
384
|
|
|
176
385
|
/** Set of ops the schema validates — exported for test enumeration. */
|
|
177
|
-
export const
|
|
386
|
+
export const SHOWRUNNER_VALIDATED_OPS = SHOWRUNNER_OPS
|
|
387
|
+
|
|
388
|
+
/** Produce outer-loop ops the schema validates — exported for test enumeration. */
|
|
389
|
+
export const PRODUCE_VALIDATED_OPS = PRODUCE_OPS
|
|
178
390
|
|
|
179
391
|
/**
|
|
180
392
|
* @param {string} op
|
|
@@ -191,3 +403,46 @@ function requireFields(op, d, fields) {
|
|
|
191
403
|
if (missing.length === 0) return { ok: true }
|
|
192
404
|
return { ok: false, error: `${op} missing required field(s): ${missing.join(', ')}` }
|
|
193
405
|
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Validate the saga `phase` value against ALLOWED_SAGA_PHASES (M4). Mirrors the
|
|
409
|
+
* inline phase.changed.to value check — fail-closed on an out-of-vocabulary
|
|
410
|
+
* phase so a saga event can never carry an unknown phase onto the log.
|
|
411
|
+
*
|
|
412
|
+
* @param {string} op
|
|
413
|
+
* @param {Record<string, unknown>} d
|
|
414
|
+
* @returns {{ ok: true } | { ok: false, error: string }}
|
|
415
|
+
*/
|
|
416
|
+
function checkSagaPhase(op, d) {
|
|
417
|
+
if (!ALLOWED_SAGA_PHASES.has(String(d.phase))) {
|
|
418
|
+
return {
|
|
419
|
+
ok: false,
|
|
420
|
+
error: `${op}.phase must be one of [${[...ALLOWED_SAGA_PHASES].join(', ')}], got: ${String(
|
|
421
|
+
d.phase,
|
|
422
|
+
)}`,
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return { ok: true }
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Validate the claim `target_kind` value against ALLOWED_CLAIM_TARGET_KINDS (M6).
|
|
430
|
+
* Mirrors checkSagaPhase — fail-closed on an out-of-vocabulary target kind so a
|
|
431
|
+
* produce.claim.consumed event can never carry an unknown delta target onto the
|
|
432
|
+
* log (ID-M6-06).
|
|
433
|
+
*
|
|
434
|
+
* @param {string} op
|
|
435
|
+
* @param {Record<string, unknown>} d
|
|
436
|
+
* @returns {{ ok: true } | { ok: false, error: string }}
|
|
437
|
+
*/
|
|
438
|
+
function checkClaimTargetKind(op, d) {
|
|
439
|
+
if (!ALLOWED_CLAIM_TARGET_KINDS.has(String(d.target_kind))) {
|
|
440
|
+
return {
|
|
441
|
+
ok: false,
|
|
442
|
+
error: `${op}.target_kind must be one of [${[...ALLOWED_CLAIM_TARGET_KINDS].join(
|
|
443
|
+
', ',
|
|
444
|
+
)}], got: ${String(d.target_kind)}`,
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return { ok: true }
|
|
448
|
+
}
|
|
@@ -32,7 +32,7 @@ import { withFileLock } from '../util/fs-lock.mjs'
|
|
|
32
32
|
import { atomicWriteJson } from '../util/io.mjs'
|
|
33
33
|
import { getAgentIdentity, resolveSharedRoot } from './agent-identity.mjs'
|
|
34
34
|
import { appendLifecycleEvent } from './event-log.mjs'
|
|
35
|
-
import {
|
|
35
|
+
import { validateShowrunnerEvent } from './event-schema.mjs'
|
|
36
36
|
import { advanceLastSeen as lastSeenAdvance, readLastSeen as lastSeenRead } from './last-seen.mjs'
|
|
37
37
|
import {
|
|
38
38
|
listActive as teamStatusListActive,
|
|
@@ -131,16 +131,16 @@ export function createCoordinationStore(projectRoot) {
|
|
|
131
131
|
* call via appendLifecycleEvent. Best-effort: filesystem errors are
|
|
132
132
|
* swallowed so a missing events/ dir never breaks task lifecycle.
|
|
133
133
|
*
|
|
134
|
-
* Step 1 — schema gate:
|
|
134
|
+
* Step 1 — schema gate: showrunner ops written via the store seam are
|
|
135
135
|
* validated against `event-schema.mjs` before they reach disk.
|
|
136
136
|
* Schema violations throw (caught here and surfaced via console.warn)
|
|
137
|
-
* because a malformed
|
|
137
|
+
* because a malformed showrunner event would silently break the
|
|
138
138
|
* drawer's pairing logic — we want it loud, not best-effort.
|
|
139
139
|
*/
|
|
140
140
|
appendEvent(evt) {
|
|
141
141
|
try {
|
|
142
142
|
if (evt && typeof evt.op === 'string') {
|
|
143
|
-
const validation =
|
|
143
|
+
const validation = validateShowrunnerEvent(evt.op, evt.data)
|
|
144
144
|
if (!validation.ok) {
|
|
145
145
|
console.warn(`[store.appendEvent] schema violation: ${validation.error}`)
|
|
146
146
|
return null
|
package/src/cli/dispatch.mjs
CHANGED
|
@@ -78,6 +78,7 @@ import { cmdPersonas } from './commands/personas.mjs'
|
|
|
78
78
|
import { cmdPlanApproval } from './commands/plan-approval.mjs'
|
|
79
79
|
import { cmdPrReview } from './commands/pr-review.mjs'
|
|
80
80
|
import { cmdPrecompactHook } from './commands/precompact-hook.mjs'
|
|
81
|
+
import { cmdProduce } from './commands/produce.mjs'
|
|
81
82
|
import { cmdProductContext } from './commands/product-context.mjs'
|
|
82
83
|
import { cmdProfile } from './commands/profile.mjs'
|
|
83
84
|
// cmdRecipeDiff — loaded lazily in the dispatch handler (Fast Path PRF-001)
|
|
@@ -326,6 +327,7 @@ export const DISPATCH = {
|
|
|
326
327
|
team: (args) => wrap(cmdTeam)(args[1], args[2], args.slice(3)),
|
|
327
328
|
active: (args) => wrap(cmdActive)(args[1], args[2], args.slice(3)),
|
|
328
329
|
roadmap: (args) => wrap(cmdRoadmap)(args[1], args[2], args.slice(3)),
|
|
330
|
+
produce: (args) => wrap(cmdProduce)(args[1], args[2], args.slice(3)),
|
|
329
331
|
seed: (args) => wrap(cmdSeed)(args[1], args[2], args.slice(3)),
|
|
330
332
|
workflow: (args) => wrap(cmdWorkflow)(args[1], args[2], args.slice(3)),
|
|
331
333
|
'pr-review': (args) => wrap(cmdPrReview)(args[1], args[2], args.slice(3)),
|
package/src/cli/help.mjs
CHANGED
|
@@ -29,6 +29,7 @@ Commands:
|
|
|
29
29
|
risk-check <dir> --paths <p1> [--operation <type>] Classify file paths by risk level
|
|
30
30
|
|
|
31
31
|
task create <dir> --description <text> [--scope <s>] [--milestone <id>] [--phase <id>] [--roadmap-ref-url <url>] [--depends-on <refs>] [--track <T>] [--autonomy <N>] Create isolated task
|
|
32
|
+
task ensure <dir> --description <text> --intent <create-new|require-existing|self-managed|none> [--track <T>] [--autonomy <N>] [--scope <s>] [--id <id>] Deterministic idempotent allocator: create-new provisions a per-task worktree (idempotent on re-run), require-existing resolves the active task without minting, none/self-managed allocate nothing
|
|
32
33
|
task list <dir> [--scope <s>] [--blocked-by <id>] List active tasks (optionally filtered)
|
|
33
34
|
task get <dir> --id <task-id> Get task details and artifacts
|
|
34
35
|
task update <dir> --id <id> [--lifecycle-phase <p>] [--pr-url <url>] [--subtasks-total <N>] [--depends-on <refs>] Update non-linkage task state; --pr-url may arm ci-watch per ci_watch.after_ship
|
|
@@ -136,6 +137,35 @@ Commands:
|
|
|
136
137
|
ci-watch start|stop|status|tick <dir> [--pr <N>] [...] /apt:watch-ci primitives — see SKILL.md for full flag matrix
|
|
137
138
|
ci-watch sweep <dir> --orphaned [--dry-run] BUG-027: enumerate ci-watches state files, query gh per PR, remove terminal-state (MERGED|CLOSED) entries (manual GC; rate-limited)
|
|
138
139
|
|
|
140
|
+
produce start <dir> --outcome "<o>" [--run-id <id>] /apt:produce M1 — freeze an immutable acceptance setpoint under .aperant/produce/<run-id>/ (idempotent-reuse on --run-id, never overwrites); emits produce.run.started + produce.setpoint.frozen
|
|
141
|
+
produce add-milestone <dir> --run-id <id> --title "<t>" [--id <mid>] Append produce.roadmap.milestone_added + refresh the derived roadmap.json projection cache
|
|
142
|
+
produce set-milestone-status <dir> --run-id <id> --milestone <mid> --status <planned|in_progress|done> [--verdict-path <p>] Append produce.roadmap.milestone_status_changed; --status done is the M2 two-gate adjudication (visible oracle AND blind probe)
|
|
143
|
+
produce status <dir> --run-id <id> Re-project the roadmap from the append-only event log (no in-memory authority)
|
|
144
|
+
produce tick <dir> --run-id <id> Run exactly ONE wake tick — re-project from disk, emit produce.tick, compute next_action + next_tick_hint, then exit (no loop)
|
|
145
|
+
produce record-implementer <dir> --run-id <id> --milestone <mid> --implementer-family <fam> /apt:produce M2 — record the implementer family (the cross-family disjointness anchor)
|
|
146
|
+
produce resolve-probe-family <dir> --run-id <id> [--milestone <mid>] [--implementer-family <fam>] [--host-family <fam>] [--available-families a,b,c] M2 — resolve a probe/oracle family DISJOINT from the implementer + a LIVE model (never hardcoded); available:false when none
|
|
147
|
+
produce oracle prepare <dir> --run-id <id> --milestone <mid> --verdict-path <p> M2 — extract verify-proof's v2 verdict (must be approved) + tests[] evidence into a cross-family judge payload
|
|
148
|
+
produce oracle record <dir> --run-id <id> --milestone <mid> --verdict <pass|fail> --oracle-family <fam> M2 — record produce.oracle.judged (refused when oracle_family === implementer)
|
|
149
|
+
produce probe freeze <dir> --run-id <id> --milestone <mid> --probe-file <p> --author-family <fam> M2 — freeze an immutable held-out probe set (hash + family only; refused when author_family === implementer)
|
|
150
|
+
produce probe record <dir> --run-id <id> --milestone <mid> --result <pass|fail> --probe-family <fam> --head-sha <sha> M2 — record produce.probe.run (result/family/sha only; refused when probe_family === implementer)
|
|
151
|
+
produce probe sweep <dir> --run-id <id> [--sample N] M2 — deterministic rotating sample of already-done milestones to blind-re-probe against HEAD
|
|
152
|
+
produce canary <dir> --run-id <id> M2 — green-on-visible MINUS green-on-blind + per-milestone breakdown (the reward-hacking canary)
|
|
153
|
+
produce declare-criteria <dir> --run-id <id> --milestone <mid> --criterion "<text>" [--criterion-id <cid>] [--scope-change "<reason>"] /apt:produce M3 — open one acceptance criterion (V += 1); rejected after descent unless --scope-change justifies the increase (anti-windup)
|
|
154
|
+
produce progress <dir> --run-id <id> M3 — re-read the Lyapunov V-series from the log: open-criteria count strictly decreasing across shipped milestones + any un-sanctioned-increase violations (flags, never rejects)
|
|
155
|
+
produce saga enter <dir> --run-id <id> --milestone <mid> --phase <plan|execute|verify|review|ship> /apt:produce M4 — append produce.saga.phase_entered (separate fold from the roadmap projection)
|
|
156
|
+
produce saga complete <dir> --run-id <id> --milestone <mid> --phase <plan|execute|verify|review|ship> M4 — append produce.saga.phase_completed
|
|
157
|
+
produce saga compensate <dir> --run-id <id> --milestone <mid> --phase <p> [--reason "<r>"] M4 — fire the FORWARD compensator (verify|review|ship ships a revert + reopens + re-plans; NEVER rolls back a merged PR); records the descriptor, does not execute it
|
|
158
|
+
produce saga resolve-reviewer <dir> --run-id <id> --milestone <mid> [--host-family <fam>] [--available-families a,b,c] M4 — resolve a REVIEW-phase reviewer family DISJOINT from the implementer + a LIVE model (reuses resolveProbeFamily; never hardcoded); available:false when none
|
|
159
|
+
produce saga review <dir> --run-id <id> --milestone <mid> --verdict <pass|fail> --reviewer-family <fam> M4 — record produce.saga.reviewed (refused when reviewer_family === implementer)
|
|
160
|
+
produce saga status <dir> --run-id <id> M4 — re-project per-milestone saga phase state + pending compensation from the log (no roadmap status mutation)
|
|
161
|
+
produce ttl select <dir> --run-id <id> --head-sha <sha> [--sample N] M4 — deterministic rotating sample of OLD done milestones STALE against HEAD (reuses the M2 rotation; a milestone re-verified against current HEAD is excluded as fresh)
|
|
162
|
+
produce ttl reverify <dir> --run-id <id> --milestone <mid> --result <pass|fail> --probe-family <fam> --head-sha <sha> M4 — cross-family re-verify; --result fail appends ttl.reverified + ttl.regression_detected + fires the FORWARD compensator (ships a revert, not a rollback)
|
|
163
|
+
produce schedule <dir> --run-id <id> [--wip N] /apt:produce M5 — WSJF-rank the ready milestones (cost-of-delay / job-size) + a WIP-limited pick; dependency-aware readiness (blocked / cycle), M4-regression re-entry; read-only
|
|
164
|
+
produce claim declare <dir> --run-id <id> --profile <p> --claim-file <path> [--claim-id <id>] /apt:produce M6 — validate + freeze an immutable Claim Envelope to claims/<claim-id>.json (interop, not a 4th store); rejects a global/unbounded scope, empty preconditions, or missing expiry fail-closed; logs produce.claim.declared (content_hash only)
|
|
165
|
+
produce claim list <dir> --run-id <id> M6 — re-project the claim ledger (declared − expired) folded from the append-only log; produce.claim.* never enters the roadmap projection
|
|
166
|
+
produce claim expire <dir> --run-id <id> --claim-id <id> [--reason "<r>"] M6 — append produce.claim.expired; the claim drops out of the ledger's active set (anti-corrosion manual expiry)
|
|
167
|
+
produce claim consume <dir> --run-id <id> [--milestone <mid>] M6 — emit the STRUCTURED delta {claim_id, targets:[{kind, requirement, ref?}]} derived from resolution_verifier (never a lesson-text paste); skips expired / HEAD-invalidated / precondition-unmatched claims
|
|
168
|
+
|
|
139
169
|
followups check <dir> --task-id <id> G45: derive the expected follow-up universe (Out of Scope ∪ raw review rows ∪ qa findings) + report missing/unadjudicated/unfixed/undispositioned rows; exit 1 when the ledger is dishonest
|
|
140
170
|
followups disposition <dir> --task-id <id> --row <row-id> --kind <filed_task|executed_commit|parked_note|dropped_by_user> --ref <ref> [--reason <text>] G45: flip a ledger row to dispositioned (atomic; dropped_by_user requires --reason)
|
|
141
171
|
followups policy <dir> --task-id <id> G45: effective disposition policy (ask|file|chain + max_chain_depth) from config.followups when set, else autonomy-derived
|
|
@@ -108,6 +108,7 @@ export const LEGACY_INSTALL_PATHS = Object.freeze({
|
|
|
108
108
|
'agents/apt-personas.md',
|
|
109
109
|
'agents/apt-plan.md',
|
|
110
110
|
'agents/apt-pr-review.md',
|
|
111
|
+
'agents/apt-produce.md',
|
|
111
112
|
'agents/apt-prototype.md',
|
|
112
113
|
'agents/apt-quick.md',
|
|
113
114
|
'agents/apt-release-notes.md',
|
|
@@ -153,6 +154,7 @@ export const LEGACY_INSTALL_PATHS = Object.freeze({
|
|
|
153
154
|
'commands/apt-personas.md',
|
|
154
155
|
'commands/apt-plan.md',
|
|
155
156
|
'commands/apt-pr-review.md',
|
|
157
|
+
'commands/apt-produce.md',
|
|
156
158
|
'commands/apt-prototype.md',
|
|
157
159
|
'commands/apt-quick.md',
|
|
158
160
|
'commands/apt-release-notes.md',
|