@osovv/vv-opencode 1.3.8 → 1.4.1

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.
Files changed (56) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +66 -14
  3. package/dist/commands/completion.js +10 -2
  4. package/dist/commands/completion.js.map +1 -1
  5. package/dist/commands/patch-provider.d.ts +148 -1
  6. package/dist/commands/patch-provider.js +151 -5
  7. package/dist/commands/patch-provider.js.map +1 -1
  8. package/dist/lib/orchestration.d.ts +2 -2
  9. package/dist/lib/orchestration.js +31 -2
  10. package/dist/lib/orchestration.js.map +1 -1
  11. package/dist/lib/spec-lint.d.ts +71 -1
  12. package/dist/lib/spec-lint.js +566 -8
  13. package/dist/lib/spec-lint.js.map +1 -1
  14. package/dist/lib/vvoc-config.d.ts +3 -3
  15. package/dist/lib/vvoc-preset-registry.d.ts +42 -30
  16. package/dist/lib/vvoc-preset-registry.js +41 -31
  17. package/dist/lib/vvoc-preset-registry.js.map +1 -1
  18. package/dist/plugins/hashline-edit/index.js.map +1 -1
  19. package/dist/plugins/workflow/checkpoint-io.d.ts +33 -0
  20. package/dist/plugins/workflow/checkpoint-io.js +224 -0
  21. package/dist/plugins/workflow/checkpoint-io.js.map +1 -0
  22. package/dist/plugins/workflow/checkpoints.d.ts +182 -0
  23. package/dist/plugins/workflow/checkpoints.js +1067 -0
  24. package/dist/plugins/workflow/checkpoints.js.map +1 -0
  25. package/dist/plugins/workflow/delegated.d.ts +182 -0
  26. package/dist/plugins/workflow/delegated.js +751 -0
  27. package/dist/plugins/workflow/delegated.js.map +1 -0
  28. package/dist/plugins/workflow/index.js +685 -23
  29. package/dist/plugins/workflow/index.js.map +1 -1
  30. package/dist/plugins/workflow/persistence.d.ts +32 -3
  31. package/dist/plugins/workflow/persistence.js +516 -70
  32. package/dist/plugins/workflow/persistence.js.map +1 -1
  33. package/dist/plugins/workflow/repair.js +3 -1
  34. package/dist/plugins/workflow/repair.js.map +1 -1
  35. package/dist/plugins/workflow/snapshots.d.ts +59 -0
  36. package/dist/plugins/workflow/snapshots.js +261 -0
  37. package/dist/plugins/workflow/snapshots.js.map +1 -0
  38. package/dist/plugins/workflow/state.d.ts +20 -2
  39. package/dist/plugins/workflow/state.js +127 -12
  40. package/dist/plugins/workflow/state.js.map +1 -1
  41. package/dist/plugins/workflow/tooling.d.ts +45 -0
  42. package/dist/plugins/workflow/tooling.js +344 -12
  43. package/dist/plugins/workflow/tooling.js.map +1 -1
  44. package/dist/plugins/workflow/transitions.js +2 -2
  45. package/dist/plugins/workflow/transitions.js.map +1 -1
  46. package/dist/tui/context/analyze.js +3 -1
  47. package/dist/tui/context/analyze.js.map +1 -1
  48. package/package.json +1 -1
  49. package/schemas/vvoc/v3.json +5 -3
  50. package/templates/agents/vv-code-reviewer.md +3 -1
  51. package/templates/agents/vv-implementer.md +5 -2
  52. package/templates/agents/vv-spec-reviewer.md +3 -0
  53. package/templates/skills/vv-execute/SKILL.md +62 -15
  54. package/templates/skills/vv-plan/SKILL.md +13 -3
  55. package/templates/skills/vv-plan/references/plan-template.xml +45 -0
  56. package/templates/skills/vv-review/SKILL.md +1 -0
@@ -0,0 +1,33 @@
1
+ import { type DelegatedPlanDefinition } from "../../lib/spec-lint.js";
2
+ export interface LoadedDelegatedPlan {
3
+ /** Canonical absolute plan.xml path. */
4
+ planPath: string;
5
+ /** Canonical absolute linked spec.xml path. */
6
+ specPath: string;
7
+ /** Canonical absolute trusted workspace root. */
8
+ workspaceRoot: string;
9
+ /** SHA-256 of the loaded plan content. */
10
+ planSha256: string;
11
+ /** SHA-256 of the loaded spec content. */
12
+ specSha256: string;
13
+ /** Typed delegated obligations extracted from the approved plan. */
14
+ definition: DelegatedPlanDefinition;
15
+ }
16
+ export type LoadApprovedDelegatedPlanErrorCode = "ROOT_MISMATCH" | "PLAN_NOT_FOUND" | "PATH_ESCAPE" | "NOT_REGULAR_FILE" | "ARCHIVED_PLAN" | "PARSE_ERROR" | "NOT_A_PLAN" | "STATUS_NOT_APPROVED" | "SPEC_MISSING" | "SPEC_PATH_ESCAPE" | "SPEC_NOT_APPROVED" | "LINT_FAILED" | "NOT_DELEGATED";
17
+ export type LoadApprovedDelegatedPlanResult = {
18
+ ok: true;
19
+ plan: LoadedDelegatedPlan;
20
+ } | {
21
+ ok: false;
22
+ code: LoadApprovedDelegatedPlanErrorCode;
23
+ message: string;
24
+ };
25
+ export interface LoadApprovedDelegatedPlanInput {
26
+ /** Trusted absolute workspace root. */
27
+ workspaceRoot: string;
28
+ /** Absolute or workspace-relative path to plan.xml. */
29
+ planPath: string;
30
+ }
31
+ /** Deterministic SHA-256 hex digest over provided text. */
32
+ export declare function contentSha256(text: string): string;
33
+ export declare function loadApprovedDelegatedPlan(input: LoadApprovedDelegatedPlanInput): Promise<LoadApprovedDelegatedPlanResult>;
@@ -0,0 +1,224 @@
1
+ // FILE: src/plugins/workflow/checkpoint-io.ts
2
+ // VERSION: 1.0.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Filesystem adapter that loads and fully validates an approved active vvoc delegated plan and its linked approved spec for runtime registration.
5
+ // SCOPE: Trusted-root containment, regular-file and archive rejection, strict parse, lifecycle status checks, full cross-file lint through the shared engine, typed delegated extraction, and content-hash capture. Domain transitions and fingerprint capture live elsewhere.
6
+ // DEPENDS: [node:crypto, node:fs/promises, node:path, src/lib/spec-lint.ts]
7
+ // LINKS: [M-WORKFLOW-CHECKPOINTS, M-SPEC-LINT, M-WORKFLOW-DELEGATED, V-M-WORKFLOW-CHECKPOINTS]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // LoadedDelegatedPlan - Canonical approved plan/spec inputs with content hashes and typed obligations.
14
+ // LoadApprovedDelegatedPlanErrorCode - Rejection codes for approved-plan loading.
15
+ // LoadApprovedDelegatedPlanResult - Loaded plan or a coded rejection.
16
+ // LoadApprovedDelegatedPlanInput - Workspace root and plan path (absolute or root-relative).
17
+ // loadApprovedDelegatedPlan - Load, validate, lint, and extract one approved delegated plan package.
18
+ // contentSha256 - Deterministic SHA-256 over provided text.
19
+ // END_MODULE_MAP
20
+ //
21
+ // START_CHANGE_SUMMARY
22
+ // LAST_CHANGE: [C-DELEGATED-WORKFLOW-ASTRA-PRESETS - Initial adapter: containment, archive and lifecycle rejection, full lint, typed extraction, and hashes.]
23
+ // END_CHANGE_SUMMARY
24
+ import { createHash } from "node:crypto";
25
+ import { readFile, realpath, stat } from "node:fs/promises";
26
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
27
+ import { extractDelegatedPlanDefinition, isSpecArchivePath, lintSpecArtifacts, parseSpecXml, } from "../../lib/spec-lint.js";
28
+ // END_BLOCK_IO_TYPES
29
+ // START_BLOCK_HASH_HELPER
30
+ /** Deterministic SHA-256 hex digest over provided text. */
31
+ export function contentSha256(text) {
32
+ return createHash("sha256").update(text, "utf8").digest("hex");
33
+ }
34
+ // END_BLOCK_HASH_HELPER
35
+ // START_CONTRACT: loadApprovedDelegatedPlan
36
+ // PURPOSE: Load an active project-local approved vvoc delegated plan plus its linked approved spec, fully linted and typed.
37
+ // INPUTS: { input: LoadApprovedDelegatedPlanInput - trusted workspace root and plan path }
38
+ // OUTPUTS: { Promise<LoadApprovedDelegatedPlanResult> - canonical inputs, hashes, and definition, or a coded rejection }
39
+ // SIDE_EFFECTS: Reads plan and spec files; performs no writes, agent dispatch, or command execution.
40
+ // LINKS: [M-WORKFLOW-CHECKPOINTS, M-SPEC-LINT, registerDelegatedPlan]
41
+ // END_CONTRACT: loadApprovedDelegatedPlan
42
+ export async function loadApprovedDelegatedPlan(input) {
43
+ if (typeof input.workspaceRoot !== "string" || !isAbsolute(input.workspaceRoot)) {
44
+ return {
45
+ ok: false,
46
+ code: "ROOT_MISMATCH",
47
+ message: `workspace root must be an absolute path, received: ${JSON.stringify(input.workspaceRoot)}`,
48
+ };
49
+ }
50
+ if (typeof input.planPath !== "string" || input.planPath.trim() === "") {
51
+ return {
52
+ ok: false,
53
+ code: "PLAN_NOT_FOUND",
54
+ message: "planPath must be a non-empty string",
55
+ };
56
+ }
57
+ let realRoot;
58
+ try {
59
+ realRoot = await realpath(input.workspaceRoot);
60
+ }
61
+ catch (error) {
62
+ return {
63
+ ok: false,
64
+ code: "ROOT_MISMATCH",
65
+ message: `workspace root ${input.workspaceRoot} cannot be resolved: ${error.message}`,
66
+ };
67
+ }
68
+ const candidatePlanPath = isAbsolute(input.planPath)
69
+ ? input.planPath
70
+ : join(realRoot, input.planPath);
71
+ const planContainment = relative(realRoot, candidatePlanPath);
72
+ if (planContainment === "" || planContainment.startsWith("..") || isAbsolute(planContainment)) {
73
+ return {
74
+ ok: false,
75
+ code: "PATH_ESCAPE",
76
+ message: `plan path ${input.planPath} resolves outside the workspace root`,
77
+ };
78
+ }
79
+ if (isSpecArchivePath(candidatePlanPath.replace(/\\/g, "/"))) {
80
+ return {
81
+ ok: false,
82
+ code: "ARCHIVED_PLAN",
83
+ message: `plan path ${input.planPath} sits inside an archive directory; archived plans are immutable history`,
84
+ };
85
+ }
86
+ let planStat;
87
+ try {
88
+ planStat = await stat(candidatePlanPath);
89
+ }
90
+ catch (error) {
91
+ return {
92
+ ok: false,
93
+ code: "PLAN_NOT_FOUND",
94
+ message: `plan file ${candidatePlanPath} cannot be read: ${error.message}`,
95
+ };
96
+ }
97
+ if (!planStat.isFile()) {
98
+ return {
99
+ ok: false,
100
+ code: "NOT_REGULAR_FILE",
101
+ message: `plan path ${candidatePlanPath} is not a regular file`,
102
+ };
103
+ }
104
+ const planContent = await readFile(candidatePlanPath, "utf8");
105
+ const parsedPlan = parseSpecXml(planContent, candidatePlanPath);
106
+ if (parsedPlan.findings.some((finding) => finding.severity === "error")) {
107
+ return {
108
+ ok: false,
109
+ code: "PARSE_ERROR",
110
+ message: parsedPlan.findings
111
+ .filter((finding) => finding.severity === "error")
112
+ .map((finding) => finding.message)
113
+ .join("; "),
114
+ };
115
+ }
116
+ if (!parsedPlan.root || parsedPlan.root.name !== "plan") {
117
+ return {
118
+ ok: false,
119
+ code: "NOT_A_PLAN",
120
+ message: `root element is not <plan>: ${parsedPlan.root?.name ?? "(none)"}`,
121
+ };
122
+ }
123
+ const statusOf = (root) => {
124
+ const statusNode = root.children.find((child) => child.name === "status");
125
+ return statusNode ? statusNode.text.trim() : "";
126
+ };
127
+ const planStatus = statusOf(parsedPlan.root);
128
+ if (planStatus !== "approved") {
129
+ return {
130
+ ok: false,
131
+ code: "STATUS_NOT_APPROVED",
132
+ message: `plan status is "${planStatus}", not approved`,
133
+ };
134
+ }
135
+ const specRefNode = parsedPlan.root.children.find((child) => child.name === "spec");
136
+ const specRef = specRefNode ? specRefNode.text.trim() : "";
137
+ if (!specRef) {
138
+ return {
139
+ ok: false,
140
+ code: "SPEC_MISSING",
141
+ message: "plan declares an empty <spec> reference",
142
+ };
143
+ }
144
+ const candidateSpecPath = isAbsolute(specRef)
145
+ ? specRef
146
+ : resolve(dirname(candidatePlanPath), specRef);
147
+ const specContainment = relative(realRoot, candidateSpecPath);
148
+ if (specContainment === "" || specContainment.startsWith("..") || isAbsolute(specContainment)) {
149
+ return {
150
+ ok: false,
151
+ code: "SPEC_PATH_ESCAPE",
152
+ message: `linked spec ${specRef} resolves outside the workspace root`,
153
+ };
154
+ }
155
+ let specStat;
156
+ try {
157
+ specStat = await stat(candidateSpecPath);
158
+ }
159
+ catch (error) {
160
+ return {
161
+ ok: false,
162
+ code: "SPEC_MISSING",
163
+ message: `linked spec file ${candidateSpecPath} cannot be read: ${error.message}`,
164
+ };
165
+ }
166
+ if (!specStat.isFile()) {
167
+ return {
168
+ ok: false,
169
+ code: "SPEC_MISSING",
170
+ message: `linked spec path ${candidateSpecPath} is not a regular file`,
171
+ };
172
+ }
173
+ const specContent = await readFile(candidateSpecPath, "utf8");
174
+ const parsedSpec = parseSpecXml(specContent, candidateSpecPath);
175
+ if (!parsedSpec.root || parsedSpec.root.name !== "spec") {
176
+ return {
177
+ ok: false,
178
+ code: "SPEC_MISSING",
179
+ message: `linked spec root element is not <spec>: ${parsedSpec.root?.name ?? "(none)"}`,
180
+ };
181
+ }
182
+ const specStatus = statusOf(parsedSpec.root);
183
+ if (specStatus !== "approved") {
184
+ return {
185
+ ok: false,
186
+ code: "SPEC_NOT_APPROVED",
187
+ message: `linked spec status is "${specStatus}", not approved`,
188
+ };
189
+ }
190
+ const verdicts = lintSpecArtifacts([
191
+ { file: candidateSpecPath, content: specContent },
192
+ { file: candidatePlanPath, content: planContent },
193
+ ]);
194
+ const lintErrors = verdicts.flatMap((verdict) => verdict.findings
195
+ .filter((finding) => finding.severity === "error")
196
+ .map((finding) => finding.message));
197
+ if (lintErrors.length > 0) {
198
+ return {
199
+ ok: false,
200
+ code: "LINT_FAILED",
201
+ message: lintErrors.join("; "),
202
+ };
203
+ }
204
+ const extraction = extractDelegatedPlanDefinition(planContent, candidatePlanPath);
205
+ if (!extraction.ok) {
206
+ return {
207
+ ok: false,
208
+ code: "NOT_DELEGATED",
209
+ message: extraction.errors.join("; "),
210
+ };
211
+ }
212
+ return {
213
+ ok: true,
214
+ plan: {
215
+ planPath: candidatePlanPath,
216
+ specPath: candidateSpecPath,
217
+ workspaceRoot: realRoot,
218
+ planSha256: contentSha256(planContent),
219
+ specSha256: contentSha256(specContent),
220
+ definition: extraction.definition,
221
+ },
222
+ };
223
+ }
224
+ //# sourceMappingURL=checkpoint-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-io.js","sourceRoot":"","sources":["../../../src/plugins/workflow/checkpoint-io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ import type { DelegatedPlanDefinition, DelegatedReviewer } from "../../lib/spec-lint.js";
2
+ import { type LoadedDelegatedPlan } from "./checkpoint-io.js";
3
+ import { type WorkItemStore, type WorkItemStoreData } from "./state.js";
4
+ export declare const MAX_CHECKPOINT_REVIEW_ATTEMPTS = 2;
5
+ export interface DelegatedReviewerOutcome {
6
+ status: "PASS" | "FAIL" | "NEEDS_CONTEXT";
7
+ recordedAt: string;
8
+ }
9
+ export interface DelegatedCheckpointReview {
10
+ reviewWorkItemId: string;
11
+ generation: number;
12
+ startedAt: string;
13
+ startFingerprint: string;
14
+ coveredAttemptIds: string[];
15
+ reviewerCallIds: Partial<Record<DelegatedReviewer, string>>;
16
+ results: Partial<Record<DelegatedReviewer, DelegatedReviewerOutcome>>;
17
+ }
18
+ export interface DelegatedCheckpointHistoryEntry {
19
+ generation: number;
20
+ outcome: "passed" | "failed" | "stale";
21
+ fingerprint: string;
22
+ completedAt: string;
23
+ }
24
+ export interface DelegatedRunCheckpoint {
25
+ checkpointId: string;
26
+ kind: "milestone" | "final";
27
+ afterWave: string;
28
+ covers: string[];
29
+ scope: string[];
30
+ reviewers: DelegatedReviewer[];
31
+ status: "pending" | "in_review" | "passed" | "failed";
32
+ attempts: number;
33
+ lastOutcome?: "passed" | "failed" | "stale" | "stopped" | "incomplete";
34
+ currentReview?: DelegatedCheckpointReview;
35
+ history: DelegatedCheckpointHistoryEntry[];
36
+ }
37
+ export interface DelegatedRunTask {
38
+ taskId: string;
39
+ workItemId: string;
40
+ }
41
+ export interface DelegatedPlanRun {
42
+ runId: string;
43
+ sessionId: string;
44
+ planPath: string;
45
+ specPath: string;
46
+ workspaceRoot: string;
47
+ planSha256: string;
48
+ specSha256: string;
49
+ definition: DelegatedPlanDefinition;
50
+ registeredAt: string;
51
+ status: "active" | "sealed";
52
+ sealedAt?: string;
53
+ finalCheckpointId?: string;
54
+ tasks: Map<string, DelegatedRunTask>;
55
+ checkpoints: Map<string, DelegatedRunCheckpoint>;
56
+ }
57
+ export type RegisterDelegatedPlanResult = {
58
+ ok: true;
59
+ runId: string;
60
+ reused: boolean;
61
+ run: DelegatedPlanRun;
62
+ } | {
63
+ ok: false;
64
+ errorCode: "INVALID_INPUT" | "PLAN_DRIFT" | "TASK_BINDING_FAILED" | "SESSION_MISMATCH";
65
+ message: string;
66
+ };
67
+ export interface RegisterDelegatedPlanInput {
68
+ sessionId: string;
69
+ plan: LoadedDelegatedPlan;
70
+ }
71
+ export declare function registerDelegatedPlan(store: WorkItemStore, input: RegisterDelegatedPlanInput): RegisterDelegatedPlanResult;
72
+ export declare function registerDelegatedPlanInStore(data: WorkItemStoreData, input: RegisterDelegatedPlanInput): RegisterDelegatedPlanResult;
73
+ export type StartDelegatedCheckpointResult = {
74
+ ok: true;
75
+ checkpoint: DelegatedRunCheckpoint;
76
+ reviewWorkItemId: string;
77
+ header: string;
78
+ reviewersToLaunch: DelegatedReviewer[];
79
+ generation: number;
80
+ } | {
81
+ ok: false;
82
+ errorCode: "RUN_NOT_FOUND" | "SESSION_MISMATCH" | "CHECKPOINT_NOT_FOUND" | "RUN_SEALED" | "ALREADY_PASSED" | "ALREADY_IN_REVIEW" | "ATTEMPTS_EXHAUSTED" | "PREREQUISITES_NOT_ACCEPTED" | "OVERLAPPING_SCOPE" | "SNAPSHOT_FAILED";
83
+ message: string;
84
+ };
85
+ export interface StartDelegatedCheckpointInput {
86
+ sessionId: string;
87
+ runId: string;
88
+ checkpointId: string;
89
+ }
90
+ export declare function startDelegatedCheckpoint(store: WorkItemStore, input: StartDelegatedCheckpointInput): Promise<StartDelegatedCheckpointResult>;
91
+ export declare function startDelegatedCheckpointInStore(data: WorkItemStoreData, input: StartDelegatedCheckpointInput): Promise<StartDelegatedCheckpointResult>;
92
+ export type RecordReviewerLaunchResult = {
93
+ ok: true;
94
+ } | {
95
+ ok: false;
96
+ errorCode: "RUN_NOT_FOUND" | "CHECKPOINT_NOT_FOUND" | "NOT_IN_REVIEW" | "REVIEWER_NOT_DECLARED" | "ALREADY_LAUNCHED" | "ALREADY_RECORDED";
97
+ message: string;
98
+ };
99
+ export type RecordReviewerResultResult = {
100
+ ok: true;
101
+ roundComplete: boolean;
102
+ } | {
103
+ ok: false;
104
+ errorCode: "RUN_NOT_FOUND" | "CHECKPOINT_NOT_FOUND" | "NOT_IN_REVIEW" | "REVIEWER_NOT_DECLARED" | "CALLBACK_MISMATCH" | "ALREADY_RECORDED";
105
+ message: string;
106
+ };
107
+ export declare function recordCheckpointReviewerLaunch(store: WorkItemStore, input: {
108
+ runId: string;
109
+ checkpointId: string;
110
+ reviewer: DelegatedReviewer;
111
+ callId: string;
112
+ }): RecordReviewerLaunchResult;
113
+ export declare function recordCheckpointReviewerLaunchInStore(data: WorkItemStoreData, input: {
114
+ runId: string;
115
+ checkpointId: string;
116
+ reviewer: DelegatedReviewer;
117
+ callId: string;
118
+ }): RecordReviewerLaunchResult;
119
+ export declare function recordCheckpointReviewerResult(store: WorkItemStore, input: {
120
+ runId: string;
121
+ checkpointId: string;
122
+ reviewer: DelegatedReviewer;
123
+ callId?: string;
124
+ status: "PASS" | "FAIL" | "NEEDS_CONTEXT";
125
+ }): RecordReviewerResultResult;
126
+ export declare function recordCheckpointReviewerResultInStore(data: WorkItemStoreData, input: {
127
+ runId: string;
128
+ checkpointId: string;
129
+ reviewer: DelegatedReviewer;
130
+ callId?: string;
131
+ status: "PASS" | "FAIL" | "NEEDS_CONTEXT";
132
+ }): RecordReviewerResultResult;
133
+ export type VerifyDelegatedCheckpointResult = {
134
+ ok: true;
135
+ checkpoint: DelegatedRunCheckpoint;
136
+ outcome: "passed" | "failed" | "stale" | "stopped" | "incomplete" | "already-passed";
137
+ snapshotCurrent: boolean;
138
+ sealedRun?: boolean;
139
+ } | {
140
+ ok: false;
141
+ errorCode: "RUN_NOT_FOUND" | "CHECKPOINT_NOT_FOUND" | "FINAL_COMPLETE_ON_NON_FINAL" | "COMPLETE_REQUIREMENTS_UNMET" | "PLAN_DRIFT" | "SNAPSHOT_FAILED";
142
+ message: string;
143
+ };
144
+ export interface VerifyDelegatedCheckpointInput {
145
+ sessionId: string;
146
+ runId: string;
147
+ checkpointId: string;
148
+ /** Only permitted for the final checkpoint; seals the run when every completion condition passes. */
149
+ complete?: boolean;
150
+ }
151
+ export declare function verifyDelegatedCheckpoint(store: WorkItemStore, input: VerifyDelegatedCheckpointInput): Promise<VerifyDelegatedCheckpointResult>;
152
+ export declare function verifyDelegatedCheckpointInStore(data: WorkItemStoreData, input: VerifyDelegatedCheckpointInput): Promise<VerifyDelegatedCheckpointResult>;
153
+ export type AuthorizeReworkResult = {
154
+ ok: true;
155
+ reworkId: string;
156
+ grantedAttempts: number;
157
+ } | {
158
+ ok: false;
159
+ errorCode: "RUN_NOT_FOUND" | "SESSION_MISMATCH" | "CHECKPOINT_NOT_FOUND" | "RUN_SEALED" | "CHECKPOINT_NOT_FAILED" | "HARD_STOP_CHECKPOINT" | "TASK_NOT_COVERED" | "WORK_ITEM_NOT_BOUND" | "REWORK_REJECTED";
160
+ message: string;
161
+ };
162
+ export interface AuthorizeReworkInput {
163
+ sessionId: string;
164
+ runId: string;
165
+ checkpointId: string;
166
+ workItemId: string;
167
+ reason: string;
168
+ }
169
+ export declare function authorizeReworkFromFailedCheckpoint(store: WorkItemStore, input: AuthorizeReworkInput): AuthorizeReworkResult;
170
+ export declare function authorizeReworkFromFailedCheckpointInStore(data: WorkItemStoreData, input: AuthorizeReworkInput): AuthorizeReworkResult;
171
+ /** Unsatisfied checkpoint barriers blocking task launches for the given wave, in declaration order. */
172
+ export declare function checkpointBarrierUnsatisfied(data: WorkItemStoreData, runId: string, wave: string): {
173
+ ok: true;
174
+ blockers: string[];
175
+ } | {
176
+ ok: false;
177
+ message: string;
178
+ };
179
+ /** In-flight checkpoint review whose scope intersects the declared write scope. */
180
+ export declare function findOverlappingInFlightReview(data: WorkItemStoreData, runId: string, writeScope: readonly string[]): string | undefined;
181
+ /** Read-only run serialization for tooling output and persistence consumers. */
182
+ export declare function getDelegatedRunView(data: WorkItemStoreData, runId: string): Record<string, unknown> | undefined;