@abelxiaoxing/cadence 1.8.2 → 1.8.4

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.
@@ -2,28 +2,20 @@
2
2
 
3
3
  You are a package-owned read-only professional Agent for the `abel-design` stage.
4
4
 
5
- You explore the repository ONLY through the scoped `read`, `grep`, `find`, and `ls` tools.
6
- You have no shell, edit, Git, network, or validation capability, and you never create or modify files.
5
+ Explore the current workspace using only `read`, `grep`, `find`, and `ls`.
6
+ Do not write files, run commands, use Git, invoke workflow controls, or start another agent.
7
+ The parent controls stage authority and validates your evidence.
7
8
 
8
- Submit one accepted final result through `abel_submit_result`; brief accompanying text is harmless.
9
- If the tool rejects your submission, use its error to correct once in this same disposable session.
10
- A second rejected structural submission ends the session.
11
- Never submit again after acceptance.
9
+ Return one concise final answer.
10
+ Put the evidence object in exactly one `json` code fence.
11
+ The parent binds packet identity; do not invent authority or claim verification.
12
+ Required draft fields: include `module_name`, `scope`, `files_read`, `evidence` (with claim, path, line_start, line_end), `constraints_discovered`, `open_questions`, and `risks`.
13
+ The trusted tool binds packet identity.
14
+ Omission is not a verified absence or authorization.
15
+ Optional arrays may describe structures, conventions, dependencies, write-set hints, validation hints, agent impact, and success criteria.
12
16
 
13
- Required draft fields:
14
-
15
- - `module_name`: a canonical workspace-relative module path or slug;
16
- - `scope` and `files_read`: unique workspace-relative paths, with nonempty scope;
17
- - `evidence`: cited claims with `claim`, `path`, positive `line_start`, and inclusive `line_end >= line_start`;
18
- - `constraints_discovered`, `open_questions`, and `risks`: explicit arrays (use `[]` only when there are none).
19
-
20
- Omit `id`, `packet_id`, `role`, and `kind`: the trusted tool binds them to this packet.
21
- If supplied, they must match the declared identity.
22
- Optional advisory arrays are `existing_structures`, `existing_conventions`, `dependencies`, `write_set_hints`, `validation_hints`, `agents_impact_hints`, and `success_criteria_hints`.
23
- Omission means no advisory information supplied, not a verified absence or authorization.
24
- Do not invent evidence or drop unresolved questions to satisfy the format.
25
- Do not add undeclared fields.
26
-
27
- You never return raw transcripts, hidden reasoning, or tool-call history.
28
- A packet is complete only when every claim is cited and every blocking question is explicit.
29
- If a scope escape, mutation, or undeclared capability is attempted, you fail closed and report the violation.
17
+ Do not return a raw transcript or hidden reasoning.
18
+ Make every claim cite a workspace-relative path and line range.
19
+ If evidence is insufficient, state the blocking question instead of guessing.
20
+ If a correction is needed, correct it once, then stop when the final answer is complete.
21
+ Brief accompanying text is harmless.
@@ -1,28 +1,17 @@
1
1
  # Role: diagnosis-worker
2
2
 
3
- You are a package-owned read-only professional Agent for `abel-diagnose`.
3
+ You are a package-owned evidence worker for `abel-diagnose`.
4
4
 
5
- You collect evidence and falsify candidate root causes ONLY through the scoped `read`, `grep`, `find`, and `ls` tools.
6
- You never write, execute commands, or run validation.
7
- The fixed algorithm order is reproduce, falsify, failing-regression, then minimum-repair.
5
+ Collect evidence and falsify candidate root causes using only the read-only tools explicitly enabled by the parent.
6
+ The fixed order is reproduce when permitted, falsify, failing-regression evidence, then minimum-repair guidance.
7
+ You never choose a workflow stage, claim parent-owned command verification, modify files, or invoke workflow controls.
8
8
 
9
- An evidence packet submits one accepted compact structured evidence object through `abel_submit_result` with the reported symptoms, candidate causes, confirming or refuting citations, and a supported root-cause conclusion or an explicit evidence gap.
10
- Only the parent may claim that command-based reproduction succeeded.
11
- For evidence, omit `id`, `role`, and `kind`; the tool binds them.
12
- Keep `conclusions`, `citations`, `constraints`, `risks`, and `blockingQuestions` explicit.
13
- `dependencies` and `hints` may be omitted when no advisory information is supplied.
14
- If supplying hints, use `writeSet`, `verification`, and `agentsImpact` (`none`, `update-existing`, `create-index`, or `remove-index`).
15
- Omission never proves the absence of an impact.
16
- After a rejected evidence or patch submission, use the error to correct once in this same disposable session.
17
- A second rejected structural submission ends the session.
18
- Never submit again after acceptance.
9
+ Return one concise final answer.
10
+ For evidence, put one JSON object in a single `json` code fence with reported symptoms, candidate causes, confirming or refuting citations, constraints, risks, and blockingQuestions.
11
+ Diagnose packets are evidence-only: do not propose a structured diff or claim that a repair was applied.
12
+ The parent owns result acceptance, any later implementation, candidate sealing, verification, and recovery.
19
13
 
20
- A candidate packet submits one complete structured patch: either the failing regression or, after the parent has verified that regression, the minimum repair.
21
- Use ordered `replace`, `rewrite`, `create`, and `delete` operations inside the approved write set.
22
- Never write unified-diff headers or hunk ranges because the trusted control plane generates them.
23
- If approved context is insufficient, submit a small typed context request instead of a partial patch.
24
- The trusted submit tool validates the accepted payload; brief accompanying text is harmless.
25
- Never claim that you ran the parent-owned verification.
26
-
27
- You never invent a fix for an unverified root cause, change behavior contracts, select another workflow stage, or prescribe parent recovery.
28
- Scope-expanding repairs are reported as evidence for a user decision.
14
+ Use the terms failing-regression and minimum-repair when describing the diagnosis algorithm.
15
+ Never claim a result, and never invent a fix for an unverified root cause.
16
+ Keep output bounded.
17
+ If a correction is needed, describe the minimum repair and its verification condition, then stop when the final answer is complete.
@@ -1,39 +1,21 @@
1
1
  # Role: implementation-worker
2
2
 
3
- You are a package-owned read-only professional Agent for `abel-implement` task phases (Red, Green, and optional Refactor).
3
+ You are a package-owned implementation worker for `abel-implement` task phases (Red, Green, and optional Refactor).
4
4
 
5
- You explore the workspace ONLY through the scoped `read`, `grep`, `find`, and `ls` tools.
6
- You never write the workspace, run validation, or execute commands.
5
+ Use only the tools explicitly enabled by the parent.
6
+ The current working directory is a disposable proposal workspace, not an OS sandbox: never access unrelated absolute paths, never commit Git, and never claim that parent-owned verification succeeded.
7
+ Edit only paths in the phase contract.
8
+ The parent captures and checks the workspace diff, including out-of-bound changes; never silently drop such changes.
7
9
 
8
- Your output is one complete structured patch delivered through `abel_submit_result`:
10
+ Make the smallest complete change required by the objective.
11
+ Preserve the expected parent-owned verification contract.
12
+ If context is insufficient, explain the missing context rather than making a speculative partial repair.
13
+ Describe changed paths and intent in the final summary, but never write unified-diff headers or hunk ranges and do not calculate hashes or byte counts.
14
+ Finish without claiming a result; the parent owns result acceptance.
9
15
 
10
- - copy the attempt-bound `candidateId` from the phase contract;
11
- - submit one accepted `candidate-patch` call containing that `candidateId` and
12
- an ordered `operations` array;
13
- - use `replace` with exact uniquely occurring `oldText` and the intended
14
- `newText` for compact edits, `rewrite` for a complete existing-file body,
15
- `create` with complete content plus `regular | executable` mode, and
16
- `delete` only for an approved deletion path;
17
- - never write unified-diff headers or hunks and never calculate sequences,
18
- Base64 encodings, byte counts, or hashes; the trusted submit tool validates
19
- the operations, generates the diff, chunks it, and seals it atomically;
20
- - every operation path is within the declared phase boundary; paths that do
21
- not need a change may remain untouched;
22
- - preserve the expected parent-owned verification contract without claiming a result;
23
- - use a typed `context-request` for bounded context or task splitting instead
24
- of submitting a partial patch; classify every ref as a requested path with
25
- `read | write` access, a source citation with path and line, or a
26
- contract-diagnostic ref;
27
- - report only the missing context and structural facts: never select
28
- `approval-needed`, `boundary-review-needed`, a Gate, or a workflow stage;
29
- - an `AGENTS.md` path is never a Worker write path;
30
- - report an AGENTS read need separately, and leave every sealed AGENTS contract
31
- and managed-block update to the parent control plane.
32
-
33
- If the submit tool rejects malformed operations, use its concrete error to correct the submission once in this same disposable session; a second rejected structural submission ends the session.
34
-
35
- Never submit again after acceptance; brief accompanying text is harmless.
36
-
37
- If the configured candidate limit is exceeded, the submit tool returns terminal typed `result-limit` with `limitBytes`; never continue with a partial or truncated patch.
38
- The parent alone reviews, applies, and validates the generated diff.
39
- You report candidate facts only and never claim execution success, select parent recovery, choose a workflow stage, or control the task DAG.
16
+ Finish with a concise plain-text summary.
17
+ If the parent requests structured evidence, put one JSON object in a single `json` code fence.
18
+ Never claim a result, select a workflow stage, choose recovery, or report verification success.
19
+ Respect output limits (including a terminal `result-limit`) and stop when the requested work is complete.
20
+ If a correction is needed, correct it once, then stop when the final answer is complete.
21
+ Brief accompanying text is harmless.
@@ -1,8 +1,5 @@
1
- # Worker routing is configured as one whole JSON policy at
2
- # <project>/.pi/cadence/routes.json or ~/.pi/agent/cadence/routes.json.
3
- # Copy routes.example.json and reference custom credentials by environment
4
- # variable name; never place credential values in routes.json.
5
- CADENCE_CUSTOM_WORKER_API_KEY=
1
+ # Cadence child workers use the active Pi model and authentication configuration.
2
+ # Cadence no longer reads routes.json or custom worker endpoint settings.
6
3
 
7
4
  # Context7 works anonymously with its default URL. Uncomment the API key for
8
5
  # authenticated access, or the URL only when overriding the default endpoint.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abelxiaoxing/cadence",
3
- "version": "1.8.2",
3
+ "version": "1.8.4",
4
4
  "description": "Four explicit Abel workflow prompts with stage-isolated design and diagnosis, durable resumable implementation, and three package-owned professional Agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,8 +37,8 @@ Use bounded `abel_dispatch` packets with `action: "run"`, `stage: "abel-diagnose
37
37
  Each packet covers one defect or one falsification question.
38
38
  Do not send an Implement control command from Diagnose.
39
39
 
40
- The parent runs reproduction and verification commands and applies accepted diffs.
41
- A diagnosis Worker is read-only: it proposes cited evidence or one complete candidate diff and never claims that it executed a command or observed a passing result.
40
+ The parent runs reproduction and verification commands and owns any later implementation.
41
+ A diagnosis Worker is read-only and evidence-only: it returns cited evidence and minimum-repair guidance, never proposes or applies a diff, and never claims that it executed a command or observed a passing result.
42
42
 
43
43
  ## Evidence-first algorithm
44
44
 
@@ -51,8 +51,8 @@ For each defect, keep this order:
51
51
  Accept a root cause only when evidence rules out material alternatives.
52
52
  4. Add the smallest executable regression verification and run it.
53
53
  It must fail for the reproduced defect, not for syntax, setup, environment, or another reason.
54
- 5. Apply the minimum repair within the existing behavior and architecture contract.
55
- Run the regression after every edit and the affected suite after refactoring.
54
+ 5. Describe the minimum repair within the existing behavior and architecture contract, including its regression verification condition.
55
+ Do not edit files or claim that a repair was applied from Diagnose.
56
56
  6. Compare the full suite with baseline and require no introduced failure.
57
57
  Classify any AGENTS impact and apply only a verified managed-region update at a stable parent checkpoint.
58
58
  Preserve every byte outside `<!-- ABEL:AGENTS-INDEX:START -->` and `<!-- ABEL:AGENTS-INDEX:END -->`; never give a Worker an AGENTS write path or put runtime/session ids, credentials, or approval state in the index.
@@ -65,7 +65,7 @@ Do not silently widen Diagnose and do not transform an ordinary repair failure i
65
65
 
66
66
  When an approved browser E2E check cannot run, pause only that check and provide executable remediation; continue independent non-browser evidence when safe.
67
67
 
68
- Finish only when reproduction, falsification, failing regression, minimum repair, affected verification, and baseline comparison are all evidenced.
68
+ Finish only when reproduction, falsification, failing-regression evidence, minimum-repair guidance, affected verification, and baseline comparison are all evidenced.
69
69
  After presenting the final structural diagnosis/repair result, send `{"action":"finish"}` so private dispatch is deactivated.
70
70
  A resumable evidence or capability pause remains active for direct follow-up and must not send finish.
71
71
  Never archive, publish, or commit implicitly.
@@ -0,0 +1,289 @@
1
+ import { isAgentsPath, isValidRelativePath } from "./contracts.ts";
2
+ import type { BeginCandidateInput, TaskLedger } from "./task-ledger.ts";
3
+ export type CandidateContextRequestCode =
4
+ | "approved-context-needed"
5
+ | "task-split-needed"
6
+ | "boundary-review-needed";
7
+
8
+ export type CandidateContextRef =
9
+ | { kind: "requested-path"; path: string; access: "read" | "write" }
10
+ | { kind: "source-citation"; path: string; line: number }
11
+ | { kind: "contract-diagnostic"; ref: string };
12
+
13
+ export type CandidateContextRefInput = string | CandidateContextRef;
14
+
15
+ export type CandidateArtifactSubmissionResult =
16
+ | {
17
+ kind: "sealed-candidate";
18
+ candidateId: string;
19
+ state: "sealed";
20
+ artifactHash: string;
21
+ bytes: number;
22
+ paths: string[];
23
+ replayed?: true;
24
+ }
25
+ | {
26
+ kind: "context-request";
27
+ candidateId: string;
28
+ code: CandidateContextRequestCode;
29
+ refs: CandidateContextRef[];
30
+ };
31
+
32
+ export type CandidateContextRequest = Extract<
33
+ CandidateArtifactSubmissionResult,
34
+ { kind: "context-request" }
35
+ >;
36
+
37
+ export interface CandidateContextBoundary {
38
+ phase: "red" | "green" | "refactor";
39
+ readPaths: readonly string[];
40
+ writePaths: readonly string[];
41
+ deletePaths?: readonly string[];
42
+ taskPaths: readonly string[];
43
+ contextReadRoots?: readonly string[];
44
+ redWritePaths: readonly string[];
45
+ agents: {
46
+ impact: "none" | "update-existing" | "create-index" | "remove-index";
47
+ target?: string;
48
+ };
49
+ }
50
+
51
+ export interface ClassifiedCandidateContextRequest {
52
+ kind: "paused" | "retryable" | "approval-needed";
53
+ code:
54
+ | "approved-context-needed"
55
+ | "task-split-needed"
56
+ | "boundary-review-needed"
57
+ | "red-artifact-constraint"
58
+ | "agents-context-needed"
59
+ | "agents-write-parent-owned"
60
+ | "agents-contract-insufficient";
61
+ contextRequest: {
62
+ code: CandidateContextRequestCode;
63
+ refs: CandidateContextRef[];
64
+ };
65
+ }
66
+
67
+ const LEGACY_CITATION = /^(.*):(\d+)$/u;
68
+ const LEGACY_DIAGNOSTIC =
69
+ /^(?:phase-contract|task-contract|sealed-contract|workflow-contract)\.[a-z0-9._-]+$/iu;
70
+
71
+ function validDiagnosticRef(value: unknown): value is string {
72
+ return (
73
+ typeof value === "string" &&
74
+ value.length > 0 &&
75
+ value.length <= 512 &&
76
+ value.trim() === value &&
77
+ !/[\r\n\0]/u.test(value)
78
+ );
79
+ }
80
+
81
+ function normalizeCandidateContextRef(
82
+ input: CandidateContextRefInput,
83
+ ): CandidateContextRef {
84
+ if (typeof input === "string") {
85
+ const citation = LEGACY_CITATION.exec(input);
86
+ if (citation && isValidRelativePath(citation[1])) {
87
+ const line = Number(citation[2]);
88
+ if (Number.isSafeInteger(line) && line >= 1) {
89
+ return { kind: "source-citation", path: citation[1], line };
90
+ }
91
+ }
92
+ if (LEGACY_DIAGNOSTIC.test(input)) {
93
+ return { kind: "contract-diagnostic", ref: input };
94
+ }
95
+ if (!isValidRelativePath(input)) {
96
+ throw new Error("context request refs are invalid");
97
+ }
98
+ return { kind: "requested-path", path: input, access: "read" };
99
+ }
100
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
101
+ throw new Error("context request refs are invalid");
102
+ }
103
+ if (
104
+ input.kind === "requested-path" &&
105
+ Object.keys(input).length === 3 &&
106
+ isValidRelativePath(input.path) &&
107
+ (input.access === "read" || input.access === "write")
108
+ ) {
109
+ return { ...input };
110
+ }
111
+ if (
112
+ input.kind === "source-citation" &&
113
+ Object.keys(input).length === 3 &&
114
+ isValidRelativePath(input.path) &&
115
+ Number.isSafeInteger(input.line) &&
116
+ input.line >= 1
117
+ ) {
118
+ return { ...input };
119
+ }
120
+ if (
121
+ input.kind === "contract-diagnostic" &&
122
+ Object.keys(input).length === 2 &&
123
+ validDiagnosticRef(input.ref)
124
+ ) {
125
+ return { ...input };
126
+ }
127
+ throw new Error("context request refs are invalid");
128
+ }
129
+
130
+ export function normalizeCandidateContextRefs(
131
+ value: unknown,
132
+ ): CandidateContextRef[] {
133
+ if (!Array.isArray(value) || value.length === 0 || value.length > 32) {
134
+ throw new Error("context request refs are invalid");
135
+ }
136
+ const refs = value.map((entry) =>
137
+ normalizeCandidateContextRef(entry as CandidateContextRefInput),
138
+ );
139
+ const identities = refs.map((ref) => JSON.stringify(ref));
140
+ if (new Set(identities).size !== refs.length) {
141
+ throw new Error("context request refs are invalid");
142
+ }
143
+ return refs;
144
+ }
145
+
146
+ function contextRefWithinBoundary(relative: string, approved: string): boolean {
147
+ return (
148
+ approved === "." ||
149
+ relative === approved ||
150
+ relative.startsWith(`${approved}/`)
151
+ );
152
+ }
153
+
154
+ function normalizedBoundary(
155
+ boundary: readonly string[] | CandidateContextBoundary,
156
+ ): CandidateContextBoundary {
157
+ if (!Array.isArray(boundary)) return boundary as CandidateContextBoundary;
158
+ return {
159
+ phase: "green",
160
+ readPaths: boundary,
161
+ writePaths: [],
162
+ deletePaths: [],
163
+ taskPaths: boundary,
164
+ redWritePaths: [],
165
+ agents: { impact: "none" },
166
+ };
167
+ }
168
+
169
+ function pathWithinAny(relative: string, approved: readonly string[]): boolean {
170
+ return approved.some((path) => contextRefWithinBoundary(relative, path));
171
+ }
172
+
173
+ export function permitsContextRead(
174
+ relative: string,
175
+ roots: readonly string[],
176
+ ): boolean {
177
+ // Dynamic discovery never grants hidden credentials or a directory tree.
178
+ return (
179
+ isValidRelativePath(relative) &&
180
+ relative.split("/").every((part) => !part.startsWith(".")) &&
181
+ !/\.(?:pem|key|p12|pfx)$/iu.test(relative) &&
182
+ pathWithinAny(relative, roots)
183
+ );
184
+ }
185
+
186
+ export function classifyCandidateContextRequest(
187
+ request: {
188
+ kind: "context-request";
189
+ candidateId: string;
190
+ code: CandidateContextRequestCode;
191
+ refs: readonly CandidateContextRefInput[];
192
+ },
193
+ inputBoundary: readonly string[] | CandidateContextBoundary,
194
+ ): ClassifiedCandidateContextRequest {
195
+ const refs = normalizeCandidateContextRefs(request.refs);
196
+ const boundary = normalizedBoundary(inputBoundary);
197
+ const phasePaths = [
198
+ ...boundary.readPaths,
199
+ ...boundary.writePaths,
200
+ ...(boundary.deletePaths ?? []),
201
+ ];
202
+ const requested = refs.filter(
203
+ (ref): ref is Extract<CandidateContextRef, { kind: "requested-path" }> =>
204
+ ref.kind === "requested-path",
205
+ );
206
+ const ordinaryRequested = requested.filter((ref) => !isAgentsPath(ref.path));
207
+ const outsideOrdinary = ordinaryRequested.filter(
208
+ (ref) =>
209
+ !(
210
+ ref.access === "read" &&
211
+ permitsContextRead(ref.path, boundary.contextReadRoots ?? [])
212
+ ) &&
213
+ !pathWithinAny(
214
+ ref.path,
215
+ ref.access === "write"
216
+ ? [...boundary.writePaths, ...(boundary.deletePaths ?? [])]
217
+ : [...phasePaths, ...boundary.taskPaths],
218
+ ),
219
+ );
220
+ const agentsRequested = requested.filter((ref) => isAgentsPath(ref.path));
221
+ const agentsWrites = agentsRequested.filter((ref) => ref.access === "write");
222
+ const citedRedArtifacts = refs.filter(
223
+ (ref): ref is Extract<CandidateContextRef, { kind: "source-citation" }> =>
224
+ ref.kind === "source-citation" &&
225
+ pathWithinAny(ref.path, boundary.redWritePaths) &&
226
+ !pathWithinAny(ref.path, [
227
+ ...boundary.writePaths,
228
+ ...(boundary.deletePaths ?? []),
229
+ ]),
230
+ );
231
+ const requestedRedArtifacts = outsideOrdinary.filter(
232
+ (ref) =>
233
+ pathWithinAny(ref.path, boundary.redWritePaths) &&
234
+ pathWithinAny(ref.path, boundary.taskPaths),
235
+ );
236
+ const redArtifactConstraint =
237
+ boundary.phase === "green" &&
238
+ (citedRedArtifacts.length > 0 || requestedRedArtifacts.length > 0) &&
239
+ outsideOrdinary.every((ref) => requestedRedArtifacts.includes(ref)) &&
240
+ agentsRequested.every((ref) => ref.access === "read");
241
+
242
+ let classification: Pick<ClassifiedCandidateContextRequest, "kind" | "code">;
243
+ if (outsideOrdinary.length > 0 && !redArtifactConstraint) {
244
+ classification = {
245
+ kind: "approval-needed",
246
+ code: "boundary-review-needed",
247
+ };
248
+ } else if (agentsWrites.length > 0) {
249
+ const targetMismatch = agentsWrites.some(
250
+ (ref) =>
251
+ boundary.agents.impact === "none" ||
252
+ boundary.agents.target === undefined ||
253
+ ref.path !== boundary.agents.target,
254
+ );
255
+ classification = targetMismatch
256
+ ? { kind: "approval-needed", code: "agents-contract-insufficient" }
257
+ : { kind: "paused", code: "agents-write-parent-owned" };
258
+ } else if (redArtifactConstraint) {
259
+ classification = { kind: "retryable", code: "red-artifact-constraint" };
260
+ } else if (agentsRequested.length > 0) {
261
+ classification = { kind: "paused", code: "agents-context-needed" };
262
+ } else {
263
+ classification = {
264
+ kind: "retryable",
265
+ code:
266
+ request.code === "task-split-needed"
267
+ ? "task-split-needed"
268
+ : "approved-context-needed",
269
+ };
270
+ }
271
+ return {
272
+ ...classification,
273
+ contextRequest: {
274
+ code: request.code,
275
+ refs,
276
+ },
277
+ };
278
+ }
279
+
280
+ export interface CandidateArtifactSubmission {
281
+ ledger: Pick<
282
+ TaskLedger,
283
+ "beginCandidate" | "appendCandidateSegment" | "sealCandidate"
284
+ >;
285
+ identity: BeginCandidateInput;
286
+ workspaceRoot: string;
287
+ writePaths: readonly string[];
288
+ deletePaths: readonly string[];
289
+ }
package/src/contracts.ts CHANGED
@@ -159,38 +159,18 @@ export const VERIFICATION_ADAPTER_CODES = [
159
159
  "verification-config-unsafe",
160
160
  ] as const;
161
161
  export const CHILD_TRANSPORT_CODES = [
162
- "child-provider-rate-limited",
163
- "first-progress-timeout",
164
- "stream-idle-timeout",
165
- "attempt-timeout",
166
- "child-no-final-assistant",
167
- "child-provider-stream-aborted",
168
- "child-provider-stream-error",
169
162
  "child-timeout",
170
- "timeout",
171
163
  "transport-failure",
172
164
  ] as const;
173
165
  export const FAILURE_STAGES = [
174
- "child-session-create",
175
- "child-provider-stream",
176
166
  "child-timeout",
177
- "child-finalization",
178
- "structural-submit",
179
- "candidate-retention",
167
+ "child-provider-stream",
180
168
  "candidate-diff",
181
- "parent-review",
182
169
  "candidate-apply",
183
- "agents-checkpoint",
184
170
  "phase-runtime",
185
171
  ] as const;
186
172
 
187
- export const SUBMIT_FINAL_CATEGORIES = [
188
- "no-final-assistant",
189
- "text-only",
190
- "mixed",
191
- "multiple-submit",
192
- "single-submit-only",
193
- ] as const;
173
+ export const SUBMIT_FINAL_CATEGORIES = ["text-only"] as const;
194
174
  export const SUBMIT_SCHEMA_STATES = [
195
175
  "not-submitted",
196
176
  "valid",
@@ -1892,6 +1872,16 @@ export function validatePacketEnvelope(
1892
1872
  ) {
1893
1873
  return { ok: false, reason: "invalid Design packet contract" };
1894
1874
  }
1875
+ if (
1876
+ packet.stage === "abel-diagnose" &&
1877
+ (packet.output !== "evidence" ||
1878
+ (packet.declared.write as unknown[]).length !== 0)
1879
+ ) {
1880
+ return {
1881
+ ok: false,
1882
+ reason: "invalid Diagnose evidence-only packet contract",
1883
+ };
1884
+ }
1895
1885
 
1896
1886
  return {
1897
1887
  ok: true,
@@ -1,13 +1,11 @@
1
1
  import type { ArtifactStore } from "./artifact-store.ts";
2
+ import type { CandidateArtifactSubmission } from "./candidate-context.ts";
2
3
  import type {
3
4
  StructuredVerificationContract,
4
5
  VerificationInputObservation,
5
6
  } from "./contracts.ts";
6
7
  import type { ImplementPlan, PlanTaskDraft } from "./delivery-compiler.ts";
7
- import type { RoutePolicy, WorkerRoutePolicy } from "./route-policy.ts";
8
-
9
8
  import type { ResolvedStateRoot } from "./state-root.ts";
10
- import type { CandidateArtifactSubmission } from "./submit-tool.ts";
11
9
  import type { TaskLedger } from "./task-ledger.ts";
12
10
 
13
11
  import type {
@@ -123,7 +121,6 @@ export interface DurableWorkflowEngineOptions {
123
121
  consumerRoot: string;
124
122
  stateRoot: ResolvedStateRoot;
125
123
  deliverySource: WorkflowDeliverySource;
126
- routePolicy: RoutePolicy;
127
124
  proposeCandidate(input: {
128
125
  runId: string;
129
126
  operationId: string;
@@ -134,7 +131,6 @@ export interface DurableWorkflowEngineOptions {
134
131
  workspaceRoot: string;
135
132
  ledgerProjection: unknown;
136
133
  candidateArtifact: CandidateArtifactSubmission;
137
- route: WorkerRoutePolicy;
138
134
  repair?: {
139
135
  attempt: number;
140
136
  attribution: "introduced";