agent-dealer 1.2.8 → 1.2.9

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 (51) hide show
  1. package/bundle/server/dist/adapters/github.js +80 -4
  2. package/bundle/server/dist/adapters/github.test.js +83 -1
  3. package/bundle/server/dist/adapters/worktree-deps.js +96 -0
  4. package/bundle/server/dist/adapters/worktree-deps.test.js +144 -0
  5. package/bundle/server/dist/coordinator/auto-merge.js +205 -1
  6. package/bundle/server/dist/coordinator/checks-wait-config.js +19 -0
  7. package/bundle/server/dist/coordinator/commands.js +194 -18
  8. package/bundle/server/dist/coordinator/commands.test.js +47 -0
  9. package/bundle/server/dist/coordinator/developer-effect.js +145 -3
  10. package/bundle/server/dist/coordinator/developer-effect.test.js +288 -3
  11. package/bundle/server/dist/coordinator/human-resolution.js +19 -0
  12. package/bundle/server/dist/coordinator/human-resolution.test.js +33 -0
  13. package/bundle/server/dist/coordinator/operator-criteria.js +168 -0
  14. package/bundle/server/dist/coordinator/operator-criteria.test.js +78 -0
  15. package/bundle/server/dist/coordinator/operator-verification.integration.test.js +347 -0
  16. package/bundle/server/dist/coordinator/playbook-feedback.js +3 -0
  17. package/bundle/server/dist/coordinator/projection.js +10 -4
  18. package/bundle/server/dist/coordinator/projection.test.js +13 -0
  19. package/bundle/server/dist/coordinator/prompts.js +134 -1
  20. package/bundle/server/dist/coordinator/prompts.test.js +148 -0
  21. package/bundle/server/dist/coordinator/recovery.js +57 -3
  22. package/bundle/server/dist/coordinator/recovery.test.js +67 -8
  23. package/bundle/server/dist/coordinator/repair-cycle.integration.test.js +1 -0
  24. package/bundle/server/dist/coordinator/reviewer-effect.js +6 -0
  25. package/bundle/server/dist/coordinator/routing.js +45 -6
  26. package/bundle/server/dist/coordinator/routing.test.js +62 -15
  27. package/bundle/server/dist/coordinator/usage-cap-defer.js +61 -0
  28. package/bundle/server/dist/db/ci-attempts-migration.test.js +70 -0
  29. package/bundle/server/dist/db/index.js +13 -0
  30. package/bundle/server/dist/db/schema.sql +2 -0
  31. package/bundle/server/dist/repository/issues.js +39 -3
  32. package/bundle/server/dist/repository/work-items.js +7 -0
  33. package/bundle/server/dist/runners/muse-code-args.js +25 -0
  34. package/bundle/server/dist/runners/muse-code-args.test.js +30 -0
  35. package/bundle/server/package.json +2 -2
  36. package/bundle/server/static-ui/assets/index-CU6fNntg.js +64 -0
  37. package/bundle/server/static-ui/index.html +1 -1
  38. package/bundle/shared/dist/human-actions.d.ts +4 -4
  39. package/bundle/shared/dist/human-actions.js +8 -0
  40. package/bundle/shared/dist/issues.d.ts +30 -0
  41. package/bundle/shared/dist/issues.js +14 -0
  42. package/bundle/shared/dist/issues.test.js +2 -0
  43. package/bundle/shared/dist/workflow.d.ts +4 -4
  44. package/bundle/shared/dist/workflow.js +6 -0
  45. package/bundle/shared/dist/workflow.test.js +1 -0
  46. package/bundle/shared/package.json +1 -1
  47. package/dist/action.js +4 -1
  48. package/dist/action.test.js +42 -0
  49. package/dist/index.js +1 -1
  50. package/package.json +1 -1
  51. package/bundle/server/static-ui/assets/index-B6SVCzMR.js +0 -64
@@ -8,7 +8,7 @@
8
8
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
9
9
  <meta name="theme-color" content="#0a0e14" />
10
10
  <link rel="preload" href="/fonts/Monaco.ttf" as="font" type="font/ttf" crossorigin />
11
- <script type="module" crossorigin src="/assets/index-B6SVCzMR.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-CU6fNntg.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-K_YcYkQU.css">
13
13
  </head>
14
14
  <body>
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export declare const HumanActionType: z.ZodEnum<["product_scope_decision", "policy_escalation", "attempts_exhausted", "final_review", "deck_interaction_required", "reflection_interaction_required", "outbound_delivery_interaction_required", "muse_capability"]>;
2
+ export declare const HumanActionType: z.ZodEnum<["product_scope_decision", "policy_escalation", "attempts_exhausted", "final_review", "deck_interaction_required", "reflection_interaction_required", "outbound_delivery_interaction_required", "muse_capability", "operator_verification"]>;
3
3
  export type HumanActionType = z.infer<typeof HumanActionType>;
4
4
  export declare const HumanActionStatus: z.ZodEnum<["open", "resolved"]>;
5
5
  export type HumanActionStatus = z.infer<typeof HumanActionStatus>;
@@ -12,7 +12,7 @@ export declare const HumanAction: z.ZodObject<{
12
12
  runId: z.ZodNullable<z.ZodString>;
13
13
  /** Nullable for pre-start product_scope_decision and imported legacy actions. */
14
14
  workflowInstanceId: z.ZodNullable<z.ZodString>;
15
- actionType: z.ZodEnum<["product_scope_decision", "policy_escalation", "attempts_exhausted", "final_review", "deck_interaction_required", "reflection_interaction_required", "outbound_delivery_interaction_required", "muse_capability"]>;
15
+ actionType: z.ZodEnum<["product_scope_decision", "policy_escalation", "attempts_exhausted", "final_review", "deck_interaction_required", "reflection_interaction_required", "outbound_delivery_interaction_required", "muse_capability", "operator_verification"]>;
16
16
  reason: z.ZodString;
17
17
  question: z.ZodString;
18
18
  evidenceJson: z.ZodNullable<z.ZodString>;
@@ -29,7 +29,7 @@ export declare const HumanAction: z.ZodObject<{
29
29
  requestedAt: z.ZodString;
30
30
  resolvedAt: z.ZodNullable<z.ZodString>;
31
31
  }, "strip", z.ZodTypeAny, {
32
- actionType: "policy_escalation" | "final_review" | "product_scope_decision" | "attempts_exhausted" | "deck_interaction_required" | "reflection_interaction_required" | "outbound_delivery_interaction_required" | "muse_capability";
32
+ actionType: "policy_escalation" | "final_review" | "product_scope_decision" | "attempts_exhausted" | "deck_interaction_required" | "reflection_interaction_required" | "outbound_delivery_interaction_required" | "muse_capability" | "operator_verification";
33
33
  question: string;
34
34
  reason: string;
35
35
  evidenceJson: string | null;
@@ -46,7 +46,7 @@ export declare const HumanAction: z.ZodObject<{
46
46
  requestedAt: string;
47
47
  resolvedAt: string | null;
48
48
  }, {
49
- actionType: "policy_escalation" | "final_review" | "product_scope_decision" | "attempts_exhausted" | "deck_interaction_required" | "reflection_interaction_required" | "outbound_delivery_interaction_required" | "muse_capability";
49
+ actionType: "policy_escalation" | "final_review" | "product_scope_decision" | "attempts_exhausted" | "deck_interaction_required" | "reflection_interaction_required" | "outbound_delivery_interaction_required" | "muse_capability" | "operator_verification";
50
50
  question: string;
51
51
  reason: string;
52
52
  evidenceJson: string | null;
@@ -30,6 +30,14 @@ export const HumanActionType = z.enum([
30
30
  * The only choice is `acknowledge`: for `missing` it records a per-version override
31
31
  * so admission proceeds on that version; for `unverified` it just dismisses. */
32
32
  "muse_capability",
33
+ /** An `[operator]` acceptance criterion from the frozen task snapshot (NOT-314):
34
+ * only a human with real credentials, a real login, or a paid session can prove
35
+ * it. Raised by the auto-merge gate (coordinator/auto-merge.ts) after reviewer
36
+ * approve, before the merge — the PR stays unmerged until the human records the
37
+ * result. Choices: `verified` (note = the result, stored as an artifact),
38
+ * `waive` (explicit waiver, note required, recorded as a workflow event), or
39
+ * `repair` (another developer round with the note threaded to its prompt). */
40
+ "operator_verification",
33
41
  ]);
34
42
  export const HumanActionStatus = z.enum(["open", "resolved"]);
35
43
  export const HumanAction = z.object({
@@ -3,6 +3,12 @@ export declare const IssueStatus: z.ZodEnum<["ready", "developing", "reviewing",
3
3
  export type IssueStatus = z.infer<typeof IssueStatus>;
4
4
  export declare const IssueOwner: z.ZodEnum<["human", "developer", "reviewer", "system"]>;
5
5
  export type IssueOwner = z.infer<typeof IssueOwner>;
6
+ /**
7
+ * NOT-313: default CI-repair budget — a failing CI check is the expected feedback
8
+ * loop, not an infrastructure failure, so it spends `ci_attempts` (bounded by this),
9
+ * never `infra_attempts`. Mirrors the infra default (3) deliberately.
10
+ */
11
+ export declare const DEFAULT_MAX_CI_ATTEMPTS = 3;
6
12
  /** "agent" covers an issue a coding agent created via the API/CLI (PRD §5). */
7
13
  export declare const IssueSource: z.ZodEnum<["manual", "linear", "agent"]>;
8
14
  export type IssueSource = z.infer<typeof IssueSource>;
@@ -75,6 +81,14 @@ export declare const Issue: z.ZodObject<{
75
81
  /** 0 is a valid policy: no automatic infra retry, escalate to a human immediately. */
76
82
  maxInfraAttempts: z.ZodNumber;
77
83
  infraAttempts: z.ZodNumber;
84
+ /**
85
+ * NOT-313: separate CI-repair budget. `checks_failed` spends `ciAttempts`
86
+ * (bounded by `maxCiAttempts`), every other retryable failure spends
87
+ * `infraAttempts`. 0 means no automatic CI repair — escalate immediately.
88
+ * Deliberately absent from CreateIssueInput/UpdateIssueInput (no per-ticket config).
89
+ */
90
+ maxCiAttempts: z.ZodNumber;
91
+ ciAttempts: z.ZodNumber;
78
92
  branch: z.ZodNullable<z.ZodString>;
79
93
  baseSha: z.ZodNullable<z.ZodString>;
80
94
  headSha: z.ZodNullable<z.ZodString>;
@@ -111,6 +125,8 @@ export declare const Issue: z.ZodObject<{
111
125
  currentRound: number;
112
126
  maxInfraAttempts: number;
113
127
  infraAttempts: number;
128
+ maxCiAttempts: number;
129
+ ciAttempts: number;
114
130
  baseSha: string | null;
115
131
  headSha: string | null;
116
132
  prNumber: number | null;
@@ -150,6 +166,8 @@ export declare const Issue: z.ZodObject<{
150
166
  currentRound: number;
151
167
  maxInfraAttempts: number;
152
168
  infraAttempts: number;
169
+ maxCiAttempts: number;
170
+ ciAttempts: number;
153
171
  baseSha: string | null;
154
172
  headSha: string | null;
155
173
  prNumber: number | null;
@@ -364,6 +382,14 @@ export declare const CreateIssueResult: z.ZodObject<{
364
382
  /** 0 is a valid policy: no automatic infra retry, escalate to a human immediately. */
365
383
  maxInfraAttempts: z.ZodNumber;
366
384
  infraAttempts: z.ZodNumber;
385
+ /**
386
+ * NOT-313: separate CI-repair budget. `checks_failed` spends `ciAttempts`
387
+ * (bounded by `maxCiAttempts`), every other retryable failure spends
388
+ * `infraAttempts`. 0 means no automatic CI repair — escalate immediately.
389
+ * Deliberately absent from CreateIssueInput/UpdateIssueInput (no per-ticket config).
390
+ */
391
+ maxCiAttempts: z.ZodNumber;
392
+ ciAttempts: z.ZodNumber;
367
393
  branch: z.ZodNullable<z.ZodString>;
368
394
  baseSha: z.ZodNullable<z.ZodString>;
369
395
  headSha: z.ZodNullable<z.ZodString>;
@@ -410,6 +436,8 @@ export declare const CreateIssueResult: z.ZodObject<{
410
436
  currentRound: number;
411
437
  maxInfraAttempts: number;
412
438
  infraAttempts: number;
439
+ maxCiAttempts: number;
440
+ ciAttempts: number;
413
441
  baseSha: string | null;
414
442
  headSha: string | null;
415
443
  prNumber: number | null;
@@ -452,6 +480,8 @@ export declare const CreateIssueResult: z.ZodObject<{
452
480
  currentRound: number;
453
481
  maxInfraAttempts: number;
454
482
  infraAttempts: number;
483
+ maxCiAttempts: number;
484
+ ciAttempts: number;
455
485
  baseSha: string | null;
456
486
  headSha: string | null;
457
487
  prNumber: number | null;
@@ -12,6 +12,12 @@ export const IssueStatus = z.enum([
12
12
  "closed",
13
13
  ]);
14
14
  export const IssueOwner = z.enum(["human", "developer", "reviewer", "system"]);
15
+ /**
16
+ * NOT-313: default CI-repair budget — a failing CI check is the expected feedback
17
+ * loop, not an infrastructure failure, so it spends `ci_attempts` (bounded by this),
18
+ * never `infra_attempts`. Mirrors the infra default (3) deliberately.
19
+ */
20
+ export const DEFAULT_MAX_CI_ATTEMPTS = 3;
15
21
  /** "agent" covers an issue a coding agent created via the API/CLI (PRD §5). */
16
22
  export const IssueSource = z.enum(["manual", "linear", "agent"]);
17
23
  export const Issue = z.object({
@@ -47,6 +53,14 @@ export const Issue = z.object({
47
53
  /** 0 is a valid policy: no automatic infra retry, escalate to a human immediately. */
48
54
  maxInfraAttempts: z.number().int().min(0),
49
55
  infraAttempts: z.number().int().min(0),
56
+ /**
57
+ * NOT-313: separate CI-repair budget. `checks_failed` spends `ciAttempts`
58
+ * (bounded by `maxCiAttempts`), every other retryable failure spends
59
+ * `infraAttempts`. 0 means no automatic CI repair — escalate immediately.
60
+ * Deliberately absent from CreateIssueInput/UpdateIssueInput (no per-ticket config).
61
+ */
62
+ maxCiAttempts: z.number().int().min(0),
63
+ ciAttempts: z.number().int().min(0),
50
64
  branch: z.string().nullable(),
51
65
  baseSha: z.string().nullable(),
52
66
  headSha: z.string().nullable(),
@@ -39,6 +39,8 @@ test("Issue schema parses a well-formed issue", () => {
39
39
  currentRound: 1,
40
40
  maxInfraAttempts: 3,
41
41
  infraAttempts: 0,
42
+ maxCiAttempts: 3,
43
+ ciAttempts: 0,
42
44
  branch: null,
43
45
  baseSha: null,
44
46
  headSha: null,
@@ -24,7 +24,7 @@ export declare const WorkflowInstance: z.ZodObject<{
24
24
  outcome: "done" | "closed" | "migrated" | null;
25
25
  }>;
26
26
  export type WorkflowInstance = z.infer<typeof WorkflowInstance>;
27
- export declare const WorkflowEventType: z.ZodEnum<["issue.created", "issue.reassigned", "workflow.started", "worker.started", "worker.completed", "worker.failed", "worker.deferred", "worktree.ready", "deck.connected", "brief.resolved", "branch.pushed", "checks.started", "pull_request.opened", "pull_request.updated", "checks.completed", "review.submitted", "repair.started", "guidance.added", "task_snapshot.refreshed", "human_action.requested", "human_action.resolved", "final_review.requested", "issue.completed", "issue.closed", "queue.enqueued", "queue.wait_reason_changed", "queue.admitted", "queue.removed", "agent.started", "agent.completed", "host.suspended", "checkpoint.observed", "retry.reused", "auto_merge.conflict_sync", "auto_merge.conflict_repair_queued", "legacy.imported"]>;
27
+ export declare const WorkflowEventType: z.ZodEnum<["issue.created", "issue.reassigned", "workflow.started", "worker.started", "worker.completed", "worker.failed", "worker.deferred", "worktree.ready", "worktree.deps_ready", "deck.connected", "brief.resolved", "branch.pushed", "checks.started", "pull_request.opened", "pull_request.updated", "checks.completed", "review.submitted", "repair.started", "guidance.added", "task_snapshot.refreshed", "human_action.requested", "human_action.resolved", "final_review.requested", "issue.completed", "issue.closed", "queue.enqueued", "queue.wait_reason_changed", "queue.admitted", "queue.removed", "agent.started", "agent.completed", "host.suspended", "checkpoint.observed", "retry.reused", "auto_merge.conflict_sync", "auto_merge.conflict_repair_queued", "operator_verification.waived", "legacy.imported"]>;
28
28
  export type WorkflowEventType = z.infer<typeof WorkflowEventType>;
29
29
  export declare const WorkflowEvent: z.ZodObject<{
30
30
  id: z.ZodString;
@@ -32,7 +32,7 @@ export declare const WorkflowEvent: z.ZodObject<{
32
32
  /** Nullable only for issue creation/guidance emitted before any workflow starts. */
33
33
  workflowInstanceId: z.ZodNullable<z.ZodString>;
34
34
  workerSessionId: z.ZodNullable<z.ZodString>;
35
- type: z.ZodEnum<["issue.created", "issue.reassigned", "workflow.started", "worker.started", "worker.completed", "worker.failed", "worker.deferred", "worktree.ready", "deck.connected", "brief.resolved", "branch.pushed", "checks.started", "pull_request.opened", "pull_request.updated", "checks.completed", "review.submitted", "repair.started", "guidance.added", "task_snapshot.refreshed", "human_action.requested", "human_action.resolved", "final_review.requested", "issue.completed", "issue.closed", "queue.enqueued", "queue.wait_reason_changed", "queue.admitted", "queue.removed", "agent.started", "agent.completed", "host.suspended", "checkpoint.observed", "retry.reused", "auto_merge.conflict_sync", "auto_merge.conflict_repair_queued", "legacy.imported"]>;
35
+ type: z.ZodEnum<["issue.created", "issue.reassigned", "workflow.started", "worker.started", "worker.completed", "worker.failed", "worker.deferred", "worktree.ready", "worktree.deps_ready", "deck.connected", "brief.resolved", "branch.pushed", "checks.started", "pull_request.opened", "pull_request.updated", "checks.completed", "review.submitted", "repair.started", "guidance.added", "task_snapshot.refreshed", "human_action.requested", "human_action.resolved", "final_review.requested", "issue.completed", "issue.closed", "queue.enqueued", "queue.wait_reason_changed", "queue.admitted", "queue.removed", "agent.started", "agent.completed", "host.suspended", "checkpoint.observed", "retry.reused", "auto_merge.conflict_sync", "auto_merge.conflict_repair_queued", "operator_verification.waived", "legacy.imported"]>;
36
36
  actorType: z.ZodEnum<["human", "developer", "reviewer", "system"]>;
37
37
  actorRef: z.ZodNullable<z.ZodString>;
38
38
  /** Issue status at emit time — lets the timeline render without re-deriving state. */
@@ -45,7 +45,7 @@ export declare const WorkflowEvent: z.ZodObject<{
45
45
  causationEventId: z.ZodNullable<z.ZodString>;
46
46
  ts: z.ZodString;
47
47
  }, "strip", z.ZodTypeAny, {
48
- type: "issue.created" | "issue.reassigned" | "workflow.started" | "worker.started" | "worker.completed" | "worker.failed" | "worker.deferred" | "worktree.ready" | "deck.connected" | "brief.resolved" | "branch.pushed" | "checks.started" | "pull_request.opened" | "pull_request.updated" | "checks.completed" | "review.submitted" | "repair.started" | "guidance.added" | "task_snapshot.refreshed" | "human_action.requested" | "human_action.resolved" | "final_review.requested" | "issue.completed" | "issue.closed" | "queue.enqueued" | "queue.wait_reason_changed" | "queue.admitted" | "queue.removed" | "agent.started" | "agent.completed" | "host.suspended" | "checkpoint.observed" | "retry.reused" | "auto_merge.conflict_sync" | "auto_merge.conflict_repair_queued" | "legacy.imported";
48
+ type: "issue.created" | "issue.reassigned" | "workflow.started" | "worker.started" | "worker.completed" | "worker.failed" | "worker.deferred" | "worktree.ready" | "worktree.deps_ready" | "deck.connected" | "brief.resolved" | "branch.pushed" | "checks.started" | "pull_request.opened" | "pull_request.updated" | "checks.completed" | "review.submitted" | "repair.started" | "guidance.added" | "task_snapshot.refreshed" | "human_action.requested" | "human_action.resolved" | "final_review.requested" | "issue.completed" | "issue.closed" | "queue.enqueued" | "queue.wait_reason_changed" | "queue.admitted" | "queue.removed" | "agent.started" | "agent.completed" | "host.suspended" | "checkpoint.observed" | "retry.reused" | "auto_merge.conflict_sync" | "auto_merge.conflict_repair_queued" | "operator_verification.waived" | "legacy.imported";
49
49
  id: string;
50
50
  issueId: string;
51
51
  round: number | null;
@@ -60,7 +60,7 @@ export declare const WorkflowEvent: z.ZodObject<{
60
60
  causationEventId: string | null;
61
61
  ts: string;
62
62
  }, {
63
- type: "issue.created" | "issue.reassigned" | "workflow.started" | "worker.started" | "worker.completed" | "worker.failed" | "worker.deferred" | "worktree.ready" | "deck.connected" | "brief.resolved" | "branch.pushed" | "checks.started" | "pull_request.opened" | "pull_request.updated" | "checks.completed" | "review.submitted" | "repair.started" | "guidance.added" | "task_snapshot.refreshed" | "human_action.requested" | "human_action.resolved" | "final_review.requested" | "issue.completed" | "issue.closed" | "queue.enqueued" | "queue.wait_reason_changed" | "queue.admitted" | "queue.removed" | "agent.started" | "agent.completed" | "host.suspended" | "checkpoint.observed" | "retry.reused" | "auto_merge.conflict_sync" | "auto_merge.conflict_repair_queued" | "legacy.imported";
63
+ type: "issue.created" | "issue.reassigned" | "workflow.started" | "worker.started" | "worker.completed" | "worker.failed" | "worker.deferred" | "worktree.ready" | "worktree.deps_ready" | "deck.connected" | "brief.resolved" | "branch.pushed" | "checks.started" | "pull_request.opened" | "pull_request.updated" | "checks.completed" | "review.submitted" | "repair.started" | "guidance.added" | "task_snapshot.refreshed" | "human_action.requested" | "human_action.resolved" | "final_review.requested" | "issue.completed" | "issue.closed" | "queue.enqueued" | "queue.wait_reason_changed" | "queue.admitted" | "queue.removed" | "agent.started" | "agent.completed" | "host.suspended" | "checkpoint.observed" | "retry.reused" | "auto_merge.conflict_sync" | "auto_merge.conflict_repair_queued" | "operator_verification.waived" | "legacy.imported";
64
64
  id: string;
65
65
  issueId: string;
66
66
  round: number | null;
@@ -21,6 +21,8 @@ export const WorkflowEventType = z.enum([
21
21
  "worker.deferred",
22
22
  /** Mid-session milestones (NOT-109) — low volume, not per-tool-call. */
23
23
  "worktree.ready",
24
+ /** NOT-315: pre-spawn dependency provisioning settled (ran or skipped). */
25
+ "worktree.deps_ready",
24
26
  "deck.connected",
25
27
  "brief.resolved",
26
28
  "branch.pushed",
@@ -69,6 +71,10 @@ export const WorkflowEventType = z.enum([
69
71
  * bound key: a later not-mergeable failure with no `human_action.resolved` after
70
72
  * this event escalates with the file list instead of syncing again. */
71
73
  "auto_merge.conflict_repair_queued",
74
+ /** NOT-314: the operator explicitly waived an `[operator]` criterion instead of
75
+ * running its probe (payload: headSha the waiver covers, waivedBy, note).
76
+ * The gate re-blocks when the head moves past the waived SHA. */
77
+ "operator_verification.waived",
72
78
  /** Migration-only — the NOT-66 cutover repoints a legacy `events` row under this type,
73
79
  * preserving the original type/payload inside `payloadJson` (see `role: "legacy"` on
74
80
  * `WorkerSessionRole` and `outcome: "migrated"` on `WorkflowInstanceOutcome` for the same
@@ -20,6 +20,7 @@ test("WorkflowEventType accepts every PRD §9.2 event type", () => {
20
20
  "worker.completed",
21
21
  "worker.failed",
22
22
  "worktree.ready",
23
+ "worktree.deps_ready",
23
24
  "deck.connected",
24
25
  "brief.resolved",
25
26
  "branch.pushed",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-dealer/shared",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/dist/action.js CHANGED
@@ -29,13 +29,16 @@ export async function runActionCommand(args) {
29
29
  const id = rest[0];
30
30
  const choice = flag(rest, "--choice");
31
31
  const resolvedBy = flag(rest, "--by");
32
+ // NOT-314: operator_verification requires a non-empty note (the result,
33
+ // waiver reason, or repair note) — the server 400s without one.
34
+ const note = flag(rest, "--note");
32
35
  if (!id || !choice || !resolvedBy) {
33
36
  console.error("resolve requires an action id, --choice, and --by");
34
37
  return 1;
35
38
  }
36
39
  const result = await apiFetch(`/api/human-actions/${id}/resolve`, {
37
40
  method: "POST",
38
- body: { choice, resolvedBy },
41
+ body: note?.trim() ? { choice, resolvedBy, note: note.trim() } : { choice, resolvedBy },
39
42
  });
40
43
  console.log(JSON.stringify(result, null, 2));
41
44
  return 0;
@@ -54,6 +54,48 @@ test("action resolve calls POST /api/human-actions/:id/resolve with resolvedBy a
54
54
  stub.restore();
55
55
  }
56
56
  });
57
+ test("action resolve forwards --note when given (required for operator_verification)", async () => {
58
+ const stub = stubFetch("/api/human-actions/a1/resolve", "POST", { issueStatus: "needs_human" });
59
+ try {
60
+ const code = await runActionCommand([
61
+ "resolve",
62
+ "a1",
63
+ "--choice",
64
+ "verified",
65
+ "--by",
66
+ "alice",
67
+ "--note",
68
+ "probe output here",
69
+ ]);
70
+ assert.equal(code, 0);
71
+ const body = stub.assertCalled();
72
+ assert.deepEqual(body, { choice: "verified", resolvedBy: "alice", note: "probe output here" });
73
+ }
74
+ finally {
75
+ stub.restore();
76
+ }
77
+ });
78
+ test("action resolve omits a blank --note so noteless resolves send the historical body", async () => {
79
+ const stub = stubFetch("/api/human-actions/a1/resolve", "POST", { issueStatus: "closed" });
80
+ try {
81
+ const code = await runActionCommand([
82
+ "resolve",
83
+ "a1",
84
+ "--choice",
85
+ "complete",
86
+ "--by",
87
+ "alice",
88
+ "--note",
89
+ " ",
90
+ ]);
91
+ assert.equal(code, 0);
92
+ const body = stub.assertCalled();
93
+ assert.deepEqual(body, { choice: "complete", resolvedBy: "alice" });
94
+ }
95
+ finally {
96
+ stub.restore();
97
+ }
98
+ });
57
99
  test("action resolve returns nonzero on API failure", async () => {
58
100
  const stub = stubFetch("/api/human-actions/a1/resolve", "POST", { error: "bad choice" }, 400);
59
101
  try {
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ function printUsage() {
29
29
  agent-dealer queue list
30
30
  agent-dealer queue move <issueId> --top|--bottom|--before <id>|--after <id>
31
31
  agent-dealer action list
32
- agent-dealer action resolve <id> --choice C --by NAME
32
+ agent-dealer action resolve <id> --choice C --by NAME [--note TEXT]
33
33
  agent-dealer --version
34
34
 
35
35
  Human control plane for agent execution.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dealer",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Human control plane for agent execution — queue, plan approval, audit",
5
5
  "license": "MIT",
6
6
  "type": "module",