wicked-crew 0.7.1 → 0.7.3
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/dist/api/delivery-index.d.ts +61 -0
- package/dist/api/delivery-index.d.ts.map +1 -0
- package/dist/api/delivery-index.js +87 -0
- package/dist/api/delivery-index.js.map +1 -0
- package/dist/api/governance-steering.d.ts +139 -0
- package/dist/api/governance-steering.d.ts.map +1 -0
- package/dist/api/governance-steering.js +302 -0
- package/dist/api/governance-steering.js.map +1 -0
- package/dist/api/governance-wiki.d.ts +28 -0
- package/dist/api/governance-wiki.d.ts.map +1 -0
- package/dist/api/governance-wiki.js +97 -0
- package/dist/api/governance-wiki.js.map +1 -0
- package/dist/api/routes.d.ts +21 -16
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +196 -10
- package/dist/api/routes.js.map +1 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +56 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/testing.d.ts +117 -0
- package/dist/api/testing.d.ts.map +1 -0
- package/dist/api/testing.js +152 -0
- package/dist/api/testing.js.map +1 -0
- package/dist/campaign/supervision.d.ts +296 -0
- package/dist/campaign/supervision.d.ts.map +1 -0
- package/dist/campaign/supervision.js +515 -0
- package/dist/campaign/supervision.js.map +1 -0
- package/dist/campaigns/plan.d.ts +64 -0
- package/dist/campaigns/plan.d.ts.map +1 -0
- package/dist/campaigns/plan.js +201 -0
- package/dist/campaigns/plan.js.map +1 -0
- package/dist/campaigns/routes.d.ts +28 -0
- package/dist/campaigns/routes.d.ts.map +1 -0
- package/dist/campaigns/routes.js +177 -0
- package/dist/campaigns/routes.js.map +1 -0
- package/dist/core/adapter.d.ts +160 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +300 -1
- package/dist/core/adapter.js.map +1 -1
- package/dist/projects/routes.d.ts +4 -4
- package/dist/qe/acceptance.d.ts +20 -1
- package/dist/qe/acceptance.d.ts.map +1 -1
- package/dist/qe/acceptance.js +32 -0
- package/dist/qe/acceptance.js.map +1 -1
- package/dist/qe/conformance.d.ts +158 -0
- package/dist/qe/conformance.d.ts.map +1 -0
- package/dist/qe/conformance.js +244 -0
- package/dist/qe/conformance.js.map +1 -0
- package/dist/studio/assets/index-BAW9rqNT.css +32 -0
- package/dist/studio/assets/index-UahdRwF7.js +532 -0
- package/dist/studio/index.html +2 -2
- package/dist/studio/testid-inventory.json +4387 -0
- package/endpoint-manifest.json +154 -9
- package/package.json +3 -3
- package/dist/studio/assets/index-D-BFUYnY.js +0 -530
- package/dist/studio/assets/index-D6S9zUtO.css +0 -32
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenario → CampaignNode mapping (TH-9; DES-CAMPAIGN-001 §8).
|
|
3
|
+
*
|
|
4
|
+
* `POST /campaigns` accepts a batch of SCENARIOS (the qe-campaign vocabulary: garden's
|
|
5
|
+
* campaign-recon rungs, or any caller's batch of checks) and this module maps them onto the
|
|
6
|
+
* engine's `CampaignDef` — nodes, `on_success`/`on_terminal` edges, and one composed
|
|
7
|
+
* single-phase workflow per deterministic scenario. Pure data-in/data-out: no engine handle,
|
|
8
|
+
* no I/O, so every rule below is unit-testable without spawning a Core.
|
|
9
|
+
*
|
|
10
|
+
* ## The two scenario shapes, and where the work actually lives
|
|
11
|
+
*
|
|
12
|
+
* - **`tool` (deterministic)** — the scenario is a spec FILE (garden's runner spec, a script,
|
|
13
|
+
* any argv-runnable check) and the node's workflow is one Tool-executor phase running that
|
|
14
|
+
* argv verbatim: no council, no LLM, near-zero cost. The engine's Tool path (`run_tool_cmd`)
|
|
15
|
+
* spawns the command directly.
|
|
16
|
+
* - **`agent` (exploratory / authoring)** — a governed agent run over a problem statement;
|
|
17
|
+
* seats are spent only where judgment is the work (test-R9).
|
|
18
|
+
*
|
|
19
|
+
* ## The 1022-byte rule (load-bearing, enforced here)
|
|
20
|
+
*
|
|
21
|
+
* PTY worker prompts longer than 1022 bytes are SILENTLY DISCARDED by the canonical line
|
|
22
|
+
* discipline — the worker waits on input that never arrives and the unit burns its full
|
|
23
|
+
* timeout (the S8 campaign finding; memory: "PTY canonical line limit"). The mapping
|
|
24
|
+
* therefore refuses, loudly and per-token, anything that smells like a scenario BODY inlined
|
|
25
|
+
* where a FILE PATH belongs: every Tool argv token and every agent problem statement must be
|
|
26
|
+
* a single line of at most {@link MAX_INLINE_BYTES} bytes. The fix is always the same and the
|
|
27
|
+
* error says it: persist the content as a file and pass its path.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Byte ceiling for a single inline string handed to a node (a Tool argv token, an agent
|
|
31
|
+
* problem). 1022 is the PTY canonical-line limit — the longest line a worker's stdin
|
|
32
|
+
* accepts before the kernel silently discards it. Tool argv does not itself traverse a PTY,
|
|
33
|
+
* but the ceiling is enforced uniformly because the failure it guards against is the same
|
|
34
|
+
* SHAPE either way: scenario bodies belong in files, and a token this long is a body.
|
|
35
|
+
*/
|
|
36
|
+
export const MAX_INLINE_BYTES = 1022;
|
|
37
|
+
/** id rule for campaigns and scenarios: overlay-file-safe, run-id-safe (no `:` — the engine
|
|
38
|
+
* keys node run ids `{campaign}:{node}:a{attempt}`), and short enough that the composed
|
|
39
|
+
* workflow id (`campaign-<campaign>-<scenario>`) stays under core's 128-char id cap. */
|
|
40
|
+
const SAFE_ID = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
41
|
+
const MAX_CAMPAIGN_ID = 64;
|
|
42
|
+
const MAX_SCENARIO_ID = 48;
|
|
43
|
+
/** Composed node workflows carry this prefix — the adapter keeps them OUT of the workflow
|
|
44
|
+
* catalog (`listWorkflows`) while still persisting them to the overlay dir so a fresh-process
|
|
45
|
+
* `resumeCampaign` can re-dispatch pending nodes by workflow id. */
|
|
46
|
+
export const CAMPAIGN_WORKFLOW_PREFIX = 'campaign-';
|
|
47
|
+
/** The composed workflow id for one deterministic scenario node. */
|
|
48
|
+
export function scenarioWorkflowId(campaignId, scenarioId) {
|
|
49
|
+
return `${CAMPAIGN_WORKFLOW_PREFIX}${campaignId}-${scenarioId}`;
|
|
50
|
+
}
|
|
51
|
+
/** Throw with the scenario + token named when an inline string breaks the single-line /
|
|
52
|
+
* byte-ceiling rule. One spelling of the rule for both scenario shapes. */
|
|
53
|
+
function assertInline(scenarioId, what, value) {
|
|
54
|
+
if (/[\r\n]/.test(value)) {
|
|
55
|
+
throw new Error(`scenario '${scenarioId}': ${what} contains a newline — scenario bodies are never ` +
|
|
56
|
+
'inlined; persist the content as a file and pass its path');
|
|
57
|
+
}
|
|
58
|
+
const bytes = Buffer.byteLength(value, 'utf8');
|
|
59
|
+
if (bytes > MAX_INLINE_BYTES) {
|
|
60
|
+
throw new Error(`scenario '${scenarioId}': ${what} is ${bytes} bytes — over the ${MAX_INLINE_BYTES}-byte ` +
|
|
61
|
+
'PTY canonical-line limit (longer input is SILENTLY DISCARDED and the unit burns its ' +
|
|
62
|
+
'timeout). Persist the content as a file and pass its path instead');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** The single Tool-executor phase of a deterministic scenario node.
|
|
66
|
+
*
|
|
67
|
+
* `verified_evidence: false`, deliberately (contrast `core/deliver.ts`, which arms the built-in
|
|
68
|
+
* evidence floor): that floor re-derives "done" from a WORKTREE DIFF, and a scenario run —
|
|
69
|
+
* probing an API, reading state — legitimately leaves none, so arming it would deny every
|
|
70
|
+
* honest PASS. The executor's exit status is an executor CLAIM, not a verdict; grading belongs
|
|
71
|
+
* to the qe accept trio (garden TH-10) and the acceptance gate re-derives "done" from ledger
|
|
72
|
+
* rows (TH-6). `executes_code: false` for the same reason as the deliver phase: deterministic
|
|
73
|
+
* tooling, not governed agent work.
|
|
74
|
+
*/
|
|
75
|
+
function toolPhase(cmd) {
|
|
76
|
+
return {
|
|
77
|
+
id: 'execute',
|
|
78
|
+
kind: 'test',
|
|
79
|
+
executor: { type: 'tool', cmd },
|
|
80
|
+
gate_type: null,
|
|
81
|
+
gate: 'auto',
|
|
82
|
+
executes_code: false,
|
|
83
|
+
verified_evidence: false,
|
|
84
|
+
required_deliverables: [],
|
|
85
|
+
depends_on: [],
|
|
86
|
+
role: 'neutral',
|
|
87
|
+
skill_ref: null,
|
|
88
|
+
allowed_skills: [],
|
|
89
|
+
validator_pin: null,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Map a `POST /campaigns` body onto the engine's `CampaignDef` + the per-node workflows to arm.
|
|
94
|
+
*
|
|
95
|
+
* Throws a plain `Error` (the route answers 400 with the message) on: a malformed campaign or
|
|
96
|
+
* scenario id, a duplicate scenario id, a scenario with neither/both of `tool`/`agent`, an
|
|
97
|
+
* empty argv, an inline-rule break ({@link assertInline}), an unknown/self/duplicate dep, or an
|
|
98
|
+
* `agent.workflow` that is itself a composed campaign workflow. Cycles are LEFT to the engine's
|
|
99
|
+
* own launch validation — one authority for graph shape, and its reject arrives before anything
|
|
100
|
+
* persists.
|
|
101
|
+
*
|
|
102
|
+
* `defaultClis` is the parsed council roster used for every node that does not carry its own —
|
|
103
|
+
* Tool nodes never convene it (the phase bypasses the council), agent nodes do.
|
|
104
|
+
*/
|
|
105
|
+
export function buildCampaign(body, defaultClis) {
|
|
106
|
+
const campaignId = body.id ?? `campaign-${Date.now().toString(36)}`;
|
|
107
|
+
if (!SAFE_ID.test(campaignId) || campaignId.length > MAX_CAMPAIGN_ID) {
|
|
108
|
+
throw new Error(`campaign id '${campaignId}' must start with a letter/digit, contain only letters, ` +
|
|
109
|
+
`digits, dots, hyphens, and underscores, and be at most ${MAX_CAMPAIGN_ID} chars`);
|
|
110
|
+
}
|
|
111
|
+
if (body.scenarios.length === 0) {
|
|
112
|
+
throw new Error('a campaign needs at least one scenario');
|
|
113
|
+
}
|
|
114
|
+
const ids = new Set();
|
|
115
|
+
for (const s of body.scenarios) {
|
|
116
|
+
if (!SAFE_ID.test(s.id) || s.id.length > MAX_SCENARIO_ID) {
|
|
117
|
+
throw new Error(`scenario id '${s.id}' must start with a letter/digit, contain only letters, digits, ` +
|
|
118
|
+
`dots, hyphens, and underscores, and be at most ${MAX_SCENARIO_ID} chars`);
|
|
119
|
+
}
|
|
120
|
+
if (ids.has(s.id))
|
|
121
|
+
throw new Error(`duplicate scenario id '${s.id}'`);
|
|
122
|
+
ids.add(s.id);
|
|
123
|
+
}
|
|
124
|
+
const nodes = [];
|
|
125
|
+
const edges = [];
|
|
126
|
+
const workflows = [];
|
|
127
|
+
for (const s of body.scenarios) {
|
|
128
|
+
nodes.push(buildNode(campaignId, s, defaultClis, workflows));
|
|
129
|
+
const seenDeps = new Set();
|
|
130
|
+
for (const dep of s.deps ?? []) {
|
|
131
|
+
if (dep === s.id)
|
|
132
|
+
throw new Error(`scenario '${s.id}' depends on itself`);
|
|
133
|
+
if (!ids.has(dep)) {
|
|
134
|
+
throw new Error(`scenario '${s.id}' depends on unknown scenario '${dep}'`);
|
|
135
|
+
}
|
|
136
|
+
if (seenDeps.has(dep)) {
|
|
137
|
+
throw new Error(`scenario '${s.id}' names dep '${dep}' twice`);
|
|
138
|
+
}
|
|
139
|
+
seenDeps.add(dep);
|
|
140
|
+
edges.push({ from: dep, to: s.id, condition: s.depsCondition ?? 'on_success' });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
def: {
|
|
145
|
+
id: campaignId,
|
|
146
|
+
name: body.name ?? campaignId,
|
|
147
|
+
nodes,
|
|
148
|
+
edges,
|
|
149
|
+
policy: body.policy ?? 'continue_independent',
|
|
150
|
+
max_concurrency: body.maxConcurrency ?? 2,
|
|
151
|
+
},
|
|
152
|
+
workflows,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/** One scenario → one node; a `tool` scenario also appends its composed workflow. */
|
|
156
|
+
function buildNode(campaignId, s, defaultClis, workflows) {
|
|
157
|
+
if ((s.tool === undefined) === (s.agent === undefined)) {
|
|
158
|
+
throw new Error(`scenario '${s.id}' must carry exactly one of 'tool' (deterministic argv) or 'agent' ` +
|
|
159
|
+
'(governed problem statement)');
|
|
160
|
+
}
|
|
161
|
+
// The node's problem is a LABEL — what the scoreboard and the run list show — never the work.
|
|
162
|
+
const label = s.title ?? s.id;
|
|
163
|
+
assertInline(s.id, 'title', label);
|
|
164
|
+
if (s.tool !== undefined) {
|
|
165
|
+
if (s.tool.cmd.length === 0) {
|
|
166
|
+
throw new Error(`scenario '${s.id}': tool.cmd is empty — nothing to execute`);
|
|
167
|
+
}
|
|
168
|
+
s.tool.cmd.forEach((token, i) => assertInline(s.id, `tool.cmd[${i}]`, token));
|
|
169
|
+
const wfId = scenarioWorkflowId(campaignId, s.id);
|
|
170
|
+
workflows.push({ id: wfId, phases: [toolPhase(s.tool.cmd)] });
|
|
171
|
+
return {
|
|
172
|
+
node_id: s.id,
|
|
173
|
+
run_spec: {
|
|
174
|
+
problem: label,
|
|
175
|
+
clis: defaultClis,
|
|
176
|
+
entity_mode: 'shared',
|
|
177
|
+
workflow_id: wfId,
|
|
178
|
+
...(s.repoRef !== undefined ? { repo_ref: s.repoRef } : {}),
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const agent = s.agent;
|
|
183
|
+
assertInline(s.id, 'agent.problem', agent.problem);
|
|
184
|
+
if (agent.workflow !== undefined && agent.workflow.startsWith(CAMPAIGN_WORKFLOW_PREFIX)) {
|
|
185
|
+
// A composed node workflow is private to its node — pointing a second node at one would
|
|
186
|
+
// couple two nodes through an artifact the catalog deliberately hides.
|
|
187
|
+
throw new Error(`scenario '${s.id}': agent.workflow must name a registered workflow, not a composed ` +
|
|
188
|
+
`'${CAMPAIGN_WORKFLOW_PREFIX}*' one`);
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
node_id: s.id,
|
|
192
|
+
run_spec: {
|
|
193
|
+
problem: agent.problem,
|
|
194
|
+
clis: defaultClis,
|
|
195
|
+
entity_mode: 'shared',
|
|
196
|
+
...(agent.workflow !== undefined ? { workflow_id: agent.workflow } : {}),
|
|
197
|
+
...(s.repoRef !== undefined ? { repo_ref: s.repoRef } : {}),
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/campaigns/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAYH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC;;yFAEyF;AACzF,MAAM,OAAO,GAAG,8BAA8B,CAAC;AAC/C,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B;;qEAEqE;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,CAAC;AAEpD,oEAAoE;AACpE,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,UAAkB;IACvE,OAAO,GAAG,wBAAwB,GAAG,UAAU,IAAI,UAAU,EAAE,CAAC;AAClE,CAAC;AASD;4EAC4E;AAC5E,SAAS,YAAY,CAAC,UAAkB,EAAE,IAAY,EAAE,KAAa;IACnE,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,aAAa,UAAU,MAAM,IAAI,kDAAkD;YACjF,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/C,IAAI,KAAK,GAAG,gBAAgB,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,aAAa,UAAU,MAAM,IAAI,OAAO,KAAK,qBAAqB,gBAAgB,QAAQ;YACxF,sFAAsF;YACtF,mEAAmE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,SAAS,CAAC,GAAa;IAC9B,OAAO;QACL,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QAC/B,SAAS,EAAE,IAAI;QACf,IAAI,EAAE,MAAM;QACZ,aAAa,EAAE,KAAK;QACpB,iBAAiB,EAAE,KAAK;QACxB,qBAAqB,EAAE,EAAE;QACzB,UAAU,EAAE,EAAE;QACd,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAAC,IAAwB,EAAE,WAAsB;IAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,IAAI,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACpE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,gBAAgB,UAAU,0DAA0D;YAClF,0DAA0D,eAAe,QAAQ,CACpF,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,gBAAgB,CAAC,CAAC,EAAE,kEAAkE;gBACpF,kDAAkD,eAAe,QAAQ,CAC5E,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACtE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;QAE7D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;YAC1E,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,kCAAkC,GAAG,GAAG,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,CAAC;YACjE,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,aAAa,IAAI,YAAY,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,EAAE;YACH,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,UAAU;YAC7B,KAAK;YACL,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,sBAAsB;YAC7C,eAAe,EAAE,IAAI,CAAC,cAAc,IAAI,CAAC;SAC1C;QACD,SAAS;KACV,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,SAAS,SAAS,CAChB,UAAkB,EAClB,CAAmB,EACnB,WAAsB,EACtB,SAAwB;IAExB,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,aAAa,CAAC,CAAC,EAAE,qEAAqE;YACpF,8BAA8B,CACjC,CAAC;IACJ,CAAC;IAED,8FAA8F;IAC9F,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;IAC9B,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAEnC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,2CAA2C,CAAC,CAAC;QAChF,CAAC;QACD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAG,kBAAkB,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO,EAAE,CAAC,CAAC,EAAE;YACb,QAAQ,EAAE;gBACR,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,QAAQ;gBACrB,WAAW,EAAE,IAAI;gBACjB,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5D;SACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,KAA+C,CAAC;IAChE,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,CAAC;QACxF,wFAAwF;QACxF,uEAAuE;QACvE,MAAM,IAAI,KAAK,CACb,aAAa,CAAC,CAAC,EAAE,oEAAoE;YACnF,IAAI,wBAAwB,QAAQ,CACvC,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,EAAE;QACb,QAAQ,EAAE;YACR,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,QAAQ;YACrB,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/api/v1/campaigns` surface (crew#342 + TH-9; DES-CAMPAIGN-001 §8).
|
|
3
|
+
*
|
|
4
|
+
* Thin by design: validation is zod (strict, unknown keys named — the FINDING-031 doctrine),
|
|
5
|
+
* scenario→node mapping is `plan.ts` (pure), and the scheduler is the ENGINE's (durable,
|
|
6
|
+
* single-writer, crash-resumable) — the daemon keeps no shadow campaign state, so a restarted
|
|
7
|
+
* daemon and a second daemon over the same db answer these routes identically. Campaign
|
|
8
|
+
* progress is NOT polled from here: the 11 `campaign*` CoreEvents ride the daemon's existing
|
|
9
|
+
* allowlist-free `/ws` relay the moment the engine emits them.
|
|
10
|
+
*
|
|
11
|
+
* Error posture mirrors the chat/elicitation surfaces: a build whose engine addon lacks the
|
|
12
|
+
* campaign bindings answers 501 (`CampaignsUnsupportedError` — "upgrade the engine"), never
|
|
13
|
+
* 400 ("fix your request").
|
|
14
|
+
*/
|
|
15
|
+
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
|
16
|
+
import { type CoreAdapter } from '../core/adapter.js';
|
|
17
|
+
import type { Actor } from '../core/types.js';
|
|
18
|
+
import type { AuditLog } from '../api/audit.js';
|
|
19
|
+
export interface CampaignRoutesDeps {
|
|
20
|
+
audit: AuditLog;
|
|
21
|
+
actorOf: (req: FastifyRequest & {
|
|
22
|
+
actor?: Actor;
|
|
23
|
+
}) => Actor;
|
|
24
|
+
/** The default council roster for agent scenarios (already parsed). */
|
|
25
|
+
roster: () => unknown[];
|
|
26
|
+
}
|
|
27
|
+
export declare function registerCampaignRoutes(app: FastifyInstance, adapter: CoreAdapter, deps: CampaignRoutesDeps): void;
|
|
28
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/campaigns/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,KAAK,EAAsB,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAmDhD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC5D,uEAAuE;IACvE,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;CACzB;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAyIN"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/api/v1/campaigns` surface (crew#342 + TH-9; DES-CAMPAIGN-001 §8).
|
|
3
|
+
*
|
|
4
|
+
* Thin by design: validation is zod (strict, unknown keys named — the FINDING-031 doctrine),
|
|
5
|
+
* scenario→node mapping is `plan.ts` (pure), and the scheduler is the ENGINE's (durable,
|
|
6
|
+
* single-writer, crash-resumable) — the daemon keeps no shadow campaign state, so a restarted
|
|
7
|
+
* daemon and a second daemon over the same db answer these routes identically. Campaign
|
|
8
|
+
* progress is NOT polled from here: the 11 `campaign*` CoreEvents ride the daemon's existing
|
|
9
|
+
* allowlist-free `/ws` relay the moment the engine emits them.
|
|
10
|
+
*
|
|
11
|
+
* Error posture mirrors the chat/elicitation surfaces: a build whose engine addon lacks the
|
|
12
|
+
* campaign bindings answers 501 (`CampaignsUnsupportedError` — "upgrade the engine"), never
|
|
13
|
+
* 400 ("fix your request").
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { CampaignsUnsupportedError } from '../core/adapter.js';
|
|
17
|
+
import { API_PREFIX } from '../api/api-prefix.js';
|
|
18
|
+
import { buildCampaign } from './plan.js';
|
|
19
|
+
const V = API_PREFIX;
|
|
20
|
+
function message(err) {
|
|
21
|
+
return err instanceof Error ? err.message : String(err);
|
|
22
|
+
}
|
|
23
|
+
/** Same unknown-key-naming 400 body builder as api/routes.ts (restated because that module
|
|
24
|
+
* does not export it and importing routes.ts here would be a cycle through registerRoutes). */
|
|
25
|
+
function invalidBody(err, what) {
|
|
26
|
+
const unknown = err.issues.flatMap((i) => (i.code === 'unrecognized_keys' ? i.keys : []));
|
|
27
|
+
const error = unknown.length > 0
|
|
28
|
+
? `${what}: unknown field${unknown.length > 1 ? 's' : ''} ${unknown
|
|
29
|
+
.map((k) => `\`${k}\``)
|
|
30
|
+
.join(', ')} — this endpoint does not accept ${unknown.length > 1 ? 'them' : 'it'}, and ignoring ${unknown.length > 1 ? 'them' : 'it'} would run a different request than you sent`
|
|
31
|
+
: what;
|
|
32
|
+
return { error, details: err.issues };
|
|
33
|
+
}
|
|
34
|
+
const ScenarioSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
id: z.string().min(1),
|
|
37
|
+
title: z.string().optional(),
|
|
38
|
+
deps: z.array(z.string()).optional(),
|
|
39
|
+
depsCondition: z.enum(['on_success', 'on_terminal']).optional(),
|
|
40
|
+
tool: z.object({ cmd: z.array(z.string()).min(1) }).strict().optional(),
|
|
41
|
+
agent: z
|
|
42
|
+
.object({ problem: z.string().min(1), workflow: z.string().optional() })
|
|
43
|
+
.strict()
|
|
44
|
+
.optional(),
|
|
45
|
+
repoRef: z.string().optional(),
|
|
46
|
+
})
|
|
47
|
+
.strict();
|
|
48
|
+
const LaunchCampaignSchema = z
|
|
49
|
+
.object({
|
|
50
|
+
id: z.string().optional(),
|
|
51
|
+
name: z.string().max(200).optional(),
|
|
52
|
+
scenarios: z.array(ScenarioSchema).min(1),
|
|
53
|
+
policy: z.enum(['fail_fast', 'continue_independent', 'human_gate_on_failure']).optional(),
|
|
54
|
+
maxConcurrency: z.number().int().min(1).max(64).optional(),
|
|
55
|
+
clisJson: z.string().optional(),
|
|
56
|
+
})
|
|
57
|
+
.strict();
|
|
58
|
+
export function registerCampaignRoutes(app, adapter, deps) {
|
|
59
|
+
app.post(`${V}/campaigns`, {
|
|
60
|
+
config: {
|
|
61
|
+
manifest: {
|
|
62
|
+
requestType: 'LaunchCampaignBody',
|
|
63
|
+
responseType: '{ campaignId: string }',
|
|
64
|
+
// 400: zod reject / mapping reject (inline-byte rule, unknown dep, …) / engine def
|
|
65
|
+
// reject (cycle, empty); 409: campaign id already exists; 501: engine addon lacks
|
|
66
|
+
// the campaign bindings.
|
|
67
|
+
statusCodes: [201, 400, 409, 501],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}, async (req, reply) => {
|
|
71
|
+
const parsed = LaunchCampaignSchema.safeParse(req.body);
|
|
72
|
+
if (!parsed.success) {
|
|
73
|
+
return reply.code(400).send(invalidBody(parsed.error, 'Invalid request body'));
|
|
74
|
+
}
|
|
75
|
+
const body = parsed.data;
|
|
76
|
+
try {
|
|
77
|
+
const clis = body.clisJson !== undefined ? JSON.parse(body.clisJson) : deps.roster();
|
|
78
|
+
if (!Array.isArray(clis)) {
|
|
79
|
+
return reply
|
|
80
|
+
.code(400)
|
|
81
|
+
.send({ error: 'clisJson must be a JSON array of AgenticCli seats' });
|
|
82
|
+
}
|
|
83
|
+
const built = buildCampaign(body, clis);
|
|
84
|
+
const campaignId = await adapter.launchCampaign(built.def, built.workflows);
|
|
85
|
+
deps.audit.record('campaign.launched', deps.actorOf(req), {
|
|
86
|
+
detail: {
|
|
87
|
+
campaignId,
|
|
88
|
+
nodes: built.def.nodes.length,
|
|
89
|
+
edges: built.def.edges.length,
|
|
90
|
+
policy: built.def.policy,
|
|
91
|
+
maxConcurrency: built.def.max_concurrency,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
return reply.code(201).send({ campaignId });
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (err instanceof CampaignsUnsupportedError) {
|
|
98
|
+
return reply.code(501).send({ error: err.message });
|
|
99
|
+
}
|
|
100
|
+
const msg = message(err);
|
|
101
|
+
// A campaign id that already exists is a state conflict on a real resource.
|
|
102
|
+
if (/already exists|already launched/i.test(msg)) {
|
|
103
|
+
return reply.code(409).send({ error: msg });
|
|
104
|
+
}
|
|
105
|
+
return reply.code(400).send({ error: msg });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
app.get(`${V}/campaigns`, {
|
|
109
|
+
config: {
|
|
110
|
+
manifest: { responseType: '{ campaigns: Campaign[] }', statusCodes: [200, 501] },
|
|
111
|
+
},
|
|
112
|
+
}, async (_req, reply) => {
|
|
113
|
+
try {
|
|
114
|
+
return { campaigns: await adapter.campaignList() };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (err instanceof CampaignsUnsupportedError) {
|
|
118
|
+
return reply.code(501).send({ error: err.message });
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
app.get(`${V}/campaigns/:id`, {
|
|
124
|
+
config: {
|
|
125
|
+
manifest: { responseType: '{ campaign: Campaign }', statusCodes: [200, 404, 501] },
|
|
126
|
+
},
|
|
127
|
+
}, async (req, reply) => {
|
|
128
|
+
const { id } = req.params;
|
|
129
|
+
try {
|
|
130
|
+
const campaign = await adapter.campaignDetail(id);
|
|
131
|
+
if (campaign === null) {
|
|
132
|
+
return reply.code(404).send({ error: `unknown campaign: ${id}` });
|
|
133
|
+
}
|
|
134
|
+
return { campaign };
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (err instanceof CampaignsUnsupportedError) {
|
|
138
|
+
return reply.code(501).send({ error: err.message });
|
|
139
|
+
}
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Resume / cancel share one wrapper: both resolve the campaign status token, both 404 on an
|
|
144
|
+
// id the engine does not know, and both are actor-audited state transitions.
|
|
145
|
+
const transition = (action, run) => {
|
|
146
|
+
app.post(`${V}/campaigns/:id/${action}`, {
|
|
147
|
+
config: {
|
|
148
|
+
manifest: {
|
|
149
|
+
responseType: '{ campaignId: string; status: CampaignStatus }',
|
|
150
|
+
statusCodes: [200, 404, 409, 501],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}, async (req, reply) => {
|
|
154
|
+
const { id } = req.params;
|
|
155
|
+
try {
|
|
156
|
+
const status = await run(id);
|
|
157
|
+
deps.audit.record(`campaign.${action === 'resume' ? 'resumed' : 'cancelled'}`, deps.actorOf(req), {
|
|
158
|
+
detail: { campaignId: id, status },
|
|
159
|
+
});
|
|
160
|
+
return { campaignId: id, status };
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
if (err instanceof CampaignsUnsupportedError) {
|
|
164
|
+
return reply.code(501).send({ error: err.message });
|
|
165
|
+
}
|
|
166
|
+
const msg = message(err);
|
|
167
|
+
if (/not found|unknown campaign/i.test(msg)) {
|
|
168
|
+
return reply.code(404).send({ error: msg });
|
|
169
|
+
}
|
|
170
|
+
return reply.code(409).send({ error: msg });
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
transition('resume', (id) => adapter.resumeCampaign(id));
|
|
175
|
+
transition('cancel', (id) => adapter.cancelCampaign(id));
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/campaigns/routes.ts"],"names":[],"mappings":"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"}
|
package/dist/core/adapter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CoreEvent, LaunchRunInput, RepoEntry, RepoOnboardRef, SessionView, RecordedEvent, GovernancePolicy, ConformanceRule, GovernanceClaim, CoverageReport, GraphKind, WorkflowDef, CrewSystemSettings, Project, ProjectMember, InteractionRequest } from './types.js';
|
|
1
|
+
import type { CoreEvent, LaunchRunInput, RepoEntry, RepoOnboardRef, SessionView, RecordedEvent, GovernancePolicy, ConformanceRule, GovernanceScoreboard, GovernanceClaim, SteeringImportEntry, SteeringImportResult, GovernanceEvalReport, GovernanceEvalSample, ImportEvalCorpusResponse, CoverageReport, GraphKind, WorkflowDef, CrewSystemSettings, Project, ProjectMember, InteractionRequest, Campaign, CampaignDef } from './types.js';
|
|
2
2
|
/** Where the daemon persists system settings. Exported so tests write fixtures to the ONE
|
|
3
3
|
* spelling of this path (the tests/ tree is audited against spelling core paths itself). */
|
|
4
4
|
export declare function settingsFilePath(): string;
|
|
@@ -45,6 +45,47 @@ export declare class ProjectsUnsupportedError extends Error {
|
|
|
45
45
|
export declare class ElicitationUnsupportedError extends Error {
|
|
46
46
|
constructor(message: string);
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* The campaign surface (DES-CAMPAIGN-001 / TH-9) is not available in this deployment — the
|
|
50
|
+
* installed wicked-core-ts predates the campaign bindings. Typed for the same reason as
|
|
51
|
+
* `ChatUnsupportedError`: the routes answer 501 ("upgrade the engine") on this, never 400
|
|
52
|
+
* ("fix your request"). Gated on METHOD PRESENCE rather than a version floor because the
|
|
53
|
+
* bindings ship in the next core-ts release whose number is the release train's to pick —
|
|
54
|
+
* a presence check is true on whatever version actually carries them.
|
|
55
|
+
*/
|
|
56
|
+
export declare class CampaignsUnsupportedError extends Error {
|
|
57
|
+
constructor(what: string);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The wiki scoreboard (AW-23 / wiki-mgmt) is not available in this deployment — the installed
|
|
61
|
+
* wicked-core-ts predates the `governanceScoreboard` binding (ships in ≥ 0.7.4). Typed for the
|
|
62
|
+
* same reason as `ChatUnsupportedError`: the route answers 501 ("upgrade the engine") on this,
|
|
63
|
+
* never 400 ("fix your request"). Gated on METHOD PRESENCE, the campaigns doctrine — true on
|
|
64
|
+
* whatever release actually carries the binding.
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* The unified steering-rule model (STEERING program) is not available in this deployment —
|
|
68
|
+
* wicked-core-ts predates the `steeringImport` binding (ships in ≥ 0.7.5, alongside the model
|
|
69
|
+
* merge). Typed for the same reason as `ChatUnsupportedError`: the routes answer 501 ("upgrade
|
|
70
|
+
* the engine") on this, never 400 ("fix your request") — and never the WORSE failure of passing
|
|
71
|
+
* a steering-field write through to an engine that would silently drop the fields.
|
|
72
|
+
*/
|
|
73
|
+
export declare class SteeringUnsupportedError extends Error {
|
|
74
|
+
constructor(what: string);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The installed engine addon predates the governance-evals surface (crew-testing; the
|
|
78
|
+
* `governanceEvals` + `governanceCorpusImport` bindings ship with wicked-core-ts 0.7.5, which is
|
|
79
|
+
* unreleased at the time this seam lands). Typed for the same reason as `SteeringUnsupportedError`:
|
|
80
|
+
* the testing routes answer 501 ("upgrade the engine") on this, never 400 ("fix your request") —
|
|
81
|
+
* and they must not crash a daemon running against the released 0.7.4 addon.
|
|
82
|
+
*/
|
|
83
|
+
export declare class GovernanceEvalsUnsupportedError extends Error {
|
|
84
|
+
constructor(what: string);
|
|
85
|
+
}
|
|
86
|
+
export declare class GovernanceScoreboardUnsupportedError extends Error {
|
|
87
|
+
constructor(what: string);
|
|
88
|
+
}
|
|
48
89
|
/** One live chat on the enumerate surface — see {@link CoreAdapter.chatList}. */
|
|
49
90
|
export interface ChatSummary {
|
|
50
91
|
chatId: string;
|
|
@@ -99,6 +140,14 @@ export declare class CoreAdapter {
|
|
|
99
140
|
private closed;
|
|
100
141
|
/** Built-in workflow ids whose overlay JSON has been written this process lifetime. */
|
|
101
142
|
private readonly _builtinOverlayWritten;
|
|
143
|
+
/**
|
|
144
|
+
* The estate db the Core actor was spawned over (`CoreAdapterOptions.dbPath` — the `--db`
|
|
145
|
+
* flag / `~/.wicked-crew/core.db` default). Kept because some engine bindings take the db
|
|
146
|
+
* path as an ARG rather than reading the actor's own handle (`governanceEvals` runs its evals
|
|
147
|
+
* over a read-only connection to this same store); crew resolves it here, the one place the
|
|
148
|
+
* path is already known, so no route grows a second spelling of where the store lives.
|
|
149
|
+
*/
|
|
150
|
+
readonly dbPath: string;
|
|
102
151
|
/** `true` when this adapter armed the event-driven exec seam (for readiness/reporting). */
|
|
103
152
|
readonly engineExec: boolean;
|
|
104
153
|
/** The bus db the exec seam runs over when armed (else `undefined`). */
|
|
@@ -130,6 +179,32 @@ export declare class CoreAdapter {
|
|
|
130
179
|
confirmGate(runId: string, approve: boolean, amend?: string): Promise<string>;
|
|
131
180
|
/** Cancel a run → the status token. */
|
|
132
181
|
cancelRun(runId: string): Promise<string>;
|
|
182
|
+
/** Whether the installed engine addon carries the campaign bindings. */
|
|
183
|
+
campaignsSupported(): boolean;
|
|
184
|
+
/** Guard: the campaign binding surface, or a typed 501-shaped refusal naming the action. */
|
|
185
|
+
private _campaigns;
|
|
186
|
+
/** Validate + launch a campaign DAG → the campaign id. `def` is the ENGINE wire shape
|
|
187
|
+
* (snake_case) — `campaigns/plan.ts` is the one producer of it in this daemon.
|
|
188
|
+
*
|
|
189
|
+
* `workflows` are the composed per-node Tool workflows the def's run_specs reference; they
|
|
190
|
+
* are armed FIRST (hot-register + overlay persist) so the engine can resolve them both now
|
|
191
|
+
* and after a restart — a campaign is durable, so its node workflows must be too. Unlike a
|
|
192
|
+
* deliver-composed def they are NOT purely ephemeral (`_armPerRunWorkflow`), and unlike a
|
|
193
|
+
* user workflow they never enter `userWorkflows` or the catalog (the hydration filter in
|
|
194
|
+
* `readOverlayWorkflows` skips the `campaign-` prefix). */
|
|
195
|
+
launchCampaign(def: CampaignDef, workflows?: WorkflowDef[]): Promise<string>;
|
|
196
|
+
/** Arm one composed campaign-node workflow: validate-then-persist (the FINDING-002 ordering —
|
|
197
|
+
* core's parser is the authority and runs BEFORE the overlay write), overlay file for
|
|
198
|
+
* restart durability, no `userWorkflows` entry. */
|
|
199
|
+
private _armCampaignWorkflow;
|
|
200
|
+
/** Resume a campaign from its persisted state → the campaign status token. */
|
|
201
|
+
resumeCampaign(id: string): Promise<string>;
|
|
202
|
+
/** Cancel a campaign (in-flight node Runs cancelled, the rest marked) → the status token. */
|
|
203
|
+
cancelCampaign(id: string): Promise<string>;
|
|
204
|
+
/** A campaign's full persisted state (DAG + node statuses + run ids), or `null` when unknown. */
|
|
205
|
+
campaignDetail(id: string): Promise<Campaign | null>;
|
|
206
|
+
/** Every campaign on the store. */
|
|
207
|
+
campaignList(): Promise<Campaign[]>;
|
|
133
208
|
/**
|
|
134
209
|
* Archive (or unarchive) a TERMINAL run (crew#265) — write-off, not delete. Resolves `true`
|
|
135
210
|
* when the session existed, `false` for an unknown id (→ 404); REJECTS when the run is
|
|
@@ -297,6 +372,90 @@ export declare class CoreAdapter {
|
|
|
297
372
|
retireConformanceRule(id: string): Promise<boolean>;
|
|
298
373
|
/** Recall conformance rules matching a facet query (read-only, does not block actor). */
|
|
299
374
|
recallRulesPreview(query: Record<string, string | string[] | undefined>): Promise<ConformanceRule[]>;
|
|
375
|
+
/** Whether the installed engine addon carries the AW-23 scoreboard binding (core-ts ≥ 0.7.4). */
|
|
376
|
+
wikiScoreboardSupported(): boolean;
|
|
377
|
+
/**
|
|
378
|
+
* The wiki population/connection scoreboard (AW-23 / arch-R23) — typed %, resolving %,
|
|
379
|
+
* enforcement evidence, and an in-band honesty marker for what cannot be measured. Read-only
|
|
380
|
+
* on the engine side (`open_store_ro`), so it never blocks the single-writer actor.
|
|
381
|
+
*
|
|
382
|
+
* `docsRoot` is the same docs root `rules ingest --dir` used; omitted, the typing half reports
|
|
383
|
+
* `available: false` with the reason — an honest in-band answer, not an error.
|
|
384
|
+
*
|
|
385
|
+
* Presence-gated (the campaigns doctrine): throws {@link GovernanceScoreboardUnsupportedError}
|
|
386
|
+
* on an addon that predates the binding, which the route maps to 501 ("upgrade the engine").
|
|
387
|
+
*/
|
|
388
|
+
governanceScoreboard(docsRoot?: string): Promise<GovernanceScoreboard>;
|
|
389
|
+
/**
|
|
390
|
+
* How many `RuleSet` rows (doctrine domain parents, AW-13) the store holds — or `null` when
|
|
391
|
+
* this engine build cannot count them (no `listRuleSets` binding yet).
|
|
392
|
+
*
|
|
393
|
+
* `null` rather than `0` on purpose (the `runEvents` doctrine): "no rulesets" is a real answer
|
|
394
|
+
* about an unseeded store, and "I cannot count" must never impersonate it — the wiki meta's
|
|
395
|
+
* empty state would otherwise report a seeded store as empty and point the operator at a
|
|
396
|
+
* runbook they already ran.
|
|
397
|
+
*/
|
|
398
|
+
countRuleSets(): Promise<number | null>;
|
|
399
|
+
/**
|
|
400
|
+
* Whether the installed engine addon carries the unified steering-rule model (core-ts ≥ 0.7.5).
|
|
401
|
+
*
|
|
402
|
+
* The sentinel is the `steeringImport` binding, which ships WITH the model merge — see the
|
|
403
|
+
* `GovernanceMethods` comment. Consulted by the routes before: filtering rules by
|
|
404
|
+
* `?type=` (rows on an old engine carry no `steering_type`, so an empty answer would
|
|
405
|
+
* impersonate "no rules of that type"); accepting a rule write that carries steering fields
|
|
406
|
+
* (an old engine would silently drop them — the extraWriteRoots doctrine); and folding the
|
|
407
|
+
* legacy policy write surface (410 only once the unified store exists to point at).
|
|
408
|
+
*/
|
|
409
|
+
steeringSupported(): boolean;
|
|
410
|
+
/**
|
|
411
|
+
* Batch-import steering rules (frontmattered markdown docs and/or ready rule JSON) through the
|
|
412
|
+
* engine's ingest normalize/validate path — the SAME path `rules ingest --dir` runs, on the
|
|
413
|
+
* single-writer actor (the daemon must never open the store for writes itself). Fail-closed
|
|
414
|
+
* PER ENTRY: one bad entry rejects alone with its reason in that entry's result row, the rest
|
|
415
|
+
* still land. `defaultType` is the page's inferred steering type, applied to entries that
|
|
416
|
+
* omit one.
|
|
417
|
+
*
|
|
418
|
+
* Presence-gated (the campaigns doctrine): throws {@link SteeringUnsupportedError} on an addon
|
|
419
|
+
* that predates the binding, which the route maps to 501 ("upgrade the engine").
|
|
420
|
+
*/
|
|
421
|
+
importSteeringRules(entries: SteeringImportEntry[], defaultType?: string): Promise<SteeringImportResult[]>;
|
|
422
|
+
/**
|
|
423
|
+
* Whether the installed engine addon carries the governance-evals surface (core-ts ≥ 0.7.5,
|
|
424
|
+
* unreleased at the time this seam lands). The sentinel is the `governanceEvals` binding —
|
|
425
|
+
* for the WHOLE evals seam, corpus import included: the two bindings ship together, and a
|
|
426
|
+
* daemon running against the released 0.7.4 addon must answer 501 on both routes, never crash.
|
|
427
|
+
*/
|
|
428
|
+
governanceEvalsSupported(): boolean;
|
|
429
|
+
/**
|
|
430
|
+
* Run the governance evals: every sample of the corpus (`corpus` = an `evals:<name>` estate
|
|
431
|
+
* scope minted by {@link importGovernanceCorpus}; omitted = the engine's built-in default
|
|
432
|
+
* corpus) is pushed through the decide path and compared to what its `kind` says SHOULD have
|
|
433
|
+
* happened. Resolves the engine's serde report — snake_case field names, passed to the wire
|
|
434
|
+
* verbatim (the pinned crew/studio contract).
|
|
435
|
+
*
|
|
436
|
+
* `dbPath` rides the args because the eval run opens its own read-only connection to the
|
|
437
|
+
* steering store — the SAME store this adapter's actor writes (`this.dbPath`, the one spelling
|
|
438
|
+
* of where it lives). `knowledgeDb` is deliberately omitted: crew configures no separate
|
|
439
|
+
* knowledge db (the knowledge store is the engine's single-writer sidecar, derived from its
|
|
440
|
+
* own config exactly as the steering ingest path derives it).
|
|
441
|
+
*
|
|
442
|
+
* Presence-gated (the campaigns doctrine): throws {@link GovernanceEvalsUnsupportedError} on
|
|
443
|
+
* an addon that predates the binding, which the route maps to 501 ("upgrade the engine").
|
|
444
|
+
*/
|
|
445
|
+
runGovernanceEvals(args: {
|
|
446
|
+
type?: string;
|
|
447
|
+
corpus?: string;
|
|
448
|
+
}): Promise<GovernanceEvalReport>;
|
|
449
|
+
/**
|
|
450
|
+
* Import a named eval corpus into the knowledge store under the `evals:<name>` scope (the
|
|
451
|
+
* string a later {@link runGovernanceEvals} names as `corpus`). `knowledgeDb` is omitted for
|
|
452
|
+
* the same reason as in {@link runGovernanceEvals} — the engine derives its own sidecar.
|
|
453
|
+
*
|
|
454
|
+
* Gated on the `governanceEvals` sentinel as well as the binding itself: the two ship
|
|
455
|
+
* together, and importing a corpus no engine on this host can ever run would be a trap, not
|
|
456
|
+
* a feature (the steering author-route doctrine).
|
|
457
|
+
*/
|
|
458
|
+
importGovernanceCorpus(name: string, samples: GovernanceEvalSample[]): Promise<ImportEvalCorpusResponse>;
|
|
300
459
|
private readonly userWorkflows;
|
|
301
460
|
/** Whether {@link hydrateFromOverlay} has run this process lifetime. */
|
|
302
461
|
private overlayHydrated;
|