harnery 0.17.0 → 0.19.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 (61) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/browse.d.ts.map +1 -1
  3. package/dist/commands/browse.js +187 -4
  4. package/dist/commands/supervisor.d.ts.map +1 -1
  5. package/dist/commands/supervisor.js +76 -4
  6. package/dist/core/supervisor/index.d.ts +3 -3
  7. package/dist/core/supervisor/index.d.ts.map +1 -1
  8. package/dist/core/supervisor/index.js +2 -2
  9. package/dist/core/supervisor/plan-read.d.ts +2 -1
  10. package/dist/core/supervisor/plan-read.d.ts.map +1 -1
  11. package/dist/core/supervisor/plan-read.js +222 -3
  12. package/dist/core/supervisor/plan-types.d.ts +60 -3
  13. package/dist/core/supervisor/plan-types.d.ts.map +1 -1
  14. package/dist/core/supervisor/plan-types.js +2 -0
  15. package/dist/core/supervisor/planning.d.ts.map +1 -1
  16. package/dist/core/supervisor/planning.js +804 -56
  17. package/dist/core/supervisor/read.d.ts +3 -3
  18. package/dist/core/supervisor/read.d.ts.map +1 -1
  19. package/dist/core/supervisor/read.js +2 -2
  20. package/dist/core/supervisor/runner.d.ts.map +1 -1
  21. package/dist/core/supervisor/runner.js +7 -2
  22. package/dist/core/supervisor/service.js +3 -0
  23. package/dist/core/supervisor/state.d.ts +17 -2
  24. package/dist/core/supervisor/state.d.ts.map +1 -1
  25. package/dist/core/supervisor/state.js +211 -33
  26. package/dist/core/workflow/engine.d.ts.map +1 -1
  27. package/dist/core/workflow/engine.js +24 -6
  28. package/dist/core/workflow/types.d.ts +6 -0
  29. package/dist/core/workflow/types.d.ts.map +1 -1
  30. package/dist/core/workflow/validate.d.ts +3 -2
  31. package/dist/core/workflow/validate.d.ts.map +1 -1
  32. package/dist/core/workflow/validate.js +31 -3
  33. package/dist/lib/browser/client.d.ts +18 -0
  34. package/dist/lib/browser/client.d.ts.map +1 -1
  35. package/dist/lib/browser/client.js +39 -0
  36. package/dist/lib/browser/geometry.d.ts +146 -0
  37. package/dist/lib/browser/geometry.d.ts.map +1 -0
  38. package/dist/lib/browser/geometry.js +525 -0
  39. package/dist/lib/browser/index.d.ts +2 -0
  40. package/dist/lib/browser/index.d.ts.map +1 -1
  41. package/dist/lib/browser/target-size.d.ts +65 -0
  42. package/dist/lib/browser/target-size.d.ts.map +1 -0
  43. package/dist/lib/browser/target-size.js +108 -0
  44. package/package.json +7 -1
  45. package/src/commands/browse.ts +319 -0
  46. package/src/commands/supervisor.ts +92 -5
  47. package/src/core/supervisor/index.ts +17 -1
  48. package/src/core/supervisor/plan-read.ts +292 -2
  49. package/src/core/supervisor/plan-types.ts +69 -1
  50. package/src/core/supervisor/planning.ts +1012 -51
  51. package/src/core/supervisor/read.ts +16 -1
  52. package/src/core/supervisor/runner.ts +9 -2
  53. package/src/core/supervisor/service.ts +3 -0
  54. package/src/core/supervisor/state.ts +272 -31
  55. package/src/core/workflow/engine.ts +29 -6
  56. package/src/core/workflow/types.ts +6 -0
  57. package/src/core/workflow/validate.ts +34 -3
  58. package/src/lib/browser/client.ts +62 -0
  59. package/src/lib/browser/geometry.ts +695 -0
  60. package/src/lib/browser/index.ts +25 -0
  61. package/src/lib/browser/target-size.ts +180 -0
@@ -1,6 +1,8 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
3
  import { join, resolve } from "node:path";
3
- import { SUPERVISOR_PLAN_SCHEMA_VERSION, } from "./plan-types.js";
4
+ import { readWorkItem } from "../work/read.js";
5
+ import { MAX_SUPERVISOR_PLAN_REVIEWERS, MAX_SUPERVISOR_PLAN_REVISION_ROUNDS, SUPERVISOR_PLAN_SCHEMA_VERSION, } from "./plan-types.js";
4
6
  const PLAN_ID = /^plan-[0-9]{4}-[a-f0-9]{8}$/;
5
7
  const GOAL_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
6
8
  const WORK_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
@@ -14,8 +16,10 @@ const MAX_EVENTS = 100;
14
16
  const EVENT_TYPES = new Set([
15
17
  "plan.awaiting_approval",
16
18
  "plan.resumed",
19
+ "plan.reviewed",
17
20
  "plan.proposed",
18
21
  "plan.applied",
22
+ "plan.completed",
19
23
  "plan.rejected",
20
24
  "plan.attention",
21
25
  "plan.failed",
@@ -32,6 +36,8 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
32
36
  generation: 0,
33
37
  applied_work_ids: [],
34
38
  materialized_work_ids: [],
39
+ milestones_completed: 0,
40
+ completed: false,
35
41
  };
36
42
  }
37
43
  const entries = readdirSync(root, { withFileTypes: true })
@@ -51,6 +57,8 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
51
57
  }
52
58
  let activeRoot = originalRootWorkId;
53
59
  let generation = 0;
60
+ let milestonesCompleted = 0;
61
+ let completed = false;
54
62
  const appliedWork = new Set();
55
63
  const materializedWork = new Set();
56
64
  for (const plan of plans) {
@@ -64,15 +72,27 @@ export function readSupervisorPlans(coordRootRaw, goalId, originalRootWorkId) {
64
72
  continue;
65
73
  activeRoot = plan.root_work_id;
66
74
  generation++;
75
+ if (plan.proposal?.milestone &&
76
+ readWorkItem(coordRoot, plan.root_work_id).projection.state === "succeeded") {
77
+ milestonesCompleted++;
78
+ }
67
79
  for (const workId of plan.work_ids)
68
80
  appliedWork.add(workId);
69
81
  }
82
+ const completedPlans = plans.filter((plan) => plan.status === "completed");
83
+ if (completedPlans.length > 1 ||
84
+ (completedPlans.length === 1 && completedPlans[0] !== plans.at(-1))) {
85
+ throw new Error(`supervisor ${goalId} has invalid completion history`);
86
+ }
87
+ completed = completedPlans.length === 1;
70
88
  return {
71
89
  plans,
72
90
  active_root_work_id: activeRoot,
73
91
  generation,
74
92
  applied_work_ids: [...appliedWork],
75
93
  materialized_work_ids: [...materializedWork],
94
+ milestones_completed: milestonesCompleted,
95
+ completed,
76
96
  latest: plans.at(-1),
77
97
  };
78
98
  }
@@ -89,12 +109,37 @@ export function readSupervisorPlan(coordRootRaw, goalId, planId) {
89
109
  : undefined;
90
110
  if (proposal)
91
111
  validateProposalEnvelope(proposal, planId);
112
+ const review = readSupervisorPlanReviewReceipt(coordRootRaw, goalId, planId);
92
113
  const events = readEvents(join(dir, "events.jsonl"), planId);
93
114
  const derived = deriveStatus(coordRoot, events, proposal);
94
- return { request, proposal, events, ...derived };
115
+ return {
116
+ request,
117
+ proposal,
118
+ review: review ? summarizeReview(review) : undefined,
119
+ events,
120
+ ...derived,
121
+ };
122
+ }
123
+ export function readSupervisorPlanReviewReceipt(coordRootRaw, goalId, planId) {
124
+ assertId(goalId, GOAL_ID, "supervisor id");
125
+ assertId(planId, PLAN_ID, "supervisor plan id");
126
+ const coordRoot = resolve(coordRootRaw);
127
+ const path = join(planDir(coordRoot, goalId, planId), "review.json");
128
+ if (!existsSync(path))
129
+ return undefined;
130
+ const receipt = readJson(path, "plan review receipt");
131
+ validateReviewReceipt(receipt, planId);
132
+ const reviewPolicy = readFrozenReviewPolicy(coordRoot, goalId);
133
+ if (reviewPolicy)
134
+ validateReviewReceiptMatchesPolicy(receipt, planId, reviewPolicy);
135
+ return receipt;
95
136
  }
96
137
  function deriveStatus(coordRoot, events, proposal) {
97
138
  const latest = events.at(-1);
139
+ const completed = [...events].reverse().find((event) => event.event === "plan.completed");
140
+ if (completed) {
141
+ return { status: "completed", work_ids: [], reason: completed.reason };
142
+ }
98
143
  const applied = [...events].reverse().find((event) => event.event === "plan.applied");
99
144
  if (applied) {
100
145
  return {
@@ -159,6 +204,8 @@ function validateRequest(request, goalId, planId) {
159
204
  !Number.isSafeInteger(request.sequence) ||
160
205
  request.sequence < 1 ||
161
206
  request.sequence > MAX_PLANS ||
207
+ (request.trigger !== undefined &&
208
+ !["initial", "recovery", "milestone"].includes(request.trigger)) ||
162
209
  typeof request.trigger_fingerprint !== "string" ||
163
210
  request.trigger_fingerprint.length < 1 ||
164
211
  request.trigger_fingerprint.length > 64_000 ||
@@ -171,7 +218,7 @@ function validateRequest(request, goalId, planId) {
171
218
  function validateProposalEnvelope(proposal, planId) {
172
219
  if (proposal.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
173
220
  proposal.plan_id !== planId ||
174
- !["apply", "attention"].includes(proposal.decision) ||
221
+ !["apply", "complete", "attention"].includes(proposal.decision) ||
175
222
  typeof proposal.rationale !== "string" ||
176
223
  proposal.rationale.length < 1 ||
177
224
  proposal.rationale.length > 2_000 ||
@@ -182,6 +229,28 @@ function validateProposalEnvelope(proposal, planId) {
182
229
  !validTimestamp(proposal.proposed_at)) {
183
230
  throw new Error(`supervisor plan proposal ${planId} has an unsupported schema`);
184
231
  }
232
+ if (proposal.milestone !== undefined) {
233
+ const milestone = proposal.milestone;
234
+ if (!Number.isSafeInteger(milestone.sequence) ||
235
+ milestone.sequence < 1 ||
236
+ milestone.sequence > 20 ||
237
+ typeof milestone.title !== "string" ||
238
+ milestone.title.length < 1 ||
239
+ milestone.title.length > 200 ||
240
+ typeof milestone.objective !== "string" ||
241
+ milestone.objective.length < 1 ||
242
+ milestone.objective.length > 4_000 ||
243
+ !Array.isArray(milestone.acceptance) ||
244
+ milestone.acceptance.length < 1 ||
245
+ milestone.acceptance.length > 50 ||
246
+ milestone.acceptance.some((criterion) => typeof criterion !== "string" || criterion.length < 1 || criterion.length > 500)) {
247
+ throw new Error(`supervisor plan proposal ${planId} milestone is invalid`);
248
+ }
249
+ }
250
+ if ((proposal.decision === "attention" || proposal.decision === "complete") &&
251
+ (proposal.root !== "" || proposal.work.length > 0 || proposal.milestone !== undefined)) {
252
+ throw new Error(`supervisor plan proposal ${planId} terminal decision contains work`);
253
+ }
185
254
  for (const [index, spec] of proposal.work.entries()) {
186
255
  if (!spec ||
187
256
  typeof spec !== "object" ||
@@ -203,6 +272,156 @@ function validateProposalEnvelope(proposal, planId) {
203
272
  }
204
273
  }
205
274
  }
275
+ function validateReviewReceipt(receipt, planId) {
276
+ if (!receipt ||
277
+ typeof receipt !== "object" ||
278
+ receipt.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
279
+ receipt.plan_id !== planId ||
280
+ !["passed", "revision_exhausted", "attention", "failed"].includes(receipt.status) ||
281
+ !/^[a-f0-9]{64}$/.test(receipt.candidate_sha256) ||
282
+ !Array.isArray(receipt.rounds) ||
283
+ receipt.rounds.length < 1 ||
284
+ receipt.rounds.length > MAX_SUPERVISOR_PLAN_REVISION_ROUNDS + 1) {
285
+ throw new Error(`supervisor plan review ${planId} has an unsupported schema`);
286
+ }
287
+ validateProposalEnvelope(receipt.final_candidate, planId);
288
+ if (receipt.candidate_sha256 !== candidateDigest(receipt.final_candidate)) {
289
+ throw new Error(`supervisor plan review ${planId} has invalid candidate digest`);
290
+ }
291
+ receipt.rounds.forEach((round, index) => {
292
+ validateReviewRound(round, planId, index + 1);
293
+ });
294
+ const finalRound = receipt.rounds.at(-1);
295
+ if (finalRound?.candidate_sha256 !== receipt.candidate_sha256) {
296
+ throw new Error(`supervisor plan review ${planId} final round does not match its candidate`);
297
+ }
298
+ if (receipt.status === "passed" && finalRound?.outcome !== "approved") {
299
+ throw new Error(`supervisor plan review ${planId} passed without approval`);
300
+ }
301
+ if (receipt.status === "attention" && finalRound?.outcome === "approved") {
302
+ throw new Error(`supervisor plan review ${planId} attention conflicts with approval`);
303
+ }
304
+ }
305
+ function readFrozenReviewPolicy(coordRoot, goalId) {
306
+ const path = join(coordRoot, ".harnery", "supervisors", goalId, "intent.json");
307
+ if (!existsSync(path))
308
+ return undefined;
309
+ const intent = readJson(path, "supervisor intent");
310
+ return intent.replanning?.review;
311
+ }
312
+ function validateReviewReceiptMatchesPolicy(receipt, planId, review) {
313
+ if (receipt.rounds.length > review.max_revision_rounds + 1) {
314
+ throw new Error(`supervisor plan review ${planId} exceeds the frozen review policy`);
315
+ }
316
+ for (const round of receipt.rounds) {
317
+ if (round.reviewers.length !== review.reviewer_specialists.length) {
318
+ throw new Error(`supervisor plan review ${planId} does not match the frozen review policy`);
319
+ }
320
+ round.reviewers.forEach((reviewer, index) => {
321
+ if (reviewer.specialist !== review.reviewer_specialists[index]) {
322
+ throw new Error(`supervisor plan review ${planId} does not match the frozen review policy`);
323
+ }
324
+ });
325
+ const outcome = aggregateReviewers(round.reviewers);
326
+ if (round.outcome !== outcome) {
327
+ throw new Error(`supervisor plan review ${planId} has an invalid reviewer outcome`);
328
+ }
329
+ }
330
+ const finalRound = receipt.rounds.at(-1);
331
+ if (receipt.status === "passed" && finalRound.outcome !== "approved") {
332
+ throw new Error(`supervisor plan review ${planId} passed without policy approval`);
333
+ }
334
+ if (receipt.status === "revision_exhausted" && finalRound.round <= review.max_revision_rounds) {
335
+ throw new Error(`supervisor plan review ${planId} exhausted before the frozen review limit`);
336
+ }
337
+ }
338
+ function aggregateReviewers(reviewers) {
339
+ if (reviewers.length < 1)
340
+ return "failed";
341
+ if (reviewers.some((reviewer) => reviewer.verdict === "attention"))
342
+ return "attention";
343
+ if (reviewers.some((reviewer) => reviewer.verdict === "revise" ||
344
+ reviewer.findings.some((finding) => finding.severity === "blocking"))) {
345
+ return "revise";
346
+ }
347
+ return "approved";
348
+ }
349
+ function candidateDigest(candidate) {
350
+ return createHash("sha256")
351
+ .update(JSON.stringify(canonicalCandidate(candidate)))
352
+ .digest("hex");
353
+ }
354
+ function canonicalCandidate(candidate) {
355
+ return {
356
+ schema_version: candidate.schema_version,
357
+ plan_id: candidate.plan_id,
358
+ decision: candidate.decision,
359
+ rationale: candidate.rationale,
360
+ root: candidate.root,
361
+ work: candidate.work,
362
+ milestone: candidate.milestone,
363
+ };
364
+ }
365
+ function validateReviewRound(round, planId, sequence) {
366
+ if (!round ||
367
+ typeof round !== "object" ||
368
+ round.round !== sequence ||
369
+ !/^[a-f0-9]{64}$/.test(round.candidate_sha256) ||
370
+ !Array.isArray(round.reviewers) ||
371
+ round.reviewers.length < 1 ||
372
+ round.reviewers.length > MAX_SUPERVISOR_PLAN_REVIEWERS ||
373
+ !["approved", "revise", "attention", "failed"].includes(round.outcome) ||
374
+ (round.revision_workflow_run_id !== undefined &&
375
+ !/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(round.revision_workflow_run_id))) {
376
+ throw new Error(`supervisor plan review ${planId} round ${sequence} is invalid`);
377
+ }
378
+ round.reviewers.forEach((reviewer, index) => {
379
+ validateReviewReviewer(reviewer, planId, sequence, index);
380
+ });
381
+ }
382
+ function validateReviewReviewer(reviewer, planId, round, index) {
383
+ if (!reviewer ||
384
+ typeof reviewer !== "object" ||
385
+ typeof reviewer.specialist !== "string" ||
386
+ reviewer.specialist.length < 1 ||
387
+ reviewer.specialist.length > 100 ||
388
+ !["approve", "revise", "attention"].includes(reviewer.verdict) ||
389
+ typeof reviewer.rationale !== "string" ||
390
+ reviewer.rationale.length < 1 ||
391
+ reviewer.rationale.length > 2_000 ||
392
+ !Array.isArray(reviewer.findings) ||
393
+ reviewer.findings.length > 50) {
394
+ throw new Error(`supervisor plan review ${planId} round ${round} reviewer ${index} is invalid`);
395
+ }
396
+ reviewer.findings.forEach((finding, findingIndex) => {
397
+ validateReviewFinding(finding, planId, round, index, findingIndex);
398
+ });
399
+ }
400
+ function validateReviewFinding(finding, planId, round, reviewerIndex, findingIndex) {
401
+ if (!finding ||
402
+ typeof finding !== "object" ||
403
+ typeof finding.code !== "string" ||
404
+ !/^[a-z][a-z0-9._-]{0,99}$/.test(finding.code) ||
405
+ !["blocking", "advisory"].includes(finding.severity) ||
406
+ typeof finding.summary !== "string" ||
407
+ finding.summary.length < 1 ||
408
+ finding.summary.length > 1_000 ||
409
+ typeof finding.recommendation !== "string" ||
410
+ finding.recommendation.length < 1 ||
411
+ finding.recommendation.length > 1_000) {
412
+ throw new Error(`supervisor plan review ${planId} round ${round} reviewer ${reviewerIndex} finding ${findingIndex} is invalid`);
413
+ }
414
+ }
415
+ function summarizeReview(receipt) {
416
+ const findings = receipt.rounds.flatMap((round) => round.reviewers.flatMap((reviewer) => reviewer.findings));
417
+ return {
418
+ status: receipt.status,
419
+ candidate_sha256: receipt.candidate_sha256,
420
+ rounds: receipt.rounds.length,
421
+ blocking_findings: findings.filter((finding) => finding.severity === "blocking").length,
422
+ advisory_findings: findings.filter((finding) => finding.severity === "advisory").length,
423
+ };
424
+ }
206
425
  function validateEvent(event, planId, sequence) {
207
426
  if (event.schema_version !== SUPERVISOR_PLAN_SCHEMA_VERSION ||
208
427
  event.plan_id !== planId ||
@@ -1,4 +1,6 @@
1
1
  export declare const SUPERVISOR_PLAN_SCHEMA_VERSION: 1;
2
+ export declare const MAX_SUPERVISOR_PLAN_REVIEWERS: 5;
3
+ export declare const MAX_SUPERVISOR_PLAN_REVISION_ROUNDS: 3;
2
4
  export interface SupervisorPlanTemplate {
3
5
  workflow: {
4
6
  path: string;
@@ -14,6 +16,10 @@ export interface SupervisorReplanningPolicy {
14
16
  max_work_items_per_plan: number;
15
17
  max_total_work_items: number;
16
18
  templates: Record<string, SupervisorPlanTemplate>;
19
+ review?: {
20
+ reviewer_specialists: string[];
21
+ max_revision_rounds: number;
22
+ };
17
23
  }
18
24
  export interface CreateSupervisorPlanTemplateInput {
19
25
  workflowPath: string;
@@ -27,17 +33,28 @@ export interface CreateSupervisorReplanningInput {
27
33
  maxWorkItemsPerPlan?: number;
28
34
  maxTotalWorkItems?: number;
29
35
  templates: Readonly<Record<string, CreateSupervisorPlanTemplateInput>>;
36
+ review?: {
37
+ reviewerSpecialists: readonly string[];
38
+ maxRevisionRounds: number;
39
+ };
30
40
  }
31
41
  export interface SupervisorPlanRequest {
32
42
  schema_version: typeof SUPERVISOR_PLAN_SCHEMA_VERSION;
33
43
  id: string;
34
44
  goal_id: string;
35
45
  sequence: number;
46
+ trigger?: "initial" | "recovery" | "milestone";
36
47
  trigger_fingerprint: string;
37
48
  prior_root_work_id: string;
38
49
  workflow_run_id: string;
39
50
  created_at: string;
40
51
  }
52
+ export interface SupervisorPlanMilestone {
53
+ sequence: number;
54
+ title: string;
55
+ objective: string;
56
+ acceptance: string[];
57
+ }
41
58
  export interface SupervisorPlanWorkSpec {
42
59
  key: string;
43
60
  title: string;
@@ -49,13 +66,50 @@ export interface SupervisorPlanWorkSpec {
49
66
  export interface SupervisorPlanProposal {
50
67
  schema_version: typeof SUPERVISOR_PLAN_SCHEMA_VERSION;
51
68
  plan_id: string;
52
- decision: "apply" | "attention";
69
+ decision: "apply" | "complete" | "attention";
53
70
  rationale: string;
54
71
  root: string;
55
72
  work: SupervisorPlanWorkSpec[];
73
+ milestone?: SupervisorPlanMilestone;
56
74
  proposed_at: string;
57
75
  }
58
- export type SupervisorPlanEventType = "plan.awaiting_approval" | "plan.resumed" | "plan.proposed" | "plan.applied" | "plan.rejected" | "plan.attention" | "plan.failed";
76
+ export type SupervisorPlanEventType = "plan.awaiting_approval" | "plan.resumed" | "plan.reviewed" | "plan.proposed" | "plan.applied" | "plan.completed" | "plan.rejected" | "plan.attention" | "plan.failed";
77
+ export type SupervisorPlanReviewStatus = "passed" | "revision_exhausted" | "attention" | "failed";
78
+ export type SupervisorPlanReviewVerdict = "approve" | "revise" | "attention";
79
+ export interface SupervisorPlanReviewFinding {
80
+ code: string;
81
+ severity: "blocking" | "advisory";
82
+ summary: string;
83
+ recommendation: string;
84
+ }
85
+ export interface SupervisorPlanReviewReviewer {
86
+ specialist: string;
87
+ verdict: SupervisorPlanReviewVerdict;
88
+ rationale: string;
89
+ findings: SupervisorPlanReviewFinding[];
90
+ }
91
+ export interface SupervisorPlanReviewRound {
92
+ round: number;
93
+ candidate_sha256: string;
94
+ reviewers: SupervisorPlanReviewReviewer[];
95
+ outcome: "approved" | "revise" | "attention" | "failed";
96
+ revision_workflow_run_id?: string;
97
+ }
98
+ export interface SupervisorPlanReviewReceipt {
99
+ schema_version: typeof SUPERVISOR_PLAN_SCHEMA_VERSION;
100
+ plan_id: string;
101
+ status: SupervisorPlanReviewStatus;
102
+ candidate_sha256: string;
103
+ final_candidate: SupervisorPlanProposal;
104
+ rounds: SupervisorPlanReviewRound[];
105
+ }
106
+ export interface SupervisorPlanReviewSummary {
107
+ status: SupervisorPlanReviewStatus;
108
+ candidate_sha256: string;
109
+ rounds: number;
110
+ blocking_findings: number;
111
+ advisory_findings: number;
112
+ }
59
113
  export interface SupervisorPlanEvent {
60
114
  schema_version: typeof SUPERVISOR_PLAN_SCHEMA_VERSION;
61
115
  plan_id: string;
@@ -68,10 +122,11 @@ export interface SupervisorPlanEvent {
68
122
  root_work_id?: string;
69
123
  work_ids?: string[];
70
124
  }
71
- export type SupervisorPlanStatus = "interrupted" | "awaiting_approval" | "resumable" | "proposed" | "applied" | "rejected" | "attention" | "failed";
125
+ export type SupervisorPlanStatus = "interrupted" | "awaiting_approval" | "resumable" | "proposed" | "applied" | "completed" | "rejected" | "attention" | "failed";
72
126
  export interface SupervisorPlanRecord {
73
127
  request: SupervisorPlanRequest;
74
128
  proposal?: SupervisorPlanProposal;
129
+ review?: SupervisorPlanReviewSummary;
75
130
  events: SupervisorPlanEvent[];
76
131
  status: SupervisorPlanStatus;
77
132
  approval_id?: string;
@@ -85,6 +140,8 @@ export interface SupervisorPlanHistory {
85
140
  generation: number;
86
141
  applied_work_ids: string[];
87
142
  materialized_work_ids: string[];
143
+ milestones_completed: number;
144
+ completed: boolean;
88
145
  latest?: SupervisorPlanRecord;
89
146
  }
90
147
  export interface SupervisorPlanOutcome {
@@ -1 +1 @@
1
- {"version":3,"file":"plan-types.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/plan-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan-types.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/plan-types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export const SUPERVISOR_PLAN_SCHEMA_VERSION = 1;
2
+ export const MAX_SUPERVISOR_PLAN_REVIEWERS = 5;
3
+ export const MAX_SUPERVISOR_PLAN_REVISION_ROUNDS = 3;
2
4
  export function supervisorGraphFingerprint(input) {
3
5
  return JSON.stringify([
4
6
  input.rootWorkId,
@@ -1 +1 @@
1
- {"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/planning.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAGL,KAAK,qBAAqB,EAK3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQnD,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAkGhC;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,qBAAqB,CAyFxB;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,qBAAqB,CAYxB"}
1
+ {"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/planning.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,UAAU,EAOhB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAIL,KAAK,qBAAqB,EAU3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQnD,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CA+LhC;AAuLD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,qBAAqB,CAsHxB;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,qBAAqB,CAYxB"}