harnery 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/core/work/index.d.ts +1 -1
  3. package/dist/core/work/index.d.ts.map +1 -1
  4. package/dist/core/work/read.d.ts +1 -1
  5. package/dist/core/work/read.d.ts.map +1 -1
  6. package/dist/core/work/runner.d.ts +1 -1
  7. package/dist/core/work/runner.d.ts.map +1 -1
  8. package/dist/core/work/runner.js +54 -1
  9. package/dist/core/work/state.d.ts +3 -0
  10. package/dist/core/work/state.d.ts.map +1 -1
  11. package/dist/core/work/state.js +19 -5
  12. package/dist/core/workflow/attempt-context.d.ts +5 -0
  13. package/dist/core/workflow/attempt-context.d.ts.map +1 -0
  14. package/dist/core/workflow/attempt-context.js +189 -0
  15. package/dist/core/workflow/engine.d.ts.map +1 -1
  16. package/dist/core/workflow/engine.js +20 -2
  17. package/dist/core/workflow/index.d.ts +3 -2
  18. package/dist/core/workflow/index.d.ts.map +1 -1
  19. package/dist/core/workflow/index.js +2 -1
  20. package/dist/core/workflow/proof.d.ts +2 -1
  21. package/dist/core/workflow/proof.d.ts.map +1 -1
  22. package/dist/core/workflow/proof.js +7 -1
  23. package/dist/core/workflow/run-state.d.ts +2 -1
  24. package/dist/core/workflow/run-state.d.ts.map +1 -1
  25. package/dist/core/workflow/run-state.js +5 -0
  26. package/dist/core/workflow/types.d.ts +27 -0
  27. package/dist/core/workflow/types.d.ts.map +1 -1
  28. package/dist/core/workflow/types.js +1 -0
  29. package/package.json +1 -1
  30. package/src/core/work/index.ts +1 -0
  31. package/src/core/work/read.ts +1 -0
  32. package/src/core/work/runner.ts +69 -3
  33. package/src/core/work/state.ts +36 -5
  34. package/src/core/workflow/attempt-context.ts +215 -0
  35. package/src/core/workflow/engine.ts +29 -1
  36. package/src/core/workflow/index.ts +10 -0
  37. package/src/core/workflow/proof.ts +9 -1
  38. package/src/core/workflow/run-state.ts +11 -1
  39. package/src/core/workflow/types.ts +35 -0
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { policyDigest } from "../policy/index.js";
5
+ import { isCanonicalWorkflowAttemptContext } from "./attempt-context.js";
5
6
  import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
6
7
  import { isCanonicalWorkflowWorkContext } from "./work-context.js";
7
8
  const MAX_ACCEPTANCE_CRITERIA = 50;
@@ -129,6 +130,7 @@ export function buildWorkflowProof(input) {
129
130
  ended_at: input.endedAt,
130
131
  duration_ms: input.durationMs,
131
132
  work_context: input.workContext,
133
+ attempt_context: input.attemptContext,
132
134
  objective: input.meta.objective,
133
135
  error: clippedOptional(input.error, MAX_SUMMARY_CHARS),
134
136
  result: input.result === undefined ? undefined : digestResult(input.result),
@@ -216,7 +218,11 @@ export function readWorkflowProof(coordRoot, runId) {
216
218
  (proof.run.work_context !== undefined &&
217
219
  (!proof.run.work_item_id ||
218
220
  proof.run.work_context.id !== proof.run.work_item_id ||
219
- !isCanonicalWorkflowWorkContext(proof.run.work_context)))) {
221
+ !isCanonicalWorkflowWorkContext(proof.run.work_context))) ||
222
+ (proof.run.attempt_context !== undefined &&
223
+ (!proof.run.work_item_id ||
224
+ !proof.run.work_context ||
225
+ !isCanonicalWorkflowAttemptContext(proof.run.attempt_context)))) {
220
226
  throw new Error(`workflow proof at ${path} has an unsupported or mismatched schema`);
221
227
  }
222
228
  return proof;
@@ -1,12 +1,13 @@
1
1
  import type { RepoSnapshot } from "../context/index.js";
2
2
  import { type NormalizedPolicy, type PolicyIsolation, type PolicyNetworkAccess } from "../policy/index.js";
3
- import type { WorkflowSpecialistProfile, WorkflowWorkContext } from "./types.js";
3
+ import type { WorkflowAttemptContext, WorkflowSpecialistProfile, WorkflowWorkContext } from "./types.js";
4
4
  export declare const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION: 1;
5
5
  export interface WorkflowRunManifest {
6
6
  schema_version: typeof WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION;
7
7
  run_id: string;
8
8
  work_item_id?: string;
9
9
  work_context?: WorkflowWorkContext;
10
+ attempt_context?: WorkflowAttemptContext;
10
11
  name: string;
11
12
  started_at: string;
12
13
  script: {
@@ -1 +1 @@
1
- {"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/run-state.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGjF,eAAO,MAAM,oCAAoC,EAAG,CAAU,CAAC;AAK/D,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,OAAO,oCAAoC,CAAC;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,iBAAiB,EAAE,YAAY,CAAC;IAChC,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,iBAAiB,EAAE,OAAO,CAAC;QAC3B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,SAAS,EAAE,eAAe,CAAC;QAC3B,cAAc,EAAE,mBAAmB,CAAC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;KACzD,CAAC;CACH;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAmBrF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAoC7F;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA4BvD;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CASjF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhF;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI,CA0CvF"}
1
+ {"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/run-state.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,oCAAoC,EAAG,CAAU,CAAC;AAK/D,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,OAAO,oCAAoC,CAAC;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,iBAAiB,EAAE,YAAY,CAAC;IAChC,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,iBAAiB,EAAE,OAAO,CAAC;QAC3B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,SAAS,EAAE,eAAe,CAAC;QAC3B,cAAc,EAAE,mBAAmB,CAAC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;KACzD,CAAC;CACH;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAmBrF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAwC7F;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA4BvD;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CASjF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhF;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI,CA0CvF"}
@@ -4,6 +4,7 @@ import { hostname } from "node:os";
4
4
  import { dirname, isAbsolute, join, resolve } from "node:path";
5
5
  import { normalizePolicy, policyDigest, } from "../policy/index.js";
6
6
  import { assertWorkflowRunId, readWorkflowApproval } from "./approvals.js";
7
+ import { isCanonicalWorkflowAttemptContext } from "./attempt-context.js";
7
8
  import { normalizeWorkflowSpecialists } from "./specialists.js";
8
9
  import { isCanonicalWorkflowWorkContext } from "./work-context.js";
9
10
  export const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION = 1;
@@ -58,6 +59,10 @@ export function readWorkflowRunManifest(coordRoot, runId) {
58
59
  (!manifest.work_item_id ||
59
60
  manifest.work_context.id !== manifest.work_item_id ||
60
61
  !isCanonicalWorkflowWorkContext(manifest.work_context))) ||
62
+ (manifest.attempt_context !== undefined &&
63
+ (!manifest.work_item_id ||
64
+ !manifest.work_context ||
65
+ !isCanonicalWorkflowAttemptContext(manifest.attempt_context))) ||
61
66
  typeof manifest.name !== "string" ||
62
67
  manifest.name.length === 0 ||
63
68
  manifest.name.length > 200 ||
@@ -10,6 +10,7 @@ import type { DispatchCostEstimator, ExternalMutationRequest, NormalizedPolicy,
10
10
  import type { BillingMode, BillingProber } from "./billing.js";
11
11
  export declare const WORKFLOW_PROOF_SCHEMA_VERSION: 1;
12
12
  export declare const WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION: 1;
13
+ export declare const WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION: 1;
13
14
  export type EvidenceKind = "test" | "command" | "artifact" | "change" | "review" | "observation";
14
15
  export type EvidenceStatus = "passed" | "failed" | "observed" | "unknown";
15
16
  export type EvidenceSource = "workflow" | "engine";
@@ -128,6 +129,7 @@ export interface WorkflowProof {
128
129
  ended_at: string;
129
130
  duration_ms: number;
130
131
  work_context?: WorkflowWorkContext;
132
+ attempt_context?: WorkflowAttemptContext;
131
133
  objective?: string;
132
134
  error?: string;
133
135
  result?: ResultDigest;
@@ -265,6 +267,9 @@ export interface WorkflowContext {
265
267
  /** Frozen durable-work assignment for work-linked runs. Standalone and
266
268
  * legacy-resumed workflows have no work context. */
267
269
  work?: Readonly<WorkflowWorkContext>;
270
+ /** Frozen attempt identity and, on retry, a bounded synopsis of prior
271
+ * terminal evidence. Absent for standalone and legacy-resumed workflows. */
272
+ attempt?: Readonly<WorkflowAttemptContext>;
268
273
  /** Spawn one subagent; resolves to validated JSON (schema) or reply text. */
269
274
  agent: (prompt: string, opts?: AgentOpts) => Promise<unknown>;
270
275
  /** Run thunks with bounded concurrency; a rejected thunk resolves to null. */
@@ -297,6 +302,25 @@ export interface WorkflowWorkContext {
297
302
  readonly objective: string;
298
303
  readonly acceptance: readonly string[];
299
304
  }
305
+ export type WorkflowAttemptFailureCause = "workflow_error" | "acceptance_unsatisfied" | "acceptance_unknown" | "lost";
306
+ export interface WorkflowAttemptUnresolvedCriterion {
307
+ readonly id: string;
308
+ readonly statement: string;
309
+ readonly status: "unsatisfied" | "unknown";
310
+ }
311
+ export interface WorkflowAttemptPriorContext {
312
+ readonly run_id: string;
313
+ readonly causes: readonly WorkflowAttemptFailureCause[];
314
+ readonly error?: string;
315
+ readonly acceptance?: Readonly<AcceptanceSummary>;
316
+ readonly unresolved: readonly WorkflowAttemptUnresolvedCriterion[];
317
+ }
318
+ export interface WorkflowAttemptContext {
319
+ readonly schema_version: typeof WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION;
320
+ readonly number: number;
321
+ readonly trigger: "initial" | "retry";
322
+ readonly prior?: Readonly<WorkflowAttemptPriorContext>;
323
+ }
300
324
  export interface EngineOpts {
301
325
  /** Repo root whose .harnery/ receives the run journal. */
302
326
  coordRoot: string;
@@ -322,6 +346,9 @@ export interface EngineOpts {
322
346
  /** Frozen assignment data supplied by a durable-work host. Requires the
323
347
  * matching `workItemId`; parked resume always uses the manifest copy. */
324
348
  workContext?: WorkflowWorkContext;
349
+ /** Frozen attempt data supplied by a durable-work host. Requires matching
350
+ * work item and work contexts; parked resume uses the manifest copy. */
351
+ attemptContext?: WorkflowAttemptContext;
325
352
  /** Total-agent ceiling for the run (default 50): the runaway backstop. */
326
353
  maxAgents?: number;
327
354
  /** Concurrent-subagent cap for parallel() (default 4). */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/types.ts"],"names":[],"mappings":"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"}
@@ -8,3 +8,4 @@
8
8
  */
9
9
  export const WORKFLOW_PROOF_SCHEMA_VERSION = 1;
10
10
  export const WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION = 1;
11
+ export const WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harnery",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Multi-agent coordination for AI coding agents - Claude Code, Cursor, and Codex.",
5
5
  "license": "MIT",
6
6
  "author": "Ryan Kelly",
@@ -14,6 +14,7 @@ export {
14
14
  WORK_EVENT_SCHEMA_VERSION,
15
15
  WORK_INTENT_SCHEMA_VERSION,
16
16
  type WorkAttempt,
17
+ type WorkAttemptTrigger,
17
18
  type WorkEvent,
18
19
  type WorkEventType,
19
20
  type WorkIntent,
@@ -5,6 +5,7 @@ export {
5
5
  WORK_EVENT_SCHEMA_VERSION,
6
6
  WORK_INTENT_SCHEMA_VERSION,
7
7
  type WorkAttempt,
8
+ type WorkAttemptTrigger,
8
9
  type WorkEvent,
9
10
  type WorkEventType,
10
11
  type WorkIntent,
@@ -1,7 +1,16 @@
1
1
  import { resolve } from "node:path";
2
2
  import { runWorkflow } from "../workflow/engine.ts";
3
- import type { EngineOpts, RunReport } from "../workflow/types.ts";
4
- import { WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION } from "../workflow/types.ts";
3
+ import { readWorkflowProof } from "../workflow/proof.ts";
4
+ import type {
5
+ EngineOpts,
6
+ RunReport,
7
+ WorkflowAttemptContext,
8
+ WorkflowAttemptFailureCause,
9
+ } from "../workflow/types.ts";
10
+ import {
11
+ WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION,
12
+ WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION,
13
+ } from "../workflow/types.ts";
5
14
  import {
6
15
  acquireWorkLease,
7
16
  appendReconcileIfChanged,
@@ -10,12 +19,16 @@ import {
10
19
  boundedActor,
11
20
  newWorkflowRunId,
12
21
  readWorkItemIgnoringLease,
22
+ type WorkAttempt,
13
23
  } from "./state.ts";
14
24
 
15
25
  export interface RunWorkItemInput {
16
26
  coordRoot: string;
17
27
  workId: string;
18
- engine: Omit<EngineOpts, "coordRoot" | "runId" | "resumeRunId" | "workItemId" | "workContext">;
28
+ engine: Omit<
29
+ EngineOpts,
30
+ "coordRoot" | "runId" | "resumeRunId" | "workItemId" | "workContext" | "attemptContext"
31
+ >;
19
32
  retry?: boolean;
20
33
  actor?: string;
21
34
  }
@@ -48,6 +61,9 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
48
61
  if (record.projection.state === "blocked" && !input.retry) {
49
62
  throw new Error(`work item ${input.workId} is blocked; use an explicit retry`);
50
63
  }
64
+ if (record.projection.state === "ready" && input.retry) {
65
+ throw new Error(`work item ${input.workId} is ready; retry requires a blocked prior attempt`);
66
+ }
51
67
  if (!(record.projection.state === "ready" || record.projection.state === "blocked")) {
52
68
  throw new Error(`work item ${input.workId} cannot run from state ${record.projection.state}`);
53
69
  }
@@ -57,6 +73,20 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
57
73
  );
58
74
  }
59
75
  const attempt = record.projection.attempts_used + 1;
76
+ const trigger = input.retry ? "retry" : "initial";
77
+ let prior: WorkflowAttemptContext["prior"];
78
+ if (trigger === "retry") {
79
+ if (!latest) {
80
+ throw new Error(`work item ${input.workId} has no prior attempt to retry`);
81
+ }
82
+ prior = priorContext(coordRoot, latest);
83
+ }
84
+ const attemptContext: WorkflowAttemptContext = {
85
+ schema_version: WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION,
86
+ number: attempt,
87
+ trigger,
88
+ ...(prior ? { prior } : {}),
89
+ };
60
90
  const runId = newWorkflowRunId();
61
91
  appendWorkEvent(coordRoot, input.workId, {
62
92
  event: "attempt.started",
@@ -64,6 +94,7 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
64
94
  reason: input.retry ? "explicit retry started" : "workflow attempt started",
65
95
  run_id: runId,
66
96
  attempt,
97
+ trigger,
67
98
  });
68
99
  return await runWorkflow(record.intent.workflow.path, {
69
100
  ...input.engine,
@@ -77,6 +108,7 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
77
108
  objective: record.intent.objective,
78
109
  acceptance: [...record.intent.acceptance],
79
110
  },
111
+ attemptContext,
80
112
  });
81
113
  } finally {
82
114
  try {
@@ -87,3 +119,37 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
87
119
  }
88
120
  }
89
121
  }
122
+
123
+ function priorContext(
124
+ coordRoot: string,
125
+ prior: WorkAttempt,
126
+ ): NonNullable<WorkflowAttemptContext["prior"]> {
127
+ if (!prior.proof_path) {
128
+ return {
129
+ run_id: prior.run_id,
130
+ causes: ["lost"],
131
+ unresolved: [],
132
+ };
133
+ }
134
+ const proof = readWorkflowProof(coordRoot, prior.run_id);
135
+ const causes: WorkflowAttemptFailureCause[] = [];
136
+ if (proof.run.status === "failed") causes.push("workflow_error");
137
+ if (proof.acceptance.summary.unsatisfied > 0) causes.push("acceptance_unsatisfied");
138
+ if (proof.acceptance.summary.unknown > 0) causes.push("acceptance_unknown");
139
+ if (causes.length === 0) {
140
+ throw new Error(`workflow proof ${prior.run_id} does not describe a retryable failure`);
141
+ }
142
+ return {
143
+ run_id: prior.run_id,
144
+ causes,
145
+ error: proof.run.error,
146
+ acceptance: { ...proof.acceptance.summary },
147
+ unresolved: proof.acceptance.criteria
148
+ .filter((criterion) => criterion.status !== "satisfied")
149
+ .map((criterion) => ({
150
+ id: criterion.id,
151
+ statement: criterion.statement,
152
+ status: criterion.status as "unsatisfied" | "unknown",
153
+ })),
154
+ };
155
+ }
@@ -57,6 +57,8 @@ export type WorkNextAction =
57
57
  | "review"
58
58
  | "none";
59
59
 
60
+ export type WorkAttemptTrigger = "initial" | "retry";
61
+
60
62
  export interface WorkIntent {
61
63
  schema_version: typeof WORK_INTENT_SCHEMA_VERSION;
62
64
  id: string;
@@ -89,6 +91,7 @@ export interface WorkEvent {
89
91
  reason?: string;
90
92
  run_id?: string;
91
93
  attempt?: number;
94
+ trigger?: WorkAttemptTrigger;
92
95
  state?: WorkState;
93
96
  next_action?: WorkNextAction;
94
97
  }
@@ -97,6 +100,7 @@ export interface WorkAttempt {
97
100
  number: number;
98
101
  run_id: string;
99
102
  started_at: string;
103
+ trigger?: WorkAttemptTrigger;
100
104
  status: "running" | "parked" | "succeeded" | "failed" | "lost";
101
105
  approval_id?: string;
102
106
  proof_path?: string;
@@ -317,7 +321,9 @@ function deriveWorkProjection(
317
321
  const terminal =
318
322
  latestGovernance?.event === "work.accepted" || latestGovernance?.event === "work.cancelled";
319
323
  const attemptEvents = events.filter((event) => event.event === "attempt.started");
320
- const attempts = attemptEvents.map((event) => inspectAttempt(coordRoot, event, intent));
324
+ const attempts = attemptEvents.map((event, index) =>
325
+ inspectAttempt(coordRoot, event, intent, attemptEvents[index - 1]?.run_id),
326
+ );
321
327
  const base = {
322
328
  id: intent.id,
323
329
  title: intent.title,
@@ -340,9 +346,7 @@ function deriveWorkProjection(
340
346
  };
341
347
  }
342
348
  const reopenSeq = latestGovernance?.event === "work.reopened" ? latestGovernance.seq : 0;
343
- const currentAttempts = attemptEvents
344
- .filter((event) => event.seq > reopenSeq)
345
- .map((event) => inspectAttempt(coordRoot, event, intent));
349
+ const currentAttempts = attempts.filter((_, index) => attemptEvents[index]!.seq > reopenSeq);
346
350
  const unresolved = intent.dependencies.filter((dependency) => {
347
351
  try {
348
352
  return readWorkItem(coordRoot, dependency).projection.state !== "succeeded";
@@ -419,12 +423,18 @@ function deriveWorkProjection(
419
423
  };
420
424
  }
421
425
 
422
- function inspectAttempt(coordRoot: string, event: WorkEvent, intent: WorkIntent): WorkAttempt {
426
+ function inspectAttempt(
427
+ coordRoot: string,
428
+ event: WorkEvent,
429
+ intent: WorkIntent,
430
+ priorRunId?: string,
431
+ ): WorkAttempt {
423
432
  const runId = event.run_id as string;
424
433
  const attempt: WorkAttempt = {
425
434
  number: event.attempt as number,
426
435
  run_id: runId,
427
436
  started_at: event.ts,
437
+ trigger: event.trigger,
428
438
  status: "lost",
429
439
  };
430
440
  const proofPath = join(coordRoot, ".harnery", "workflows", runId, "proof.json");
@@ -443,6 +453,17 @@ function inspectAttempt(coordRoot: string, event: WorkEvent, intent: WorkIntent)
443
453
  `workflow run ${runId} work context does not match work item ${event.work_id}`,
444
454
  );
445
455
  }
456
+ if (
457
+ manifest.attempt_context !== undefined &&
458
+ (manifest.attempt_context.number !== event.attempt ||
459
+ manifest.attempt_context.trigger !== event.trigger ||
460
+ (manifest.attempt_context.trigger === "retry" &&
461
+ manifest.attempt_context.prior?.run_id !== priorRunId))
462
+ ) {
463
+ throw new Error(
464
+ `workflow run ${runId} attempt context does not match work item ${event.work_id}`,
465
+ );
466
+ }
446
467
  }
447
468
  if (existsSync(proofPath)) {
448
469
  if (!existsSync(manifestPath)) {
@@ -455,6 +476,9 @@ function inspectAttempt(coordRoot: string, event: WorkEvent, intent: WorkIntent)
455
476
  if (JSON.stringify(proof.run.work_context) !== JSON.stringify(manifest?.work_context)) {
456
477
  throw new Error(`workflow proof ${runId} work context does not match its run manifest`);
457
478
  }
479
+ if (JSON.stringify(proof.run.attempt_context) !== JSON.stringify(manifest?.attempt_context)) {
480
+ throw new Error(`workflow proof ${runId} attempt context does not match its run manifest`);
481
+ }
458
482
  attempt.proof_path = proofPath;
459
483
  attempt.status =
460
484
  proof.run.status === "succeeded" &&
@@ -685,6 +709,13 @@ function validateWorkEvent(event: WorkEvent, workId: string, seq: number): void
685
709
  throw new Error(`work item ${workId} event ${seq} has invalid attempt data`);
686
710
  }
687
711
  }
712
+ if (
713
+ event.trigger !== undefined &&
714
+ (event.event !== "attempt.started" ||
715
+ (event.trigger !== "initial" && event.trigger !== "retry"))
716
+ ) {
717
+ throw new Error(`work item ${workId} event ${seq} has invalid attempt trigger`);
718
+ }
688
719
  if (event.event === "work.reconciled") {
689
720
  const states: WorkState[] = [
690
721
  "waiting",
@@ -0,0 +1,215 @@
1
+ import type {
2
+ AcceptanceSummary,
3
+ WorkflowAttemptContext,
4
+ WorkflowAttemptFailureCause,
5
+ WorkflowAttemptPriorContext,
6
+ WorkflowAttemptUnresolvedCriterion,
7
+ } from "./types.ts";
8
+ import { WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION } from "./types.ts";
9
+
10
+ const RUN_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
11
+ const ACCEPTANCE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
12
+ const MAX_ATTEMPTS = 100;
13
+ const MAX_ERROR = 2_000;
14
+ const MAX_CRITERIA = 50;
15
+ const MAX_STATEMENT = 500;
16
+ const CONTEXT_FIELDS = new Set(["schema_version", "number", "trigger", "prior"]);
17
+ const PRIOR_FIELDS = new Set(["run_id", "causes", "error", "acceptance", "unresolved"]);
18
+ const SUMMARY_FIELDS = new Set(["satisfied", "unsatisfied", "unknown", "total"]);
19
+ const CRITERION_FIELDS = new Set(["id", "statement", "status"]);
20
+ const CAUSE_ORDER: readonly WorkflowAttemptFailureCause[] = [
21
+ "workflow_error",
22
+ "acceptance_unsatisfied",
23
+ "acceptance_unknown",
24
+ "lost",
25
+ ];
26
+
27
+ export function normalizeWorkflowAttemptContext(value: unknown): WorkflowAttemptContext {
28
+ const input = objectValue(value, "workflow attempt context");
29
+ rejectExtraFields(input, CONTEXT_FIELDS, "workflow attempt context");
30
+ if (input.schema_version !== WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION) {
31
+ throw new Error("workflow attempt context has an unsupported schema");
32
+ }
33
+ const number = safeInteger(input.number, "workflow attempt context number", 1, MAX_ATTEMPTS);
34
+ if (input.trigger !== "initial" && input.trigger !== "retry") {
35
+ throw new Error('workflow attempt context trigger must be "initial" or "retry"');
36
+ }
37
+ if (input.trigger === "initial") {
38
+ if (input.prior !== undefined) {
39
+ throw new Error("initial workflow attempt context cannot contain prior evidence");
40
+ }
41
+ return {
42
+ schema_version: WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION,
43
+ number,
44
+ trigger: "initial",
45
+ };
46
+ }
47
+ if (number < 2) throw new Error("retry workflow attempt context number must be at least 2");
48
+ if (input.prior === undefined) {
49
+ throw new Error("retry workflow attempt context requires prior evidence");
50
+ }
51
+ return {
52
+ schema_version: WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION,
53
+ number,
54
+ trigger: "retry",
55
+ prior: normalizePrior(input.prior),
56
+ };
57
+ }
58
+
59
+ export function freezeWorkflowAttemptContext(value: unknown): Readonly<WorkflowAttemptContext> {
60
+ const normalized = normalizeWorkflowAttemptContext(value);
61
+ if (normalized.prior) {
62
+ for (const criterion of normalized.prior.unresolved) Object.freeze(criterion);
63
+ Object.freeze(normalized.prior.causes);
64
+ Object.freeze(normalized.prior.acceptance);
65
+ Object.freeze(normalized.prior.unresolved);
66
+ Object.freeze(normalized.prior);
67
+ }
68
+ return Object.freeze(normalized);
69
+ }
70
+
71
+ export function isCanonicalWorkflowAttemptContext(value: unknown): value is WorkflowAttemptContext {
72
+ try {
73
+ const normalized = normalizeWorkflowAttemptContext(value);
74
+ return JSON.stringify(normalized) === JSON.stringify(value);
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
79
+
80
+ function normalizePrior(value: unknown): WorkflowAttemptPriorContext {
81
+ const input = objectValue(value, "workflow attempt prior context");
82
+ rejectExtraFields(input, PRIOR_FIELDS, "workflow attempt prior context");
83
+ const runId = requiredString(input.run_id, "workflow attempt prior run id", 200);
84
+ if (!RUN_ID.test(runId)) {
85
+ throw new Error(`invalid workflow attempt prior run id ${JSON.stringify(runId)}`);
86
+ }
87
+ if (!Array.isArray(input.causes) || input.causes.length === 0) {
88
+ throw new Error("workflow attempt prior causes must be a non-empty array");
89
+ }
90
+ const seen = new Set<WorkflowAttemptFailureCause>();
91
+ for (const cause of input.causes) {
92
+ if (!CAUSE_ORDER.includes(cause as WorkflowAttemptFailureCause)) {
93
+ throw new Error(`unsupported workflow attempt failure cause ${JSON.stringify(cause)}`);
94
+ }
95
+ if (seen.has(cause as WorkflowAttemptFailureCause)) {
96
+ throw new Error(`duplicate workflow attempt failure cause ${JSON.stringify(cause)}`);
97
+ }
98
+ seen.add(cause as WorkflowAttemptFailureCause);
99
+ }
100
+ const causes = CAUSE_ORDER.filter((cause) => seen.has(cause));
101
+ if (causes.includes("lost")) {
102
+ if (causes.length !== 1)
103
+ throw new Error("lost must be the only workflow attempt failure cause");
104
+ if (input.error !== undefined || input.acceptance !== undefined) {
105
+ throw new Error("lost workflow attempt evidence cannot contain proof-derived fields");
106
+ }
107
+ const unresolved = normalizeUnresolved(input.unresolved);
108
+ if (unresolved.length > 0) {
109
+ throw new Error("lost workflow attempt evidence cannot contain unresolved criteria");
110
+ }
111
+ return { run_id: runId, causes, unresolved };
112
+ }
113
+
114
+ const acceptance = normalizeAcceptanceSummary(input.acceptance);
115
+ const unresolved = normalizeUnresolved(input.unresolved);
116
+ const unsatisfied = unresolved.filter((criterion) => criterion.status === "unsatisfied").length;
117
+ const unknown = unresolved.filter((criterion) => criterion.status === "unknown").length;
118
+ if (
119
+ unsatisfied !== acceptance.unsatisfied ||
120
+ unknown !== acceptance.unknown ||
121
+ causes.includes("acceptance_unsatisfied") !== acceptance.unsatisfied > 0 ||
122
+ causes.includes("acceptance_unknown") !== acceptance.unknown > 0
123
+ ) {
124
+ throw new Error("workflow attempt failure evidence does not match acceptance");
125
+ }
126
+ if (!causes.includes("workflow_error") && acceptance.unsatisfied + acceptance.unknown === 0) {
127
+ throw new Error("workflow attempt prior context does not describe a failure");
128
+ }
129
+ const error =
130
+ input.error === undefined
131
+ ? undefined
132
+ : requiredString(input.error, "workflow attempt prior error", MAX_ERROR);
133
+ return {
134
+ run_id: runId,
135
+ causes,
136
+ ...(error === undefined ? {} : { error }),
137
+ acceptance,
138
+ unresolved,
139
+ };
140
+ }
141
+
142
+ function normalizeAcceptanceSummary(value: unknown): AcceptanceSummary {
143
+ const input = objectValue(value, "workflow attempt acceptance summary");
144
+ rejectExtraFields(input, SUMMARY_FIELDS, "workflow attempt acceptance summary");
145
+ const satisfied = safeInteger(input.satisfied, "acceptance satisfied", 0, MAX_CRITERIA);
146
+ const unsatisfied = safeInteger(input.unsatisfied, "acceptance unsatisfied", 0, MAX_CRITERIA);
147
+ const unknown = safeInteger(input.unknown, "acceptance unknown", 0, MAX_CRITERIA);
148
+ const total = safeInteger(input.total, "acceptance total", 0, MAX_CRITERIA);
149
+ if (satisfied + unsatisfied + unknown !== total) {
150
+ throw new Error("workflow attempt acceptance summary total does not match its counts");
151
+ }
152
+ return { satisfied, unsatisfied, unknown, total };
153
+ }
154
+
155
+ function normalizeUnresolved(value: unknown): WorkflowAttemptUnresolvedCriterion[] {
156
+ if (!Array.isArray(value) || value.length > MAX_CRITERIA) {
157
+ throw new Error(
158
+ `workflow attempt unresolved criteria must contain at most ${MAX_CRITERIA} entries`,
159
+ );
160
+ }
161
+ const ids = new Set<string>();
162
+ return value.map((candidate, index) => {
163
+ const input = objectValue(candidate, `workflow attempt unresolved[${index}]`);
164
+ rejectExtraFields(input, CRITERION_FIELDS, `workflow attempt unresolved[${index}]`);
165
+ const id = requiredString(input.id, `workflow attempt unresolved[${index}].id`, 64);
166
+ if (!ACCEPTANCE_ID.test(id)) {
167
+ throw new Error(`invalid workflow attempt acceptance id ${JSON.stringify(id)}`);
168
+ }
169
+ if (ids.has(id))
170
+ throw new Error(`duplicate workflow attempt acceptance id ${JSON.stringify(id)}`);
171
+ ids.add(id);
172
+ if (input.status !== "unsatisfied" && input.status !== "unknown") {
173
+ throw new Error(`workflow attempt unresolved[${index}].status is invalid`);
174
+ }
175
+ return {
176
+ id,
177
+ statement: requiredString(
178
+ input.statement,
179
+ `workflow attempt unresolved[${index}].statement`,
180
+ MAX_STATEMENT,
181
+ ),
182
+ status: input.status,
183
+ };
184
+ });
185
+ }
186
+
187
+ function objectValue(value: unknown, field: string): Record<string, unknown> {
188
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
189
+ throw new Error(`${field} must be an object`);
190
+ }
191
+ return value as Record<string, unknown>;
192
+ }
193
+
194
+ function rejectExtraFields(
195
+ value: Record<string, unknown>,
196
+ allowed: ReadonlySet<string>,
197
+ field: string,
198
+ ): void {
199
+ const extra = Object.keys(value).find((key) => !allowed.has(key));
200
+ if (extra) throw new Error(`${field} has unknown field ${JSON.stringify(extra)}`);
201
+ }
202
+
203
+ function requiredString(value: unknown, field: string, max: number): string {
204
+ if (typeof value !== "string" || value.trim() === "") throw new Error(`${field} is required`);
205
+ const normalized = value.trim();
206
+ if (normalized.length > max) throw new Error(`${field} exceeds ${max} characters`);
207
+ return normalized;
208
+ }
209
+
210
+ function safeInteger(value: unknown, field: string, min: number, max: number): number {
211
+ if (!Number.isSafeInteger(value) || (value as number) < min || (value as number) > max) {
212
+ throw new Error(`${field} must be an integer from ${min} to ${max}`);
213
+ }
214
+ return value as number;
215
+ }