harnery 0.19.1 → 0.21.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 (57) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/supervisor.d.ts.map +1 -1
  3. package/dist/commands/supervisor.js +21 -1
  4. package/dist/core/supervisor/index.d.ts +1 -1
  5. package/dist/core/supervisor/index.d.ts.map +1 -1
  6. package/dist/core/supervisor/index.js +1 -1
  7. package/dist/core/supervisor/plan-api.d.ts +7 -0
  8. package/dist/core/supervisor/plan-api.d.ts.map +1 -1
  9. package/dist/core/supervisor/plan-api.js +17 -1
  10. package/dist/core/supervisor/plan-read.d.ts.map +1 -1
  11. package/dist/core/supervisor/plan-read.js +4 -0
  12. package/dist/core/supervisor/plan-types.d.ts +2 -2
  13. package/dist/core/supervisor/plan-types.d.ts.map +1 -1
  14. package/dist/core/supervisor/planning.d.ts +7 -0
  15. package/dist/core/supervisor/planning.d.ts.map +1 -1
  16. package/dist/core/supervisor/planning.js +38 -0
  17. package/dist/core/supervisor/state.d.ts +2 -1
  18. package/dist/core/supervisor/state.d.ts.map +1 -1
  19. package/dist/core/supervisor/state.js +4 -1
  20. package/dist/core/work/runner.d.ts +1 -1
  21. package/dist/core/work/runner.d.ts.map +1 -1
  22. package/dist/core/work/runner.js +8 -0
  23. package/dist/core/work/state.d.ts.map +1 -1
  24. package/dist/core/work/state.js +24 -4
  25. package/dist/core/workflow/engine.d.ts.map +1 -1
  26. package/dist/core/workflow/engine.js +29 -3
  27. package/dist/core/workflow/index.d.ts +2 -2
  28. package/dist/core/workflow/index.d.ts.map +1 -1
  29. package/dist/core/workflow/index.js +1 -1
  30. package/dist/core/workflow/proof.d.ts +2 -1
  31. package/dist/core/workflow/proof.d.ts.map +1 -1
  32. package/dist/core/workflow/proof.js +8 -1
  33. package/dist/core/workflow/run-state.d.ts +2 -1
  34. package/dist/core/workflow/run-state.d.ts.map +1 -1
  35. package/dist/core/workflow/run-state.js +5 -0
  36. package/dist/core/workflow/types.d.ts +16 -0
  37. package/dist/core/workflow/types.d.ts.map +1 -1
  38. package/dist/core/workflow/types.js +1 -0
  39. package/dist/core/workflow/work-context.d.ts +5 -0
  40. package/dist/core/workflow/work-context.d.ts.map +1 -0
  41. package/dist/core/workflow/work-context.js +58 -0
  42. package/package.json +1 -1
  43. package/src/commands/supervisor.ts +32 -0
  44. package/src/core/supervisor/index.ts +5 -1
  45. package/src/core/supervisor/plan-api.ts +27 -1
  46. package/src/core/supervisor/plan-read.ts +4 -0
  47. package/src/core/supervisor/plan-types.ts +2 -0
  48. package/src/core/supervisor/planning.ts +52 -0
  49. package/src/core/supervisor/state.ts +7 -1
  50. package/src/core/work/runner.ts +9 -1
  51. package/src/core/work/state.ts +35 -4
  52. package/src/core/workflow/engine.ts +33 -2
  53. package/src/core/workflow/index.ts +5 -1
  54. package/src/core/workflow/proof.ts +12 -1
  55. package/src/core/workflow/run-state.ts +7 -1
  56. package/src/core/workflow/types.ts +17 -0
  57. package/src/core/workflow/work-context.ts +66 -0
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EAEZ,aAAa,EAId,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC,CAAC;IAClF,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACnC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;QACrC,SAAS,EAAE,eAAe,CAAC;QAC3B,aAAa,EAAE,mBAAmB,CAAC;KACpC,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,YAAY,EAAE,MAAM,GACnB,sBAAsB,CAqCxB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,sBAAsB,CA6BzB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,QAAQ,EAAE,sBAAsB,EAAE,GACjC;IAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAuB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa,CA2ChF;AAgCD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAe3E;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAkBjF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAoChE"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EAEZ,aAAa,EAIb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAgBpB,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAC5C,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC,CAAC;IAClF,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACnC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;QACrC,SAAS,EAAE,eAAe,CAAC;QAC3B,aAAa,EAAE,mBAAmB,CAAC;KACpC,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,YAAY,EAAE,MAAM,GACnB,sBAAsB,CAqCxB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,sBAAsB,CA6BzB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,QAAQ,EAAE,sBAAsB,EAAE,GACjC;IAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAuB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa,CA4ChF;AAgCD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAe3E;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAyBjF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAoChE"}
@@ -3,6 +3,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, u
3
3
  import { dirname, join } from "node:path";
4
4
  import { policyDigest } from "../policy/index.js";
5
5
  import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
6
+ import { isCanonicalWorkflowWorkContext } from "./work-context.js";
6
7
  const MAX_ACCEPTANCE_CRITERIA = 50;
7
8
  const MAX_EVIDENCE_RECORDS = 200;
8
9
  const MAX_PACKET_BYTES = 512 * 1024;
@@ -127,6 +128,7 @@ export function buildWorkflowProof(input) {
127
128
  started_at: input.startedAt,
128
129
  ended_at: input.endedAt,
129
130
  duration_ms: input.durationMs,
131
+ work_context: input.workContext,
130
132
  objective: input.meta.objective,
131
133
  error: clippedOptional(input.error, MAX_SUMMARY_CHARS),
132
134
  result: input.result === undefined ? undefined : digestResult(input.result),
@@ -209,7 +211,12 @@ export function readWorkflowProof(coordRoot, runId) {
209
211
  catch (error) {
210
212
  throw new Error(`cannot parse workflow proof at ${path}: ${error.message}`);
211
213
  }
212
- if (proof.schema_version !== WORKFLOW_PROOF_SCHEMA_VERSION || proof.run?.id !== runId) {
214
+ if (proof.schema_version !== WORKFLOW_PROOF_SCHEMA_VERSION ||
215
+ proof.run?.id !== runId ||
216
+ (proof.run.work_context !== undefined &&
217
+ (!proof.run.work_item_id ||
218
+ proof.run.work_context.id !== proof.run.work_item_id ||
219
+ !isCanonicalWorkflowWorkContext(proof.run.work_context)))) {
213
220
  throw new Error(`workflow proof at ${path} has an unsupported or mismatched schema`);
214
221
  }
215
222
  return proof;
@@ -1,11 +1,12 @@
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 } from "./types.js";
3
+ import type { 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
+ work_context?: WorkflowWorkContext;
9
10
  name: string;
10
11
  started_at: string;
11
12
  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,MAAM,YAAY,CAAC;AAE5D,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,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,CAgC7F;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;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"}
@@ -5,6 +5,7 @@ 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
7
  import { normalizeWorkflowSpecialists } from "./specialists.js";
8
+ import { isCanonicalWorkflowWorkContext } from "./work-context.js";
8
9
  export const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION = 1;
9
10
  const MANIFEST_LIMIT_BYTES = 256 * 1024;
10
11
  const FOREIGN_LEASE_STALE_MS = 24 * 60 * 60 * 1_000;
@@ -53,6 +54,10 @@ export function readWorkflowRunManifest(coordRoot, runId) {
53
54
  manifest.run_id !== runId ||
54
55
  (manifest.work_item_id !== undefined &&
55
56
  !/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(manifest.work_item_id)) ||
57
+ (manifest.work_context !== undefined &&
58
+ (!manifest.work_item_id ||
59
+ manifest.work_context.id !== manifest.work_item_id ||
60
+ !isCanonicalWorkflowWorkContext(manifest.work_context))) ||
56
61
  typeof manifest.name !== "string" ||
57
62
  manifest.name.length === 0 ||
58
63
  manifest.name.length > 200 ||
@@ -9,6 +9,7 @@
9
9
  import type { DispatchCostEstimator, ExternalMutationRequest, NormalizedPolicy, PolicyAskResolver, PolicyDecision, PolicyIsolation, PolicyNetworkAccess, PolicySpec } from "../policy/index.js";
10
10
  import type { BillingMode, BillingProber } from "./billing.js";
11
11
  export declare const WORKFLOW_PROOF_SCHEMA_VERSION: 1;
12
+ export declare const WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION: 1;
12
13
  export type EvidenceKind = "test" | "command" | "artifact" | "change" | "review" | "observation";
13
14
  export type EvidenceStatus = "passed" | "failed" | "observed" | "unknown";
14
15
  export type EvidenceSource = "workflow" | "engine";
@@ -126,6 +127,7 @@ export interface WorkflowProof {
126
127
  started_at: string;
127
128
  ended_at: string;
128
129
  duration_ms: number;
130
+ work_context?: WorkflowWorkContext;
129
131
  objective?: string;
130
132
  error?: string;
131
133
  result?: ResultDigest;
@@ -260,6 +262,9 @@ export type Spawner = (req: SpawnRequest) => Promise<SpawnResult>;
260
262
  /** The API surface injected into a workflow script's default export. Explicit
261
263
  * injection (no ambient globals): keeps scripts portable and unit-testable. */
262
264
  export interface WorkflowContext {
265
+ /** Frozen durable-work assignment for work-linked runs. Standalone and
266
+ * legacy-resumed workflows have no work context. */
267
+ work?: Readonly<WorkflowWorkContext>;
263
268
  /** Spawn one subagent; resolves to validated JSON (schema) or reply text. */
264
269
  agent: (prompt: string, opts?: AgentOpts) => Promise<unknown>;
265
270
  /** Run thunks with bounded concurrency; a rejected thunk resolves to null. */
@@ -284,6 +289,14 @@ export interface WorkflowModule {
284
289
  meta?: WorkflowMeta;
285
290
  default: (ctx: WorkflowContext) => Promise<unknown>;
286
291
  }
292
+ /** Minimal immutable durable-work input exposed to reusable workflow code. */
293
+ export interface WorkflowWorkContext {
294
+ readonly schema_version: typeof WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION;
295
+ readonly id: string;
296
+ readonly title: string;
297
+ readonly objective: string;
298
+ readonly acceptance: readonly string[];
299
+ }
287
300
  export interface EngineOpts {
288
301
  /** Repo root whose .harnery/ receives the run journal. */
289
302
  coordRoot: string;
@@ -306,6 +319,9 @@ export interface EngineOpts {
306
319
  runId?: string;
307
320
  /** Durable objective this execution attempt belongs to. */
308
321
  workItemId?: string;
322
+ /** Frozen assignment data supplied by a durable-work host. Requires the
323
+ * matching `workItemId`; parked resume always uses the manifest copy. */
324
+ workContext?: WorkflowWorkContext;
309
325
  /** Total-agent ceiling for the run (default 50): the runaway backstop. */
310
326
  maxAgents?: number;
311
327
  /** 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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"}
@@ -7,3 +7,4 @@
7
7
  * Design record: decision 0015 (portable coordination-aware workflows).
8
8
  */
9
9
  export const WORKFLOW_PROOF_SCHEMA_VERSION = 1;
10
+ export const WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION = 1;
@@ -0,0 +1,5 @@
1
+ import type { WorkflowWorkContext } from "./types.js";
2
+ export declare function normalizeWorkflowWorkContext(value: unknown): WorkflowWorkContext;
3
+ export declare function freezeWorkflowWorkContext(value: unknown): Readonly<WorkflowWorkContext>;
4
+ export declare function isCanonicalWorkflowWorkContext(value: unknown): value is WorkflowWorkContext;
5
+ //# sourceMappingURL=work-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-context.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/work-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAUtD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA+BhF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAIvF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAO3F"}
@@ -0,0 +1,58 @@
1
+ import { WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION } from "./types.js";
2
+ const WORK_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
3
+ const MAX_TITLE = 200;
4
+ const MAX_OBJECTIVE = 4_000;
5
+ const MAX_ACCEPTANCE = 50;
6
+ const MAX_ACCEPTANCE_ITEM = 500;
7
+ const FIELDS = new Set(["schema_version", "id", "title", "objective", "acceptance"]);
8
+ export function normalizeWorkflowWorkContext(value) {
9
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
10
+ throw new Error("workflow work context must be an object");
11
+ }
12
+ const input = value;
13
+ const extra = Object.keys(input).filter((key) => !FIELDS.has(key));
14
+ if (extra.length > 0) {
15
+ throw new Error(`workflow work context has unknown field ${JSON.stringify(extra[0])}`);
16
+ }
17
+ if (input.schema_version !== WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION) {
18
+ throw new Error("workflow work context has an unsupported schema");
19
+ }
20
+ const id = requiredString(input.id, "workflow work context id", 100);
21
+ if (!WORK_ID.test(id)) {
22
+ throw new Error(`invalid workflow work context id ${JSON.stringify(id)}`);
23
+ }
24
+ if (!Array.isArray(input.acceptance) || input.acceptance.length > MAX_ACCEPTANCE) {
25
+ throw new Error(`workflow work context acceptance must contain at most ${MAX_ACCEPTANCE} criteria`);
26
+ }
27
+ const acceptance = input.acceptance.map((criterion, index) => requiredString(criterion, `workflow work context acceptance[${index}]`, MAX_ACCEPTANCE_ITEM));
28
+ return {
29
+ schema_version: WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION,
30
+ id,
31
+ title: requiredString(input.title, "workflow work context title", MAX_TITLE),
32
+ objective: requiredString(input.objective, "workflow work context objective", MAX_OBJECTIVE),
33
+ acceptance,
34
+ };
35
+ }
36
+ export function freezeWorkflowWorkContext(value) {
37
+ const normalized = normalizeWorkflowWorkContext(value);
38
+ Object.freeze(normalized.acceptance);
39
+ return Object.freeze(normalized);
40
+ }
41
+ export function isCanonicalWorkflowWorkContext(value) {
42
+ try {
43
+ const normalized = normalizeWorkflowWorkContext(value);
44
+ return JSON.stringify(normalized) === JSON.stringify(value);
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ function requiredString(value, field, max) {
51
+ if (typeof value !== "string" || value.trim() === "") {
52
+ throw new Error(`${field} is required`);
53
+ }
54
+ const normalized = value.trim();
55
+ if (normalized.length > max)
56
+ throw new Error(`${field} exceeds ${max} characters`);
57
+ return normalized;
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harnery",
3
- "version": "0.19.1",
3
+ "version": "0.21.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",
@@ -20,6 +20,7 @@ import {
20
20
  readSupervisorServiceStatus,
21
21
  rejectSupervisorPlan,
22
22
  requestSupervisorServiceStop,
23
+ retrySupervisorPlan,
23
24
  runSupervisor,
24
25
  runSupervisorServiceDaemon,
25
26
  type SupervisorPlanOutcome,
@@ -256,6 +257,34 @@ function registerPlanCommand(supervisor: Command, emit: EmitContext): void {
256
257
  });
257
258
  },
258
259
  );
260
+
261
+ plan
262
+ .command("retry <goal-id> <plan-id>")
263
+ .description("Attach bounded guidance and authorize a new attempt after plan attention.")
264
+ .requiredOption("--reason <text>", "Guidance for the next planner attempt")
265
+ .option("--actor <name>", "Actor recorded on the retry request")
266
+ .option("--json", "Emit the plan outcome as JSON")
267
+ .action(
268
+ (
269
+ goalId: string,
270
+ planId: string,
271
+ opts: { actor?: string; reason: string; json?: boolean },
272
+ ) => {
273
+ withSupervisorRoot(emit, (coordRoot) => {
274
+ emitPlanOutcome(
275
+ retrySupervisorPlan({
276
+ coordRoot,
277
+ goalId,
278
+ planId,
279
+ actor: opts.actor,
280
+ reason: opts.reason,
281
+ }),
282
+ opts.json,
283
+ emit,
284
+ );
285
+ });
286
+ },
287
+ );
259
288
  }
260
289
 
261
290
  function registerServiceCommand(
@@ -723,6 +752,9 @@ function emitSupervisor(
723
752
  lines.push(`original root: ${record.intent.root_work_id}`);
724
753
  }
725
754
  if (projection.pending_plan_id) lines.push(`pending plan: ${projection.pending_plan_id}`);
755
+ if (projection.attention_plan_id) {
756
+ lines.push(`attention plan: ${projection.attention_plan_id}`);
757
+ }
726
758
  }
727
759
  if (record.intent.mission) {
728
760
  lines.push(`mission: ${record.intent.mission.objective}`);
@@ -1,4 +1,8 @@
1
- export { approveSupervisorPlan, rejectSupervisorPlan } from "./plan-api.ts";
1
+ export {
2
+ approveSupervisorPlan,
3
+ rejectSupervisorPlan,
4
+ retrySupervisorPlan,
5
+ } from "./plan-api.ts";
2
6
  export {
3
7
  readSupervisorPlan,
4
8
  readSupervisorPlanReviewReceipt,
@@ -1,5 +1,9 @@
1
1
  import type { SupervisorPlanOutcome } from "./plan-types.ts";
2
- import { applySupervisorPlanProposal, rejectSupervisorPlanProposal } from "./planning.ts";
2
+ import {
3
+ applySupervisorPlanProposal,
4
+ rejectSupervisorPlanProposal,
5
+ retrySupervisorPlanProposal,
6
+ } from "./planning.ts";
3
7
  import { acquireSupervisorLease, readSupervisorIgnoringLease } from "./state.ts";
4
8
 
5
9
  export function approveSupervisorPlan(input: {
@@ -45,3 +49,25 @@ export function rejectSupervisorPlan(input: {
45
49
  release();
46
50
  }
47
51
  }
52
+
53
+ export function retrySupervisorPlan(input: {
54
+ coordRoot: string;
55
+ goalId: string;
56
+ planId: string;
57
+ actor?: string;
58
+ reason: string;
59
+ }): SupervisorPlanOutcome {
60
+ const actor = input.actor?.trim() || `supervisor:${input.goalId}`;
61
+ const release = acquireSupervisorLease(input.coordRoot, input.goalId);
62
+ try {
63
+ return retrySupervisorPlanProposal({
64
+ coordRoot: input.coordRoot,
65
+ record: readSupervisorIgnoringLease(input.coordRoot, input.goalId),
66
+ planId: input.planId,
67
+ actor,
68
+ reason: input.reason,
69
+ });
70
+ } finally {
71
+ release();
72
+ }
73
+ }
@@ -39,6 +39,7 @@ const EVENT_TYPES = new Set<SupervisorPlanEventType>([
39
39
  "plan.applied",
40
40
  "plan.completed",
41
41
  "plan.rejected",
42
+ "plan.retry_requested",
42
43
  "plan.attention",
43
44
  "plan.failed",
44
45
  ]);
@@ -188,6 +189,9 @@ function deriveStatus(
188
189
  if (latest?.event === "plan.rejected") {
189
190
  return { status: "rejected", work_ids: [], reason: latest.reason };
190
191
  }
192
+ if (latest?.event === "plan.retry_requested") {
193
+ return { status: "retry_requested", work_ids: [], reason: latest.reason };
194
+ }
191
195
  if (latest?.event === "plan.attention") {
192
196
  return { status: "attention", work_ids: [], reason: latest.reason };
193
197
  }
@@ -87,6 +87,7 @@ export type SupervisorPlanEventType =
87
87
  | "plan.applied"
88
88
  | "plan.completed"
89
89
  | "plan.rejected"
90
+ | "plan.retry_requested"
90
91
  | "plan.attention"
91
92
  | "plan.failed";
92
93
 
@@ -154,6 +155,7 @@ export type SupervisorPlanStatus =
154
155
  | "applied"
155
156
  | "completed"
156
157
  | "rejected"
158
+ | "retry_requested"
157
159
  | "attention"
158
160
  | "failed";
159
161
 
@@ -583,6 +583,58 @@ export function rejectSupervisorPlanProposal(input: {
583
583
  return outcome(readSupervisorPlan(input.coordRoot, input.goalId, input.planId));
584
584
  }
585
585
 
586
+ export function retrySupervisorPlanProposal(input: {
587
+ coordRoot: string;
588
+ record: SupervisorRecord;
589
+ planId: string;
590
+ actor: string;
591
+ reason: string;
592
+ }): SupervisorPlanOutcome {
593
+ const policy = input.record.intent.replanning;
594
+ if (!policy) {
595
+ throw new Error(`supervisor ${input.record.intent.id} does not allow replanning`);
596
+ }
597
+ const reason = bounded(input.reason, "plan retry reason", MAX_REASON);
598
+ const history = readSupervisorPlans(
599
+ input.coordRoot,
600
+ input.record.intent.id,
601
+ input.record.intent.root_work_id,
602
+ );
603
+ const latest = history.latest;
604
+ if (!latest || latest.request.id !== input.planId) {
605
+ throw new Error(`supervisor plan ${input.planId} is not the latest plan`);
606
+ }
607
+ const triggerFingerprint = supervisorGraphFingerprint({
608
+ rootWorkId: history.active_root_work_id,
609
+ generation: history.generation,
610
+ work: input.record.work,
611
+ });
612
+ if (
613
+ latest.request.trigger_fingerprint !== triggerFingerprint ||
614
+ latest.request.prior_root_work_id !== history.active_root_work_id
615
+ ) {
616
+ throw new Error(`supervisor plan ${input.planId} no longer matches the active graph`);
617
+ }
618
+ if (history.completed) {
619
+ throw new Error(`supervisor ${input.record.intent.id} mission is already complete`);
620
+ }
621
+ if (latest.status === "retry_requested") return outcome(latest);
622
+ if (latest.status !== "attention") {
623
+ throw new Error(`supervisor plan ${input.planId} cannot be retried from ${latest.status}`);
624
+ }
625
+ if (history.plans.length >= policy.max_replans) {
626
+ throw new Error(
627
+ `supervisor ${input.record.intent.id} exhausted its ${policy.max_replans} replans`,
628
+ );
629
+ }
630
+ appendPlanEvent(input.coordRoot, input.record.intent.id, input.planId, {
631
+ event: "plan.retry_requested",
632
+ actor: input.actor,
633
+ reason,
634
+ });
635
+ return outcome(readSupervisorPlan(input.coordRoot, input.record.intent.id, input.planId));
636
+ }
637
+
586
638
  function createPlanRequest(
587
639
  coordRoot: string,
588
640
  record: SupervisorRecord,
@@ -97,6 +97,7 @@ export type SupervisorNextAction =
97
97
  | "plan_initial"
98
98
  | "plan_milestone"
99
99
  | "review_plan"
100
+ | "retry_plan"
100
101
  | "none";
101
102
 
102
103
  export interface SupervisorProjection {
@@ -121,6 +122,7 @@ export interface SupervisorProjection {
121
122
  milestones_completed: number;
122
123
  milestones_remaining: number;
123
124
  pending_plan_id?: string;
125
+ attention_plan_id?: string;
124
126
  latest_plan_status?: SupervisorPlanRecord["status"];
125
127
  governed_work_ids: string[];
126
128
  }
@@ -445,7 +447,11 @@ function deriveProjection(
445
447
  ...base,
446
448
  state: "awaiting_attention",
447
449
  reason: plans.latest.reason ?? `plan ${plans.latest.request.id} requires attention`,
448
- next_action: "none",
450
+ attention_plan_id: plans.latest.request.id,
451
+ next_action:
452
+ intent.replanning && plans.plans.length < intent.replanning.max_replans
453
+ ? "retry_plan"
454
+ : "none",
449
455
  };
450
456
  }
451
457
  if (!root && intent.mission) {
@@ -1,6 +1,7 @@
1
1
  import { resolve } from "node:path";
2
2
  import { runWorkflow } from "../workflow/engine.ts";
3
3
  import type { EngineOpts, RunReport } from "../workflow/types.ts";
4
+ import { WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION } from "../workflow/types.ts";
4
5
  import {
5
6
  acquireWorkLease,
6
7
  appendReconcileIfChanged,
@@ -14,7 +15,7 @@ import {
14
15
  export interface RunWorkItemInput {
15
16
  coordRoot: string;
16
17
  workId: string;
17
- engine: Omit<EngineOpts, "coordRoot" | "runId" | "resumeRunId" | "workItemId">;
18
+ engine: Omit<EngineOpts, "coordRoot" | "runId" | "resumeRunId" | "workItemId" | "workContext">;
18
19
  retry?: boolean;
19
20
  actor?: string;
20
21
  }
@@ -69,6 +70,13 @@ export async function runWorkItem(input: RunWorkItemInput): Promise<RunReport> {
69
70
  coordRoot,
70
71
  runId,
71
72
  workItemId: input.workId,
73
+ workContext: {
74
+ schema_version: WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION,
75
+ id: record.intent.id,
76
+ title: record.intent.title,
77
+ objective: record.intent.objective,
78
+ acceptance: [...record.intent.acceptance],
79
+ },
72
80
  });
73
81
  } finally {
74
82
  try {
@@ -317,7 +317,7 @@ function deriveWorkProjection(
317
317
  const terminal =
318
318
  latestGovernance?.event === "work.accepted" || latestGovernance?.event === "work.cancelled";
319
319
  const attemptEvents = events.filter((event) => event.event === "attempt.started");
320
- const attempts = attemptEvents.map((event) => inspectAttempt(coordRoot, event));
320
+ const attempts = attemptEvents.map((event) => inspectAttempt(coordRoot, event, intent));
321
321
  const base = {
322
322
  id: intent.id,
323
323
  title: intent.title,
@@ -342,7 +342,7 @@ function deriveWorkProjection(
342
342
  const reopenSeq = latestGovernance?.event === "work.reopened" ? latestGovernance.seq : 0;
343
343
  const currentAttempts = attemptEvents
344
344
  .filter((event) => event.seq > reopenSeq)
345
- .map((event) => inspectAttempt(coordRoot, event));
345
+ .map((event) => inspectAttempt(coordRoot, event, intent));
346
346
  const unresolved = intent.dependencies.filter((dependency) => {
347
347
  try {
348
348
  return readWorkItem(coordRoot, dependency).projection.state !== "succeeded";
@@ -419,7 +419,7 @@ function deriveWorkProjection(
419
419
  };
420
420
  }
421
421
 
422
- function inspectAttempt(coordRoot: string, event: WorkEvent): WorkAttempt {
422
+ function inspectAttempt(coordRoot: string, event: WorkEvent, intent: WorkIntent): WorkAttempt {
423
423
  const runId = event.run_id as string;
424
424
  const attempt: WorkAttempt = {
425
425
  number: event.attempt as number,
@@ -429,17 +429,32 @@ function inspectAttempt(coordRoot: string, event: WorkEvent): WorkAttempt {
429
429
  };
430
430
  const proofPath = join(coordRoot, ".harnery", "workflows", runId, "proof.json");
431
431
  const manifestPath = join(coordRoot, ".harnery", "workflows", runId, "run.json");
432
+ let manifest: ReturnType<typeof readWorkflowRunManifest> | undefined;
432
433
  if (existsSync(manifestPath)) {
433
- const manifest = readWorkflowRunManifest(coordRoot, runId);
434
+ manifest = readWorkflowRunManifest(coordRoot, runId);
434
435
  if (manifest.work_item_id !== event.work_id) {
435
436
  throw new Error(`workflow run ${runId} does not belong to work item ${event.work_id}`);
436
437
  }
438
+ if (
439
+ manifest.work_context !== undefined &&
440
+ JSON.stringify(manifest.work_context) !== JSON.stringify(workContextForIntent(intent))
441
+ ) {
442
+ throw new Error(
443
+ `workflow run ${runId} work context does not match work item ${event.work_id}`,
444
+ );
445
+ }
437
446
  }
438
447
  if (existsSync(proofPath)) {
439
448
  if (!existsSync(manifestPath)) {
440
449
  throw new Error(`workflow run ${runId} has proof without a work-linked manifest`);
441
450
  }
442
451
  const proof = readWorkflowProof(coordRoot, runId);
452
+ if (proof.run.work_item_id !== event.work_id) {
453
+ throw new Error(`workflow proof ${runId} does not belong to work item ${event.work_id}`);
454
+ }
455
+ if (JSON.stringify(proof.run.work_context) !== JSON.stringify(manifest?.work_context)) {
456
+ throw new Error(`workflow proof ${runId} work context does not match its run manifest`);
457
+ }
443
458
  attempt.proof_path = proofPath;
444
459
  attempt.status =
445
460
  proof.run.status === "succeeded" &&
@@ -471,6 +486,22 @@ function inspectAttempt(coordRoot: string, event: WorkEvent): WorkAttempt {
471
486
  return attempt;
472
487
  }
473
488
 
489
+ function workContextForIntent(intent: WorkIntent): {
490
+ schema_version: 1;
491
+ id: string;
492
+ title: string;
493
+ objective: string;
494
+ acceptance: string[];
495
+ } {
496
+ return {
497
+ schema_version: 1,
498
+ id: intent.id,
499
+ title: intent.title,
500
+ objective: intent.objective,
501
+ acceptance: [...intent.acceptance],
502
+ };
503
+ }
504
+
474
505
  function appendGovernanceEvent(
475
506
  coordRoot: string,
476
507
  workId: string,