@wildorder/nightshift 0.3.1 → 0.5.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 (44) hide show
  1. package/README.md +48 -1
  2. package/dist/agent-runner.d.ts +18 -0
  3. package/dist/agent-runner.d.ts.map +1 -1
  4. package/dist/agent-runner.js +26 -0
  5. package/dist/agent-runner.js.map +1 -1
  6. package/dist/author.d.ts +64 -0
  7. package/dist/author.d.ts.map +1 -0
  8. package/dist/author.js +627 -0
  9. package/dist/author.js.map +1 -0
  10. package/dist/cli.js +110 -1
  11. package/dist/cli.js.map +1 -1
  12. package/dist/config.d.ts +14 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +7 -1
  15. package/dist/config.js.map +1 -1
  16. package/dist/decide.d.ts +49 -0
  17. package/dist/decide.d.ts.map +1 -0
  18. package/dist/decide.js +178 -0
  19. package/dist/decide.js.map +1 -0
  20. package/dist/decider-review.d.ts +21 -0
  21. package/dist/decider-review.d.ts.map +1 -0
  22. package/dist/decider-review.js +98 -0
  23. package/dist/decider-review.js.map +1 -0
  24. package/dist/findings.d.ts +3 -21
  25. package/dist/findings.d.ts.map +1 -1
  26. package/dist/findings.js +0 -7
  27. package/dist/findings.js.map +1 -1
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/manifest.d.ts +2 -0
  33. package/dist/manifest.d.ts.map +1 -1
  34. package/dist/manifest.js +2 -0
  35. package/dist/manifest.js.map +1 -1
  36. package/dist/review-pass.d.ts +64 -0
  37. package/dist/review-pass.d.ts.map +1 -0
  38. package/dist/review-pass.js +370 -0
  39. package/dist/review-pass.js.map +1 -0
  40. package/dist/run-program.d.ts +20 -0
  41. package/dist/run-program.d.ts.map +1 -1
  42. package/dist/run-program.js +445 -131
  43. package/dist/run-program.js.map +1 -1
  44. package/package.json +2 -2
@@ -1,6 +1,7 @@
1
1
  /**
2
- * `advisory` never fails a gate and never keeps the convergence loop running.
3
- * It is where the severity policy puts observations that name no cause.
2
+ * Routes a finding's destination (see `findingDestination` in
3
+ * `review-pass.ts`): blocker and major reach the decision ledger, minor and
4
+ * advisory are reported only. Never a gate — nothing here fails a build.
4
5
  */
5
6
  export type Severity = "blocker" | "major" | "minor" | "advisory";
6
7
  export declare const SEVERITY_ORDER: readonly Severity[];
@@ -46,13 +47,6 @@ export interface Finding {
46
47
  evidence: Evidence[];
47
48
  workstreamId?: string;
48
49
  file?: string;
49
- /**
50
- * The fix is not an edit to a spec — the workstream must be split, a
51
- * workstream is missing, the manifest's ordering is itself wrong. Ends the
52
- * convergence loop immediately rather than spending further rounds
53
- * polishing a spec that should not exist in that shape.
54
- */
55
- requiresReplan?: boolean;
56
50
  /** Set by the policy layer when it downgrades, explaining why. */
57
51
  downgradedFrom?: Severity;
58
52
  downgradeReason?: string;
@@ -61,15 +55,6 @@ export interface Finding {
61
55
  export type IdentifiedFinding = Finding & {
62
56
  id: string;
63
57
  };
64
- /** Proof that a model inspected a defect's whole equivalence class. */
65
- export interface ClassAnalysis {
66
- subject: string;
67
- scope: "isolated" | "systemic";
68
- rootCause: string;
69
- affectedSubjects: string[];
70
- checkedSubjects: string[];
71
- completenessBasis: string;
72
- }
73
58
  export declare function identify(finding: Finding): IdentifiedFinding;
74
59
  /**
75
60
  * Critics recurrently merge criteria that share a root cause into one subject
@@ -94,9 +79,6 @@ export declare function normalizeSubject(subject: string): string;
94
79
  * way to detect a round that produced nothing new.
95
80
  */
96
81
  export declare function fingerprint(finding: Finding): string;
97
- export declare function isGateFailing(finding: Finding, strict: boolean): boolean;
98
- /** Blockers and majors are what keep the loop running; minors never do. */
99
- export declare function haltsConvergence(finding: Finding): boolean;
100
82
  export declare function countBySeverity(findings: readonly Finding[]): Record<Severity, number>;
101
83
  export declare function sortBySeverity(findings: readonly Finding[]): Finding[];
102
84
  /** Convenience constructors keep deterministic call sites terse. */
@@ -1 +1 @@
1
- {"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../src/findings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../src/findings.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAElE,eAAO,MAAM,cAAc,EAAE,SAAS,QAAQ,EAKpC,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,8KAWrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAChB;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAE5D;AAID;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAIhE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQxD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOpD;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAS1B;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAKtE;AAED,oEAAoE;AACpE,eAAO,MAAM,EAAE,GACb,MAAM,MAAM,EACZ,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,QAKD,CAAC;AAEH,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,KAAG,QAIvD,CAAC;AAEH,eAAO,MAAM,QAAQ,GACnB,QAAQ,WAAW,GAAG,WAAW,EACjC,OAAO,MAAM,KACZ,QAAoD,CAAC"}
package/dist/findings.js CHANGED
@@ -70,13 +70,6 @@ export function fingerprint(finding) {
70
70
  ];
71
71
  return createHash("sha256").update(parts.join("|")).digest("hex").slice(0, 16);
72
72
  }
73
- export function isGateFailing(finding, strict) {
74
- return (finding.severity === "blocker" || (strict && finding.severity === "major"));
75
- }
76
- /** Blockers and majors are what keep the loop running; minors never do. */
77
- export function haltsConvergence(finding) {
78
- return finding.severity === "blocker" || finding.severity === "major";
79
- }
80
73
  export function countBySeverity(findings) {
81
74
  const counts = {
82
75
  blocker: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"findings.js","sourceRoot":"","sources":["../src/findings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"findings.js","sourceRoot":"","sources":["../src/findings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC,MAAM,CAAC,MAAM,cAAc,GAAwB;IACjD,SAAS;IACT,OAAO;IACP,OAAO;IACP,UAAU;CACF,CAAC;AAEX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,UAAU;IACV,UAAU;IACV,cAAc;IACd,YAAY;IACZ,aAAa;IACb,oBAAoB;IACpB,cAAc;IACd,qBAAqB;IACrB,YAAY;IACZ,iBAAiB;CACT,CAAC;AA8CX,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,OAAO,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,0BAA0B,GAAG,kCAAkC,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO;SACX,WAAW,EAAE;SACb,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;SACxB,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,MAAM,KAAK,GAAG;QACZ,OAAO,CAAC,QAAQ;QAChB,OAAO,CAAC,YAAY,IAAI,EAAE;QAC1B,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC;KAClC,CAAC;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,QAA4B;IAE5B,MAAM,MAAM,GAA6B;QACvC,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAA4B;IACzD,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC1E,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,MAAM,EAAE,GAAG,CAChB,IAAY,EACZ,SAAiB,EACjB,OAAgB,EACN,EAAE,CAAC,CAAC;IACd,IAAI,EAAE,UAAU;IAChB,IAAI;IACJ,SAAS;IACT,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;CAC9C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,MAAe,EAAY,EAAE,CAAC,CAAC;IACpE,IAAI,EAAE,SAAS;IACf,KAAK;IACL,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,MAAiC,EACjC,KAAa,EACH,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./agent-runner.js";
3
3
  export * from "./agent-summary.js";
4
4
  export * from "./graph.js";
5
5
  export * from "./findings.js";
6
+ export * from "./review-pass.js";
6
7
  export * from "./project-manifest.js";
7
8
  export * from "./program-memory.js";
8
9
  export * from "./worktree-guard.js";
@@ -10,7 +11,9 @@ export * from "./detect-package-manager.js";
10
11
  export * from "./decision.js";
11
12
  export * from "./decision-ledger.js";
12
13
  export * from "./manifest.js";
14
+ export * from "./author.js";
13
15
  export * from "./run-program.js";
16
+ export * from "./decide.js";
14
17
  export * from "./init-project.js";
15
18
  export * from "./install-skills.js";
16
19
  export * from "./install-prefs.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export * from "./agent-runner.js";
3
3
  export * from "./agent-summary.js";
4
4
  export * from "./graph.js";
5
5
  export * from "./findings.js";
6
+ export * from "./review-pass.js";
6
7
  export * from "./project-manifest.js";
7
8
  export * from "./program-memory.js";
8
9
  export * from "./worktree-guard.js";
@@ -10,7 +11,9 @@ export * from "./detect-package-manager.js";
10
11
  export * from "./decision.js";
11
12
  export * from "./decision-ledger.js";
12
13
  export * from "./manifest.js";
14
+ export * from "./author.js";
13
15
  export * from "./run-program.js";
16
+ export * from "./decide.js";
14
17
  export * from "./init-project.js";
15
18
  export * from "./install-skills.js";
16
19
  export * from "./install-prefs.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
@@ -18,6 +18,7 @@ declare const workstreamSchema: z.ZodObject<{
18
18
  failed: "failed";
19
19
  parked: "parked";
20
20
  }>>;
21
+ commit: z.ZodOptional<z.ZodString>;
21
22
  size: z.ZodOptional<z.ZodString>;
22
23
  scope: z.ZodOptional<z.ZodObject<{
23
24
  summary: z.ZodString;
@@ -56,6 +57,7 @@ declare const manifestSchema: z.ZodObject<{
56
57
  failed: "failed";
57
58
  parked: "parked";
58
59
  }>>;
60
+ commit: z.ZodOptional<z.ZodString>;
59
61
  size: z.ZodOptional<z.ZodString>;
60
62
  scope: z.ZodOptional<z.ZodObject<{
61
63
  summary: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,yEAMtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAQpE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;iBASpB,CAAC;AAEH,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAyC1B;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAMf"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,yEAMtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAQpE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;iBAWpB,CAAC;AAEH,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAyC1B;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAMf"}
package/dist/manifest.js CHANGED
@@ -24,6 +24,8 @@ const workstreamSchema = z.object({
24
24
  name: z.string().min(1),
25
25
  taskFile: z.string().min(1),
26
26
  status: z.enum(WORKSTREAM_STATUSES).default("not_started"),
27
+ /** Sha of this workstream's own `nightshift(...)` commit, once complete. */
28
+ commit: z.string().optional(),
27
29
  size: z.string().optional(),
28
30
  scope: scopeSchema.optional(),
29
31
  dependencies: z.array(z.string()).default([]),
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,aAAa;IACb,aAAa;IACb,UAAU;IACV,QAAQ;IACR,QAAQ;CACA,CAAC;AAIX,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC1D,4EAA4E;IAC5E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC7B,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,OAAO,EAAE,CAAC;SACP,MAAM,CAAC;QACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC5D,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC3C,CAAC;SACD,KAAK,EAAE;IACV,eAAe,EAAE,CAAC;SACf,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAC5E;SACA,OAAO,CAAC,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAChE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC5C,CAAC;KACD,KAAK,EAAE,CAAC;AAKX,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB;IAC1D,OAAO,IAAI,CACT,OAAO,CAAC,IAAI,CAAC,EACb,MAAM,EACN,UAAU,EACV,GAAG,SAAS,gBAAgB,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,SAAiB;IAEjB,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,8CAA8C,CACrE,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uBAAwB,KAAe,CAAC,OAAO,EAAE,EAAE;YACxE,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;aAC/B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;aACvE,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gBAAgB,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,KAAK,MAAM,UAAU,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC9C,KAAK,MAAM,UAAU,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,KAAK,UAAU,CAAC,EAAE,mCAAmC,UAAU,GAAG,CAC1E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,SAAiB,EACjB,QAAyB;IAEzB,MAAM,SAAS,CACb,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,EAC7B,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACxC,MAAM,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type Finding, type Severity } from "./findings.js";
2
+ import type { LedgerEvent } from "./decision-ledger.js";
3
+ export interface ParsedFindings {
4
+ findings: Finding[];
5
+ /** Malformed entries/blocks, described. Never fatal — reported to the run report. */
6
+ errors: string[];
7
+ }
8
+ /** Every fenced ```findings block in an agent's output, in order. */
9
+ export declare function extractFindings(output: string): ParsedFindings;
10
+ /** The ```findings block-format instructions, composed into every reviewer brief. */
11
+ export declare function findingsContract(): string;
12
+ export type FindingDestination = "decision-oneway" | "decision" | "report";
13
+ /**
14
+ * blocker -> "decision-oneway" (a decision recorded reversible:false — a one-way door)
15
+ * major -> "decision" (an ordinary reversible, risk-accepted decision)
16
+ * minor -> "report" (the run report only)
17
+ * advisory -> "report"
18
+ */
19
+ export declare function findingDestination(severity: Severity): FindingDestination;
20
+ export declare const REVIEW_ROUND_CAP = 2;
21
+ export type StopReason = "converged" | "cap-reached" | "reviewer-error" | "no-reviewer";
22
+ export interface ReviewRoundResult {
23
+ findings: Finding[];
24
+ errors: string[];
25
+ ran: boolean;
26
+ }
27
+ export interface ReviewPassOutcome {
28
+ ran: boolean;
29
+ roundsRun: number;
30
+ stopReason: StopReason;
31
+ open: Finding[];
32
+ resolved: Finding[];
33
+ errors: string[];
34
+ writerNotes: string[];
35
+ severityCounts: Record<Severity, number>;
36
+ }
37
+ export interface RunReviewPassOptions {
38
+ cap?: number;
39
+ /** Invoke the reviewer for round `n`; parse and return its findings. Stage-owned. */
40
+ review: (round: number, priorOpen: Finding[]) => Promise<ReviewRoundResult>;
41
+ /** Re-brief the writer with this round's findings; return its prose reply. Stage-owned. */
42
+ respond: (round: number, findings: Finding[]) => Promise<{
43
+ note?: string;
44
+ }>;
45
+ }
46
+ /** The pass a stage records when no reviewerAgent is configured (SC-08). */
47
+ export declare function reviewerAbsentOutcome(): ReviewPassOutcome;
48
+ export declare function runReviewPass(options: RunReviewPassOptions): Promise<ReviewPassOutcome>;
49
+ export interface FindingsToLedgerOptions {
50
+ workstreamId: string;
51
+ findings: readonly Finding[];
52
+ baseCommit?: string;
53
+ now: () => Date;
54
+ }
55
+ /** Blocker/major findings -> decision-recorded events; minor/advisory dropped (report-only). */
56
+ export declare function findingsToLedgerEvents(options: FindingsToLedgerOptions): LedgerEvent[];
57
+ /**
58
+ * A human-facing summary of one completed (or absent) pass, for the run
59
+ * report. `label` is the pass name the stage supplies ("Spec critique",
60
+ * "Test critique"). Returns markdown lines; the caller splices them under
61
+ * its own section heading.
62
+ */
63
+ export declare function renderPassReport(label: string, outcome: ReviewPassOutcome): string[];
64
+ //# sourceMappingURL=review-pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-pass.d.ts","sourceRoot":"","sources":["../src/review-pass.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA0CxD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,qFAAqF;IACrF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAoC9D;AAgFD,qFAAqF;AACrF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,kBAAkB,CAUzE;AAED,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,aAAa,CAAC;AAElB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,2FAA2F;IAC3F,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7E;AAMD,4EAA4E;AAC5E,wBAAgB,qBAAqB,IAAI,iBAAiB,CAWzD;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CA+E5B;AA4BD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAcD,gGAAgG;AAChG,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,WAAW,EAAE,CAuCf;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GACzB,MAAM,EAAE,CAmDV"}
@@ -0,0 +1,370 @@
1
+ import { z } from "zod";
2
+ import { countBySeverity, fingerprint, FINDING_CATEGORIES, SEVERITY_ORDER, } from "./findings.js";
3
+ import { decisionFingerprint } from "./decision.js";
4
+ /**
5
+ * The shared foundation both review passes (spec critique, test critique)
6
+ * stand on: the ```findings block contract and parser, severity routing,
7
+ * bounded-round bookkeeping, ledger conversion for residual findings, and
8
+ * the run-report renderer. Neither pass is wired here — see WS-02 and
9
+ * WS-03. Everything in this module fails open: no path throws on reviewer
10
+ * misbehavior, malformed input, or a missing reviewer.
11
+ */
12
+ const evidenceSchema = z.discriminatedUnion("kind", [
13
+ z.object({
14
+ kind: z.literal("location"),
15
+ file: z.string().min(1),
16
+ startLine: z.number(),
17
+ endLine: z.number().optional(),
18
+ excerpt: z.string().optional(),
19
+ }),
20
+ z.object({
21
+ kind: z.literal("concern"),
22
+ named: z.string().min(1),
23
+ detail: z.string().optional(),
24
+ }),
25
+ z.object({
26
+ kind: z.literal("measurement"),
27
+ metric: z.enum(["lineCount", "fileCount"]),
28
+ value: z.number(),
29
+ }),
30
+ ]);
31
+ const findingSchema = z.object({
32
+ severity: z.enum(SEVERITY_ORDER),
33
+ category: z.enum(FINDING_CATEGORIES),
34
+ code: z.string().optional(),
35
+ subject: z.string().min(1),
36
+ message: z.string().min(1),
37
+ evidence: z.array(evidenceSchema),
38
+ workstreamId: z.string().optional(),
39
+ file: z.string().optional(),
40
+ });
41
+ const BLOCK_PATTERN = /```findings[^\S\r\n]*\r?\n([\s\S]*?)```/gu;
42
+ /** Every fenced ```findings block in an agent's output, in order. */
43
+ export function extractFindings(output) {
44
+ const parsed = { findings: [], errors: [] };
45
+ for (const match of output.matchAll(BLOCK_PATTERN)) {
46
+ const body = match[1]?.trim();
47
+ if (body === undefined || body === "")
48
+ continue;
49
+ let json;
50
+ try {
51
+ json = JSON.parse(body);
52
+ }
53
+ catch (error) {
54
+ parsed.errors.push(`findings block is not valid JSON: ${error.message}`);
55
+ continue;
56
+ }
57
+ if (!Array.isArray(json)) {
58
+ parsed.errors.push("findings block is not a JSON array");
59
+ continue;
60
+ }
61
+ json.forEach((element, index) => {
62
+ const result = findingSchema.safeParse(element);
63
+ if (!result.success) {
64
+ const issues = result.error.issues
65
+ .map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`)
66
+ .join("; ");
67
+ parsed.errors.push(`findings[${index}] has the wrong shape: ${issues}`);
68
+ return;
69
+ }
70
+ parsed.findings.push(toFinding(result.data));
71
+ });
72
+ }
73
+ return parsed;
74
+ }
75
+ /**
76
+ * `exactOptionalPropertyTypes` distinguishes an absent key from a key
77
+ * explicitly set to `undefined`; Zod's `.optional()` output allows the
78
+ * latter, `Finding`'s optional fields do not. Rebuild each finding (and its
79
+ * evidence) with the key omitted rather than set to `undefined`.
80
+ */
81
+ function toFinding(parsed) {
82
+ return {
83
+ severity: parsed.severity,
84
+ category: parsed.category,
85
+ ...(parsed.code === undefined ? {} : { code: parsed.code }),
86
+ subject: parsed.subject,
87
+ message: parsed.message,
88
+ evidence: parsed.evidence.map(toEvidence),
89
+ ...(parsed.workstreamId === undefined ? {} : { workstreamId: parsed.workstreamId }),
90
+ ...(parsed.file === undefined ? {} : { file: parsed.file }),
91
+ };
92
+ }
93
+ function toEvidence(parsed) {
94
+ if (parsed.kind === "location") {
95
+ return {
96
+ kind: "location",
97
+ file: parsed.file,
98
+ startLine: parsed.startLine,
99
+ ...(parsed.endLine === undefined ? {} : { endLine: parsed.endLine }),
100
+ ...(parsed.excerpt === undefined ? {} : { excerpt: parsed.excerpt }),
101
+ };
102
+ }
103
+ if (parsed.kind === "concern") {
104
+ return {
105
+ kind: "concern",
106
+ named: parsed.named,
107
+ ...(parsed.detail === undefined ? {} : { detail: parsed.detail }),
108
+ };
109
+ }
110
+ return { kind: "measurement", metric: parsed.metric, value: parsed.value };
111
+ }
112
+ const CONTRACT = `
113
+ ## Findings (how to report review results)
114
+
115
+ End your reply with one fenced block containing a JSON array of findings —
116
+ plural, because a review typically raises more than one:
117
+
118
+ \`\`\`findings
119
+ [
120
+ {
121
+ "severity": "major",
122
+ "category": "test-quality",
123
+ "subject": "SC-06 token refresh",
124
+ "message": "No test exercises the refresh path; a stub that returns a fixed token passes the suite.",
125
+ "evidence": [{ "kind": "location", "file": "test/auth.test.ts", "startLine": 40 }],
126
+ "workstreamId": "WS-03"
127
+ }
128
+ ]
129
+ \`\`\`
130
+
131
+ Fields:
132
+ - \`severity\`: one of ${SEVERITY_ORDER.join(", ")}. Blocker and major findings
133
+ are routed to the decision ledger for the human to see; minor and advisory
134
+ findings are reported only.
135
+ - \`category\`: one of ${FINDING_CATEGORIES.join(", ")}.
136
+ - \`subject\`: a short, stable noun phrase naming what the finding is about.
137
+ Reuse the same subject across rounds if you are re-raising the same issue —
138
+ identity is built from this field, not from your wording.
139
+ - \`message\`: the finding itself, in prose.
140
+ - \`evidence\`: an array of \`{ kind: "location", file, startLine, endLine?,
141
+ excerpt? }\`, \`{ kind: "concern", named, detail? }\`, or \`{ kind:
142
+ "measurement", metric: "lineCount" | "fileCount", value }\`.
143
+ - \`workstreamId\` and \`file\`: optional context.
144
+
145
+ Raise nothing and the block may be omitted entirely — an empty review is not
146
+ an error.
147
+ `.trim();
148
+ /** The ```findings block-format instructions, composed into every reviewer brief. */
149
+ export function findingsContract() {
150
+ return CONTRACT;
151
+ }
152
+ /**
153
+ * blocker -> "decision-oneway" (a decision recorded reversible:false — a one-way door)
154
+ * major -> "decision" (an ordinary reversible, risk-accepted decision)
155
+ * minor -> "report" (the run report only)
156
+ * advisory -> "report"
157
+ */
158
+ export function findingDestination(severity) {
159
+ switch (severity) {
160
+ case "blocker":
161
+ return "decision-oneway";
162
+ case "major":
163
+ return "decision";
164
+ case "minor":
165
+ case "advisory":
166
+ return "report";
167
+ }
168
+ }
169
+ export const REVIEW_ROUND_CAP = 2; // charter says two or three; a constant, never a config key
170
+ function emptySeverityCounts() {
171
+ return countBySeverity([]);
172
+ }
173
+ /** The pass a stage records when no reviewerAgent is configured (SC-08). */
174
+ export function reviewerAbsentOutcome() {
175
+ return {
176
+ ran: false,
177
+ roundsRun: 0,
178
+ stopReason: "no-reviewer",
179
+ open: [],
180
+ resolved: [],
181
+ errors: [],
182
+ writerNotes: [],
183
+ severityCounts: emptySeverityCounts(),
184
+ };
185
+ }
186
+ export async function runReviewPass(options) {
187
+ const cap = options.cap ?? REVIEW_ROUND_CAP;
188
+ const seen = new Set();
189
+ const latest = new Map();
190
+ const errors = [];
191
+ const writerNotes = [];
192
+ let priorOpen = [];
193
+ let round = 1;
194
+ for (;;) {
195
+ const result = await options.review(round, priorOpen);
196
+ errors.push(...result.errors);
197
+ if (!result.ran) {
198
+ if (round === 1) {
199
+ return {
200
+ ran: false,
201
+ roundsRun: 0,
202
+ stopReason: "reviewer-error",
203
+ open: [],
204
+ resolved: [],
205
+ errors,
206
+ writerNotes,
207
+ severityCounts: emptySeverityCounts(),
208
+ };
209
+ }
210
+ return finish({
211
+ ran: true,
212
+ roundsRun: round - 1,
213
+ stopReason: "reviewer-error",
214
+ open: priorOpen,
215
+ errors,
216
+ writerNotes,
217
+ seen,
218
+ latest,
219
+ });
220
+ }
221
+ for (const finding of result.findings) {
222
+ latest.set(fingerprint(finding), finding);
223
+ }
224
+ const roundFingerprints = new Set(result.findings.map((f) => fingerprint(f)));
225
+ const newFingerprints = [...roundFingerprints].filter((fp) => !seen.has(fp));
226
+ if (newFingerprints.length === 0) {
227
+ return finish({
228
+ ran: true,
229
+ roundsRun: round,
230
+ stopReason: "converged",
231
+ open: result.findings,
232
+ errors,
233
+ writerNotes,
234
+ seen,
235
+ latest,
236
+ });
237
+ }
238
+ if (round === cap) {
239
+ return finish({
240
+ ran: true,
241
+ roundsRun: round,
242
+ stopReason: "cap-reached",
243
+ open: result.findings,
244
+ errors,
245
+ writerNotes,
246
+ seen,
247
+ latest,
248
+ });
249
+ }
250
+ for (const fp of newFingerprints)
251
+ seen.add(fp);
252
+ const response = await options.respond(round, result.findings);
253
+ if (response.note !== undefined)
254
+ writerNotes.push(response.note);
255
+ priorOpen = result.findings;
256
+ round += 1;
257
+ }
258
+ }
259
+ function finish(args) {
260
+ const openFingerprints = new Set(args.open.map((f) => fingerprint(f)));
261
+ const resolved = [...args.latest.values()].filter((finding) => !openFingerprints.has(fingerprint(finding)));
262
+ return {
263
+ ran: args.ran,
264
+ roundsRun: args.roundsRun,
265
+ stopReason: args.stopReason,
266
+ open: args.open,
267
+ resolved,
268
+ errors: args.errors,
269
+ writerNotes: args.writerNotes,
270
+ severityCounts: countBySeverity([...args.latest.values()]),
271
+ };
272
+ }
273
+ function evidenceSummary(finding) {
274
+ const first = finding.evidence[0];
275
+ if (!first)
276
+ return "";
277
+ if (first.kind === "location") {
278
+ return ` (${first.file}:${first.startLine})`;
279
+ }
280
+ if (first.kind === "concern") {
281
+ return ` (${first.named})`;
282
+ }
283
+ return ` (${first.metric}: ${first.value})`;
284
+ }
285
+ /** Blocker/major findings -> decision-recorded events; minor/advisory dropped (report-only). */
286
+ export function findingsToLedgerEvents(options) {
287
+ const events = [];
288
+ for (const finding of options.findings) {
289
+ const destination = findingDestination(finding.severity);
290
+ if (destination === "report")
291
+ continue;
292
+ const decision = {
293
+ title: `Reviewer finding: ${finding.subject}`,
294
+ context: `${finding.category} — ${finding.message}${evidenceSummary(finding)}`,
295
+ options: [
296
+ {
297
+ label: "proceed",
298
+ description: "Accept the risk and proceed; the finding is recorded here for review.",
299
+ },
300
+ {
301
+ label: "fix-now",
302
+ description: "Roll back to the anchor commit and address the finding before continuing.",
303
+ },
304
+ ],
305
+ chosen: "proceed",
306
+ rationale: `An independent reviewer raised this ${finding.severity} finding and the pass proceeded at its bound; routed here for ratify-or-escalate.`,
307
+ reversible: destination !== "decision-oneway",
308
+ };
309
+ events.push({
310
+ kind: "decision-recorded",
311
+ at: options.now().toISOString(),
312
+ id: decisionFingerprint(options.workstreamId, decision),
313
+ workstream: options.workstreamId,
314
+ decision,
315
+ ...(options.baseCommit === undefined ? {} : { baseCommit: options.baseCommit }),
316
+ decidedBy: "implementer",
317
+ });
318
+ }
319
+ return events;
320
+ }
321
+ function describeSubjects(findings) {
322
+ return findings.map((finding) => finding.subject).join(", ");
323
+ }
324
+ /**
325
+ * A human-facing summary of one completed (or absent) pass, for the run
326
+ * report. `label` is the pass name the stage supplies ("Spec critique",
327
+ * "Test critique"). Returns markdown lines; the caller splices them under
328
+ * its own section heading.
329
+ */
330
+ export function renderPassReport(label, outcome) {
331
+ if (outcome.stopReason === "no-reviewer") {
332
+ return [
333
+ `**${label}:** disabled — no reviewer is configured, and the pass was`,
334
+ "not substituted with the implementer or skipped silently.",
335
+ ];
336
+ }
337
+ if (outcome.stopReason === "reviewer-error" && !outcome.ran) {
338
+ return [
339
+ `**${label}:** the reviewer produced no readable findings, so the pass`,
340
+ "did not run; the run proceeded without it.",
341
+ ];
342
+ }
343
+ const lines = [];
344
+ const roundWord = outcome.roundsRun === 1 ? "round" : "rounds";
345
+ if (outcome.stopReason === "converged") {
346
+ lines.push(`**${label}:** converged after ${outcome.roundsRun} ${roundWord}.`);
347
+ }
348
+ else if (outcome.stopReason === "cap-reached") {
349
+ lines.push(`**${label}:** ran ${outcome.roundsRun} ${roundWord} and hit the round cap; the reviewer was still finding new issues.`);
350
+ }
351
+ else {
352
+ lines.push(`**${label}:** ran ${outcome.roundsRun} ${roundWord}; the reviewer did not produce a further readable read, so the last verified round stands.`);
353
+ }
354
+ const counts = outcome.severityCounts;
355
+ lines.push(`Findings raised: ${counts.blocker} blocker, ${counts.major} major, ${counts.minor} minor, ${counts.advisory} advisory.`);
356
+ if (outcome.resolved.length > 0) {
357
+ lines.push(`Fixed: ${describeSubjects(outcome.resolved)}.`);
358
+ }
359
+ if (outcome.open.length > 0) {
360
+ lines.push(`Still open: ${describeSubjects(outcome.open)}.`);
361
+ if (outcome.writerNotes.length > 0) {
362
+ lines.push(`Writer's notes: ${outcome.writerNotes.join(" | ")}`);
363
+ }
364
+ }
365
+ else {
366
+ lines.push("No open findings remain.");
367
+ }
368
+ return lines;
369
+ }
370
+ //# sourceMappingURL=review-pass.js.map