@urateam/core 0.1.36 → 0.1.37

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 (32) hide show
  1. package/dist/__tests__/bec-181-circuit-breaker-audit-gap.test.js +16 -8
  2. package/dist/__tests__/bec-181-circuit-breaker-audit-gap.test.js.map +1 -1
  3. package/dist/__tests__/pm-escalation.test.d.ts +2 -0
  4. package/dist/__tests__/pm-escalation.test.d.ts.map +1 -0
  5. package/dist/__tests__/pm-escalation.test.js +273 -0
  6. package/dist/__tests__/pm-escalation.test.js.map +1 -0
  7. package/dist/__tests__/pm-triage-design-doc.test.d.ts +2 -0
  8. package/dist/__tests__/pm-triage-design-doc.test.d.ts.map +1 -0
  9. package/dist/__tests__/pm-triage-design-doc.test.js +226 -0
  10. package/dist/__tests__/pm-triage-design-doc.test.js.map +1 -0
  11. package/dist/audit/events.d.ts +12 -0
  12. package/dist/audit/events.d.ts.map +1 -1
  13. package/dist/audit/events.js +21 -0
  14. package/dist/audit/events.js.map +1 -1
  15. package/dist/pm/actions/db-queries.d.ts +11 -0
  16. package/dist/pm/actions/db-queries.d.ts.map +1 -1
  17. package/dist/pm/actions/db-queries.js +23 -0
  18. package/dist/pm/actions/db-queries.js.map +1 -1
  19. package/dist/pm/actions/promote.d.ts +21 -0
  20. package/dist/pm/actions/promote.d.ts.map +1 -1
  21. package/dist/pm/actions/promote.js +113 -3
  22. package/dist/pm/actions/promote.js.map +1 -1
  23. package/dist/pm/actions/triage.d.ts.map +1 -1
  24. package/dist/pm/actions/triage.js +78 -7
  25. package/dist/pm/actions/triage.js.map +1 -1
  26. package/dist/pm/types.d.ts +10 -0
  27. package/dist/pm/types.d.ts.map +1 -1
  28. package/dist/types.d.ts +2 -0
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js +6 -0
  31. package/dist/types.js.map +1 -1
  32. package/package.json +1 -1
@@ -139,18 +139,26 @@ async function assertPromoteBreakerSkip(opts) {
139
139
  expect(results[0].promoted).toBe(false);
140
140
  expect(results[0].reason).toMatch(/circuit.breaker/i);
141
141
  expect(results[0].reason).toContain(`${opts.failureCount} consecutive failed runs`);
142
- expect(client.updateIssue).not.toHaveBeenCalled();
142
+ // Tier 5 escalation: when the issue is NOT already labeled `needs-design`,
143
+ // promoteReadyIssues now attempts to label-update the issue and post a
144
+ // Linear comment (the side effects of escalation). The fixture above
145
+ // doesn't include `issueLabels` on the client, so the escalation's label
146
+ // lookup fails — but `createComment` is still called (defensive path).
147
+ // For BEC-181's contract verification we only assert that the circuit
148
+ // breaker still fires before conflict detection.
143
149
  // Breaker fires before conflict detection (saves tokens)
144
150
  expect(conflictChecker).not.toHaveBeenCalled();
145
151
  await flushFireAndForget();
146
- // Audit event is now written when the breaker fires
152
+ // Audit events: at minimum `pm.skipped_circuit_breaker` (BEC-181's
153
+ // contract) — Tier 5 may additionally emit `pm.escalated_to_needs_design`
154
+ // when the issue isn't already escalated. Both are expected after Tier 5.
147
155
  const auditRows = await db.select().from(auditEvents);
148
- expect(auditRows).toHaveLength(1);
149
- expect(auditRows[0].eventType).toBe("pm.skipped_circuit_breaker");
150
- expect(auditRows[0].issueId).toBe(opts.issueId);
151
- expect(JSON.parse(auditRows[0].payload).failureCount).toBe(opts.failureCount);
152
- expect(JSON.parse(auditRows[0].payload).threshold).toBe(opts.threshold);
153
- expect(JSON.parse(auditRows[0].payload).source).toBe("promote");
156
+ const breakerEvents = auditRows.filter((r) => r.eventType === "pm.skipped_circuit_breaker");
157
+ expect(breakerEvents).toHaveLength(1);
158
+ expect(breakerEvents[0].issueId).toBe(opts.issueId);
159
+ expect(JSON.parse(breakerEvents[0].payload).failureCount).toBe(opts.failureCount);
160
+ expect(JSON.parse(breakerEvents[0].payload).threshold).toBe(opts.threshold);
161
+ expect(JSON.parse(breakerEvents[0].payload).source).toBe("promote");
154
162
  }
155
163
  describe("BEC-181 Part 2: promoteReadyIssues circuit-breaker skip (working correctly)", () => {
156
164
  it("skips promotion for issue with 4 consecutive failures and writes a pm.skipped_circuit_breaker audit event (fix verified)", () => assertPromoteBreakerSkip({
@@ -1 +1 @@
1
- {"version":3,"file":"bec-181-circuit-breaker-audit-gap.test.js","sourceRoot":"","sources":["../../src/__tests__/bec-181-circuit-breaker-audit-gap.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bec-181-circuit-breaker-audit-gap.test.js","sourceRoot":"","sources":["../../src/__tests__/bec-181-circuit-breaker-audit-gap.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pm-escalation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm-escalation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pm-escalation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Tier 5 — escalation on consecutive failures.
3
+ *
4
+ * When the circuit breaker fires (≥ maxConsecutiveFailures failed runs in
5
+ * a row), the PM Agent escalates by:
6
+ * 1. Adding the `needs-design` label to the Linear issue (preserving
7
+ * existing labels)
8
+ * 2. Posting a Linear comment with the last failure's error message
9
+ * 3. Invoking the operator-supplied `slackPostAlert` callback
10
+ * 4. Emitting a `pm.escalated_to_needs_design` audit event
11
+ *
12
+ * Subsequent ticks find the `needs-design` label already in place and
13
+ * skip the escalation (the circuit-breaker event still fires for
14
+ * observability).
15
+ */
16
+ import { describe, it, expect, vi, beforeEach } from "vitest";
17
+ import { promoteReadyIssues } from "../pm/actions/promote.js";
18
+ function mockLinearClient(issues) {
19
+ const updateIssue = vi.fn().mockResolvedValue({ success: true });
20
+ const createComment = vi.fn().mockResolvedValue({ success: true });
21
+ const issueLabels = vi.fn().mockResolvedValue({
22
+ nodes: [
23
+ { id: "lbl_auto", name: "auto-implement" },
24
+ { id: "lbl_bug", name: "bug" },
25
+ { id: "lbl_nd", name: "needs-design" },
26
+ ],
27
+ });
28
+ const wrappedIssues = issues.map((i) => ({
29
+ ...i,
30
+ team: Promise.resolve(i.team),
31
+ state: Promise.resolve({ name: "Backlog" }),
32
+ labels: () => Promise.resolve({ nodes: i.labels }),
33
+ }));
34
+ return {
35
+ issues: vi.fn().mockResolvedValue({ nodes: wrappedIssues }),
36
+ issueLabels,
37
+ updateIssue,
38
+ createComment,
39
+ };
40
+ }
41
+ const failingIssue = {
42
+ id: "iss_fail",
43
+ identifier: "BEC-700",
44
+ title: "Some broken feature",
45
+ description: "...",
46
+ priority: 2,
47
+ team: { id: "team_1" },
48
+ labels: [{ id: "lbl_auto", name: "auto-implement" }],
49
+ };
50
+ const alreadyEscalatedIssue = {
51
+ id: "iss_already",
52
+ identifier: "BEC-701",
53
+ title: "Previously escalated",
54
+ description: "...",
55
+ priority: 2,
56
+ team: { id: "team_1" },
57
+ labels: [
58
+ { id: "lbl_auto", name: "auto-implement" },
59
+ { id: "lbl_nd", name: "needs-design" },
60
+ ],
61
+ };
62
+ describe("Tier 5 — escalation fires when circuit breaker trips on a non-escalated issue", () => {
63
+ beforeEach(() => {
64
+ vi.clearAllMocks();
65
+ });
66
+ it("adds the needs-design label, posts a Linear comment, calls slackPostAlert, and updates the result reason", async () => {
67
+ const linearClient = mockLinearClient([failingIssue]);
68
+ const checkConflict = vi.fn().mockResolvedValue({
69
+ overlapRisk: "none",
70
+ likelyFiles: [],
71
+ reasoning: "no conflict",
72
+ });
73
+ const slackPostAlert = vi.fn().mockResolvedValue(undefined);
74
+ const getLastError = vi
75
+ .fn()
76
+ .mockResolvedValue("Stage 'implement' failed: TypeError on line 42");
77
+ const results = await promoteReadyIssues({
78
+ linearClient: linearClient,
79
+ teamIds: ["team_1"],
80
+ slotsAvailable: 3,
81
+ checkConflict,
82
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
83
+ maxConsecutiveFailures: 3,
84
+ getFailureCount: vi.fn().mockResolvedValue(5),
85
+ getLastError,
86
+ slackPostAlert,
87
+ });
88
+ expect(results).toHaveLength(1);
89
+ expect(results[0].promoted).toBe(false);
90
+ expect(results[0].reason).toContain("escalated to needs-design");
91
+ expect(results[0].reason).not.toContain("already escalated");
92
+ // Label added (preserving existing)
93
+ expect(linearClient.updateIssue).toHaveBeenCalledWith("iss_fail", expect.objectContaining({
94
+ labelIds: expect.arrayContaining(["lbl_auto", "lbl_nd"]),
95
+ }));
96
+ // Comment posted
97
+ expect(linearClient.createComment).toHaveBeenCalledTimes(1);
98
+ const commentBody = linearClient.createComment.mock.calls[0][0].body;
99
+ expect(commentBody).toContain("Escalated to `needs-design`");
100
+ expect(commentBody).toMatch(/\*\*5\*\* consecutive failed pipeline runs/);
101
+ expect(commentBody).toContain("threshold 3");
102
+ expect(commentBody).toContain("TypeError on line 42");
103
+ // Slack alert fired
104
+ expect(slackPostAlert).toHaveBeenCalledTimes(1);
105
+ expect(slackPostAlert).toHaveBeenCalledWith({
106
+ issueId: "BEC-700",
107
+ issueTitle: "Some broken feature",
108
+ failureCount: 5,
109
+ errorMessage: "Stage 'implement' failed: TypeError on line 42",
110
+ });
111
+ });
112
+ it("renders a fallback message when no last-failure error is available", async () => {
113
+ const linearClient = mockLinearClient([failingIssue]);
114
+ const results = await promoteReadyIssues({
115
+ linearClient: linearClient,
116
+ teamIds: ["team_1"],
117
+ slotsAvailable: 3,
118
+ checkConflict: vi.fn().mockResolvedValue({
119
+ overlapRisk: "none",
120
+ likelyFiles: [],
121
+ reasoning: "no conflict",
122
+ }),
123
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
124
+ maxConsecutiveFailures: 3,
125
+ getFailureCount: vi.fn().mockResolvedValue(3),
126
+ getLastError: vi.fn().mockResolvedValue(null),
127
+ });
128
+ expect(results[0].reason).toContain("escalated to needs-design");
129
+ const commentBody = linearClient.createComment.mock.calls[0][0].body;
130
+ expect(commentBody).toContain("(no error message captured on the most recent failed run)");
131
+ });
132
+ it("truncates error messages over 500 chars in the Linear comment", async () => {
133
+ const linearClient = mockLinearClient([failingIssue]);
134
+ const longError = "x".repeat(2000);
135
+ await promoteReadyIssues({
136
+ linearClient: linearClient,
137
+ teamIds: ["team_1"],
138
+ slotsAvailable: 3,
139
+ checkConflict: vi.fn().mockResolvedValue({
140
+ overlapRisk: "none",
141
+ likelyFiles: [],
142
+ reasoning: "no conflict",
143
+ }),
144
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
145
+ maxConsecutiveFailures: 3,
146
+ getFailureCount: vi.fn().mockResolvedValue(3),
147
+ getLastError: vi.fn().mockResolvedValue(longError),
148
+ });
149
+ const commentBody = linearClient.createComment.mock.calls[0][0].body;
150
+ // Body contains the truncated form with a trailing ellipsis.
151
+ expect(commentBody).toMatch(/x{500}…/);
152
+ expect(commentBody).not.toMatch(/x{1000}/);
153
+ });
154
+ });
155
+ describe("Tier 5 — already-escalated issues skip the escalation (idempotency)", () => {
156
+ beforeEach(() => {
157
+ vi.clearAllMocks();
158
+ });
159
+ it("does NOT add the label again, does NOT post a second comment, does NOT call slackPostAlert", async () => {
160
+ const linearClient = mockLinearClient([alreadyEscalatedIssue]);
161
+ const slackPostAlert = vi.fn();
162
+ const results = await promoteReadyIssues({
163
+ linearClient: linearClient,
164
+ teamIds: ["team_1"],
165
+ slotsAvailable: 3,
166
+ checkConflict: vi.fn().mockResolvedValue({
167
+ overlapRisk: "none",
168
+ likelyFiles: [],
169
+ reasoning: "no conflict",
170
+ }),
171
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
172
+ maxConsecutiveFailures: 3,
173
+ getFailureCount: vi.fn().mockResolvedValue(5),
174
+ slackPostAlert,
175
+ });
176
+ expect(results).toHaveLength(1);
177
+ expect(results[0].reason).toContain("already escalated");
178
+ expect(linearClient.updateIssue).not.toHaveBeenCalled();
179
+ expect(linearClient.createComment).not.toHaveBeenCalled();
180
+ expect(slackPostAlert).not.toHaveBeenCalled();
181
+ });
182
+ });
183
+ describe("Tier 5 — no escalation when circuit breaker is disabled or threshold not reached", () => {
184
+ beforeEach(() => {
185
+ vi.clearAllMocks();
186
+ });
187
+ it("clean issue (failures below threshold) is promoted normally — no escalation side effects", async () => {
188
+ const linearClient = mockLinearClient([failingIssue]);
189
+ const slackPostAlert = vi.fn();
190
+ const results = await promoteReadyIssues({
191
+ linearClient: linearClient,
192
+ teamIds: ["team_1"],
193
+ slotsAvailable: 3,
194
+ checkConflict: vi.fn().mockResolvedValue({
195
+ overlapRisk: "none",
196
+ likelyFiles: [],
197
+ reasoning: "no conflict",
198
+ }),
199
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
200
+ maxConsecutiveFailures: 3,
201
+ getFailureCount: vi.fn().mockResolvedValue(1),
202
+ slackPostAlert,
203
+ });
204
+ expect(results).toHaveLength(1);
205
+ expect(results[0].promoted).toBe(true);
206
+ expect(slackPostAlert).not.toHaveBeenCalled();
207
+ // updateIssue was called for the normal promote (Backlog → Todo); confirm
208
+ // that single call did NOT include needs-design.
209
+ expect(linearClient.updateIssue).toHaveBeenCalledTimes(1);
210
+ const callArgs = linearClient.updateIssue.mock.calls[0];
211
+ expect(callArgs[1].labelIds).toBeUndefined();
212
+ });
213
+ it("when slackPostAlert is omitted, escalation still updates Linear + emits audit event", async () => {
214
+ // This proves the alert is best-effort: notifier outages don't suppress
215
+ // the audit / Linear-side signals.
216
+ const linearClient = mockLinearClient([failingIssue]);
217
+ const results = await promoteReadyIssues({
218
+ linearClient: linearClient,
219
+ teamIds: ["team_1"],
220
+ slotsAvailable: 3,
221
+ checkConflict: vi.fn().mockResolvedValue({
222
+ overlapRisk: "none",
223
+ likelyFiles: [],
224
+ reasoning: "no conflict",
225
+ }),
226
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
227
+ maxConsecutiveFailures: 3,
228
+ getFailureCount: vi.fn().mockResolvedValue(3),
229
+ getLastError: vi.fn().mockResolvedValue("err"),
230
+ // slackPostAlert omitted
231
+ });
232
+ expect(results[0].reason).toContain("escalated to needs-design");
233
+ expect(linearClient.updateIssue).toHaveBeenCalled();
234
+ expect(linearClient.createComment).toHaveBeenCalled();
235
+ });
236
+ });
237
+ describe("Tier 5 — defensive: label not found in workspace", () => {
238
+ beforeEach(() => {
239
+ vi.clearAllMocks();
240
+ });
241
+ it("logs a warn but does NOT crash when needs-design label is missing from the workspace", async () => {
242
+ const linearClient = mockLinearClient([failingIssue]);
243
+ // Override issueLabels to return no needs-design.
244
+ linearClient.issueLabels.mockResolvedValueOnce({
245
+ nodes: [
246
+ { id: "lbl_auto", name: "auto-implement" },
247
+ { id: "lbl_bug", name: "bug" },
248
+ ],
249
+ });
250
+ const results = await promoteReadyIssues({
251
+ linearClient: linearClient,
252
+ teamIds: ["team_1"],
253
+ slotsAvailable: 3,
254
+ checkConflict: vi.fn().mockResolvedValue({
255
+ overlapRisk: "none",
256
+ likelyFiles: [],
257
+ reasoning: "no conflict",
258
+ }),
259
+ stateMap: new Map([["team_1:Todo", "state_todo"]]),
260
+ maxConsecutiveFailures: 3,
261
+ getFailureCount: vi.fn().mockResolvedValue(3),
262
+ getLastError: vi.fn().mockResolvedValue("err"),
263
+ });
264
+ expect(results[0].reason).toContain("escalated to needs-design");
265
+ // Comment + label-update would have been attempted; updateIssue NOT called
266
+ // because needsDesignLabelId resolved to undefined.
267
+ expect(linearClient.updateIssue).not.toHaveBeenCalled();
268
+ // Comment still posted (so the operator sees the escalation rationale
269
+ // even when the label couldn't be applied).
270
+ expect(linearClient.createComment).toHaveBeenCalledTimes(1);
271
+ });
272
+ });
273
+ //# sourceMappingURL=pm-escalation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm-escalation.test.js","sourceRoot":"","sources":["../../src/__tests__/pm-escalation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pm-triage-design-doc.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm-triage-design-doc.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pm-triage-design-doc.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Tier 4 — triage produces a real design doc.
3
+ *
4
+ * The PM Agent's triage prompt is extended to also produce a 3-5 line
5
+ * `approachSummary`, an `openQuestions` array, and an `antiAcceptanceCriteria`
6
+ * array (anti-scope items). When `openQuestions.length > 0`, the ticket is
7
+ * forced to the `needs-design` pipeline label so the await-approval stage
8
+ * gates a human before any implement-stage tokens are spent — same routing
9
+ * mechanism as the QO observer-marker gate.
10
+ *
11
+ * Tests assert the routing decision and the structure of the Linear comment.
12
+ * The Claude SDK call is stubbed via the `callClaude` DI hook the triage
13
+ * function already accepts.
14
+ */
15
+ import { describe, it, expect, vi, beforeEach } from "vitest";
16
+ import { triageNewIssues } from "../pm/actions/triage.js";
17
+ function mockLinearClient(issues) {
18
+ const updateIssue = vi.fn().mockResolvedValue({ success: true });
19
+ const createComment = vi.fn().mockResolvedValue({ success: true });
20
+ const wrappedIssues = issues.map((i) => ({
21
+ ...i,
22
+ team: Promise.resolve(i.team),
23
+ state: Promise.resolve({ name: "Triage" }),
24
+ labels: () => Promise.resolve({ nodes: [] }),
25
+ }));
26
+ return {
27
+ issues: vi.fn().mockResolvedValue({ nodes: wrappedIssues }),
28
+ issueLabels: vi.fn().mockResolvedValue({
29
+ nodes: [
30
+ { id: "lbl_auto", name: "auto-implement" },
31
+ { id: "lbl_bug", name: "bug" },
32
+ { id: "lbl_qf", name: "quick-fix" },
33
+ { id: "lbl_nd", name: "needs-design" },
34
+ ],
35
+ }),
36
+ updateIssue,
37
+ createComment,
38
+ };
39
+ }
40
+ const sanitize = (text) => text;
41
+ const clearSpec = {
42
+ id: "iss_clear",
43
+ identifier: "BEC-100",
44
+ title: "Add a foo flag",
45
+ description: "Add a boolean `foo` flag to `BarConfig`. Default to false.",
46
+ team: { id: "team_1" },
47
+ };
48
+ const ambiguousSpec = {
49
+ id: "iss_ambig",
50
+ identifier: "BEC-101",
51
+ title: "Improve the thing",
52
+ description: "Make the thing better somehow.",
53
+ team: { id: "team_1" },
54
+ };
55
+ describe("triage Tier 4 — clear-spec issue routes to normal pipeline (no openQuestions)", () => {
56
+ beforeEach(() => {
57
+ vi.clearAllMocks();
58
+ });
59
+ it("routes a clear-spec issue to auto-implement (complexity != trivial) when openQuestions is empty", async () => {
60
+ const linearClient = mockLinearClient([clearSpec]);
61
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
62
+ priority: 2,
63
+ labels: ["feature"],
64
+ complexity: "small",
65
+ rationale: "clear feature request",
66
+ approachSummary: "Add a `foo` boolean to BarConfig schema, default false. Plumb through to where BarConfig is consumed. Add a unit test.",
67
+ openQuestions: [],
68
+ antiAcceptanceCriteria: ["must NOT add new dependencies"],
69
+ acceptanceCriteria: [
70
+ "BarConfig schema in types.ts gains a `foo` boolean field with default false",
71
+ "config/bar.ts reads `config.foo` and branches on it",
72
+ "tests/bar.test.ts asserts both `foo: true` and `foo: false`",
73
+ ],
74
+ }));
75
+ const results = await triageNewIssues({
76
+ linearClient: linearClient,
77
+ teamIds: ["team_1"],
78
+ callClaude,
79
+ sanitize,
80
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
81
+ });
82
+ expect(results).toHaveLength(1);
83
+ expect(results[0].issueId).toBe("BEC-100");
84
+ expect(results[0].labels).toContain("auto-implement");
85
+ expect(results[0].labels).not.toContain("needs-design");
86
+ expect(results[0].openQuestions ?? []).toEqual([]);
87
+ expect(results[0].approachSummary).toContain("BarConfig");
88
+ expect(results[0].antiAcceptanceCriteria).toEqual([
89
+ "must NOT add new dependencies",
90
+ ]);
91
+ const updateCall = linearClient.updateIssue.mock.calls[0];
92
+ expect(updateCall[1].labelIds).toContain("lbl_auto");
93
+ expect(updateCall[1].labelIds).not.toContain("lbl_nd");
94
+ });
95
+ it("posts a Linear comment that includes Approach + Anti-acceptance sections (when non-empty)", async () => {
96
+ const linearClient = mockLinearClient([clearSpec]);
97
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
98
+ priority: 2,
99
+ labels: ["feature"],
100
+ complexity: "small",
101
+ rationale: "clear feature request",
102
+ approachSummary: "Add field, plumb through, test.",
103
+ openQuestions: [],
104
+ antiAcceptanceCriteria: ["must NOT add new dependencies"],
105
+ acceptanceCriteria: ["BarConfig schema gains foo"],
106
+ }));
107
+ await triageNewIssues({
108
+ linearClient: linearClient,
109
+ teamIds: ["team_1"],
110
+ callClaude,
111
+ sanitize,
112
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
113
+ });
114
+ const commentCall = linearClient.createComment.mock.calls[0];
115
+ const body = commentCall[0].body;
116
+ expect(body).toContain("**Approach (Tier 4):**");
117
+ expect(body).toContain("Anti-acceptance criteria");
118
+ expect(body).toContain("must NOT add new dependencies");
119
+ expect(body).not.toContain("Open questions");
120
+ });
121
+ });
122
+ describe("triage Tier 4 — ambiguous-spec issue forces needs-design (openQuestions non-empty)", () => {
123
+ beforeEach(() => {
124
+ vi.clearAllMocks();
125
+ });
126
+ it("routes to needs-design when Claude flags open questions, regardless of complexity classification", async () => {
127
+ const linearClient = mockLinearClient([ambiguousSpec]);
128
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
129
+ priority: 3,
130
+ labels: ["feature"],
131
+ complexity: "small", // would normally → "auto-implement"
132
+ rationale: "ambiguous — needs clarification",
133
+ approachSummary: "Could not formulate a clear approach due to ambiguity. See open questions.",
134
+ openQuestions: [
135
+ "What does 'better' mean — performance, UX, code quality?",
136
+ "Which user-facing surface is in scope?",
137
+ ],
138
+ antiAcceptanceCriteria: [],
139
+ acceptanceCriteria: [],
140
+ }));
141
+ const results = await triageNewIssues({
142
+ linearClient: linearClient,
143
+ teamIds: ["team_1"],
144
+ callClaude,
145
+ sanitize,
146
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
147
+ });
148
+ expect(results).toHaveLength(1);
149
+ expect(results[0].labels).toContain("needs-design");
150
+ expect(results[0].labels).not.toContain("auto-implement");
151
+ expect(results[0].openQuestions).toHaveLength(2);
152
+ const updateCall = linearClient.updateIssue.mock.calls[0];
153
+ expect(updateCall[1].labelIds).toContain("lbl_nd");
154
+ });
155
+ it("posts an Open Questions section in the Linear comment when forced to needs-design", async () => {
156
+ const linearClient = mockLinearClient([ambiguousSpec]);
157
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
158
+ priority: 3,
159
+ labels: ["feature"],
160
+ complexity: "small",
161
+ rationale: "ambiguous",
162
+ approachSummary: "TBD pending clarification.",
163
+ openQuestions: ["Which feature does this refer to?"],
164
+ antiAcceptanceCriteria: [],
165
+ acceptanceCriteria: [],
166
+ }));
167
+ await triageNewIssues({
168
+ linearClient: linearClient,
169
+ teamIds: ["team_1"],
170
+ callClaude,
171
+ sanitize,
172
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
173
+ });
174
+ const commentCall = linearClient.createComment.mock.calls[0];
175
+ const body = commentCall[0].body;
176
+ expect(body).toContain("routed to needs-design");
177
+ expect(body).toContain("Open questions (must be answered before implement)");
178
+ expect(body).toContain("Which feature does this refer to?");
179
+ expect(body).toContain("**Pipeline:** needs-design");
180
+ });
181
+ it("trims whitespace-only questions and only fires routing for substantive entries", async () => {
182
+ const linearClient = mockLinearClient([ambiguousSpec]);
183
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
184
+ priority: 3,
185
+ labels: ["feature"],
186
+ complexity: "small",
187
+ rationale: "fixture",
188
+ approachSummary: "test approach",
189
+ openQuestions: [" ", "", " Real question? "],
190
+ antiAcceptanceCriteria: [],
191
+ acceptanceCriteria: [],
192
+ }));
193
+ const results = await triageNewIssues({
194
+ linearClient: linearClient,
195
+ teamIds: ["team_1"],
196
+ callClaude,
197
+ sanitize,
198
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
199
+ });
200
+ expect(results[0].openQuestions).toEqual(["Real question?"]);
201
+ expect(results[0].labels).toContain("needs-design");
202
+ });
203
+ it("treats missing/undefined openQuestions field as empty (backwards compat with classifier omissions)", async () => {
204
+ const linearClient = mockLinearClient([clearSpec]);
205
+ const callClaude = vi.fn().mockResolvedValue(JSON.stringify({
206
+ priority: 2,
207
+ labels: ["feature"],
208
+ complexity: "small",
209
+ rationale: "clear",
210
+ approachSummary: "do the thing",
211
+ // openQuestions and antiAcceptanceCriteria omitted entirely
212
+ acceptanceCriteria: ["criterion 1"],
213
+ }));
214
+ const results = await triageNewIssues({
215
+ linearClient: linearClient,
216
+ teamIds: ["team_1"],
217
+ callClaude,
218
+ sanitize,
219
+ stateMap: new Map([["team_1:Backlog", "state_backlog"]]),
220
+ });
221
+ expect(results[0].labels).not.toContain("needs-design");
222
+ expect(results[0].openQuestions).toBeUndefined();
223
+ expect(results[0].antiAcceptanceCriteria).toBeUndefined();
224
+ });
225
+ });
226
+ //# sourceMappingURL=pm-triage-design-doc.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm-triage-design-doc.test.js","sourceRoot":"","sources":["../../src/__tests__/pm-triage-design-doc.test.ts"],"names":[],"mappings":"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"}
@@ -276,6 +276,18 @@ export declare function pipelineAutoDeepReviewBumpedEvent(args: {
276
276
  from: number;
277
277
  to: number;
278
278
  }): AuditEvent;
279
+ /**
280
+ * Tier 5 — emitted when an issue trips the consecutive-failures circuit
281
+ * breaker (≥ maxConsecutiveFailures failed pipeline runs in a row) and the
282
+ * PM Agent escalates it to needs-design. Carries the truncated error
283
+ * message from the most-recent failed run so operators can see what kept
284
+ * failing without opening the run logs.
285
+ */
286
+ export declare function pmEscalatedToNeedsDesignEvent(args: {
287
+ issueId: string;
288
+ failureCount: number;
289
+ errorMessage: string | null;
290
+ }): AuditEvent;
279
291
  export declare function pipelineSpecVsImplFailedEvent(args: {
280
292
  runId: string;
281
293
  issueId: string;