@cat-factory/orchestration 0.208.0 → 0.210.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 (67) hide show
  1. package/dist/container/modules.d.ts.map +1 -1
  2. package/dist/container/modules.js +13 -1
  3. package/dist/container/modules.js.map +1 -1
  4. package/dist/index.d.ts +3 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/modules/board/BoardService.d.ts +36 -7
  9. package/dist/modules/board/BoardService.d.ts.map +1 -1
  10. package/dist/modules/board/BoardService.js +47 -7
  11. package/dist/modules/board/BoardService.js.map +1 -1
  12. package/dist/modules/board/publicBoardReads.d.ts +8 -3
  13. package/dist/modules/board/publicBoardReads.d.ts.map +1 -1
  14. package/dist/modules/board/publicBoardReads.js +7 -2
  15. package/dist/modules/board/publicBoardReads.js.map +1 -1
  16. package/dist/modules/board/riskPolicySelectionGuard.d.ts +34 -0
  17. package/dist/modules/board/riskPolicySelectionGuard.d.ts.map +1 -0
  18. package/dist/modules/board/riskPolicySelectionGuard.js +40 -0
  19. package/dist/modules/board/riskPolicySelectionGuard.js.map +1 -0
  20. package/dist/modules/boardScan/BoardScanService.d.ts.map +1 -1
  21. package/dist/modules/boardScan/BoardScanService.js +7 -13
  22. package/dist/modules/boardScan/BoardScanService.js.map +1 -1
  23. package/dist/modules/debug/debug.logic.d.ts.map +1 -1
  24. package/dist/modules/debug/debug.logic.js +7 -6
  25. package/dist/modules/debug/debug.logic.js.map +1 -1
  26. package/dist/modules/execution/DocInterviewController.d.ts.map +1 -1
  27. package/dist/modules/execution/DocInterviewController.js +14 -0
  28. package/dist/modules/execution/DocInterviewController.js.map +1 -1
  29. package/dist/modules/execution/ExecutionService.d.ts +36 -0
  30. package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
  31. package/dist/modules/execution/ExecutionService.js +44 -4
  32. package/dist/modules/execution/ExecutionService.js.map +1 -1
  33. package/dist/modules/execution/InitiativeInterviewController.d.ts.map +1 -1
  34. package/dist/modules/execution/InitiativeInterviewController.js +27 -0
  35. package/dist/modules/execution/InitiativeInterviewController.js.map +1 -1
  36. package/dist/modules/execution/InterviewGateController.d.ts +66 -1
  37. package/dist/modules/execution/InterviewGateController.d.ts.map +1 -1
  38. package/dist/modules/execution/InterviewGateController.js +11 -6
  39. package/dist/modules/execution/InterviewGateController.js.map +1 -1
  40. package/dist/modules/execution/MergeResolver.d.ts.map +1 -1
  41. package/dist/modules/execution/MergeResolver.js +1 -2
  42. package/dist/modules/execution/MergeResolver.js.map +1 -1
  43. package/dist/modules/execution/PrVerificationReportController.d.ts +61 -2
  44. package/dist/modules/execution/PrVerificationReportController.d.ts.map +1 -1
  45. package/dist/modules/execution/PrVerificationReportController.js +82 -20
  46. package/dist/modules/execution/PrVerificationReportController.js.map +1 -1
  47. package/dist/modules/execution/RunMergePolicy.d.ts +7 -2
  48. package/dist/modules/execution/RunMergePolicy.d.ts.map +1 -1
  49. package/dist/modules/execution/RunMergePolicy.js +13 -26
  50. package/dist/modules/execution/RunMergePolicy.js.map +1 -1
  51. package/dist/modules/execution/followUp.logic.d.ts +19 -0
  52. package/dist/modules/execution/followUp.logic.d.ts.map +1 -1
  53. package/dist/modules/execution/followUp.logic.js +20 -1
  54. package/dist/modules/execution/followUp.logic.js.map +1 -1
  55. package/dist/modules/execution/prReport.logic.d.ts +7 -0
  56. package/dist/modules/execution/prReport.logic.d.ts.map +1 -1
  57. package/dist/modules/execution/prReport.logic.js +21 -5
  58. package/dist/modules/execution/prReport.logic.js.map +1 -1
  59. package/dist/modules/execution/step-park.logic.d.ts +24 -0
  60. package/dist/modules/execution/step-park.logic.d.ts.map +1 -1
  61. package/dist/modules/execution/step-park.logic.js +26 -0
  62. package/dist/modules/execution/step-park.logic.js.map +1 -1
  63. package/dist/modules/merge/riskPolicyResolution.d.ts +28 -0
  64. package/dist/modules/merge/riskPolicyResolution.d.ts.map +1 -0
  65. package/dist/modules/merge/riskPolicyResolution.js +34 -0
  66. package/dist/modules/merge/riskPolicyResolution.js.map +1 -0
  67. package/package.json +12 -12
@@ -1,4 +1,5 @@
1
1
  import type { BlockRepository, Clock, ExecutionInstance, Logger, PrVerificationReportPublisher, ProvisioningLogRepository, ResolveRunRepoContext, TaskRepository, WorkspaceSettingsRepository } from '@cat-factory/kernel';
2
+ import type { PrVerificationReport } from '@cat-factory/contracts';
2
3
  /**
3
4
  * The engine collaborator that keeps a run's **verification report** on its pull request.
4
5
  *
@@ -20,6 +21,11 @@ import type { BlockRepository, Clock, ExecutionInstance, Logger, PrVerificationR
20
21
  * Every failure mode is a silent no-op: no publisher wired (tests, a no-VCS deployment), no
21
22
  * PR yet, an unchanged report, or a transport error. Publishing a report must never fail a
22
23
  * run that otherwise succeeded.
24
+ *
25
+ * The same composition also answers the public read (`GET /api/v1/runs/:runId/report`) through
26
+ * {@link PrVerificationReportController.composeForRun}, which is why there is no second
27
+ * API-shaped projection of these facts: two composers is how a pull request and an API start
28
+ * disagreeing about what a run proved.
23
29
  */
24
30
  export interface PrVerificationReportControllerDeps {
25
31
  blockRepository: BlockRepository;
@@ -58,8 +64,9 @@ export interface PrVerificationReportControllerDeps {
58
64
  appBaseUrl?: string;
59
65
  /**
60
66
  * Optional: this deployment's own externally-reachable BACKEND base URL (`PUBLIC_URL` on Node,
61
- * `WORKER_PUBLIC_URL` on the Worker), used to build direct links to the bytes of the artifacts
62
- * the report lists. Absent ⇒ the rows carry their artifact ids and no link.
67
+ * `WORKER_PUBLIC_URL` on the Worker), used to build every link a MACHINE follows: the bytes of
68
+ * the artifacts the report lists, the run's tool-call trajectory, and the report itself served
69
+ * live. Absent ⇒ those fields are null and the report states the ids alone.
63
70
  *
64
71
  * Deliberately separate from {@link appBaseUrl}: the two are the same origin on a same-origin
65
72
  * deployment and different ones the moment the SPA is served from its own host, and a link built
@@ -106,6 +113,49 @@ export declare class PrVerificationReportController {
106
113
  * silently on every skip/failure path.
107
114
  */
108
115
  publishForRun(workspaceId: string, instance: ExecutionInstance): Promise<void>;
116
+ /**
117
+ * The same report, composed for a READER rather than for the pull request
118
+ * (`GET /api/v1/runs/:runId/report`). Null when the run's block is gone, which is the only way
119
+ * a run has nothing to report on.
120
+ *
121
+ * Three differences from {@link publishForRun}, each deliberate:
122
+ * - **A run with no pull request still gets a report.** The publish path short-circuits on an
123
+ * unresolved target because there is nowhere to write; a reader is asking about the RUN, and
124
+ * a headless job or a run that failed before it pushed is exactly the case a PR-body-scraping
125
+ * consumer could never see. An unresolved target simply leaves `repo`/`provider` null.
126
+ * - **The per-workspace opt-out is not consulted.** `publishPrVerificationReport` says whether
127
+ * this deployment writes onto someone's pull request, which is a statement about a REMOTE
128
+ * surface; it was never a statement about whether the workspace's own evidence may be read
129
+ * back over an authenticated, workspace-scoped key.
130
+ * - **Failures are not swallowed.** Publishing is bookkeeping that must never fail a run; a
131
+ * read that cannot answer must say so rather than hand back a report with holes in it that
132
+ * look like findings.
133
+ *
134
+ * WHAT A CALLER IS BUYING. Composition is not free and this is the one `/api/v1` read that can
135
+ * reach OUTSIDE the deployment: a run whose tester reported pulls the service's `spec/` tree off
136
+ * the run's branch over the VCS API ({@link PrVerificationReportController.serviceSpec}), which
137
+ * is memoised per run but only within one process, so a Worker isolate that has not seen the run
138
+ * pays it again. Everything else is a handful of indexed row reads. That cost is accepted rather
139
+ * than dodged: dropping the spec join on the read path would make the API answer differ from the
140
+ * pull-request body, and one report with two contents is the exact failure serving the report
141
+ * verbatim exists to prevent. It is stated in `backend/docs/public-api.md` so an integration
142
+ * polling every run knows what it is asking for, and left OUT of the app-cache seam on purpose,
143
+ * since the branch it reads keeps moving and the seam is pass-through for mutable state on the
144
+ * Worker anyway: a cache there would add a coherence problem without removing the fetch.
145
+ */
146
+ composeForRun(workspaceId: string, instance: ExecutionInstance): Promise<PrVerificationReport | null>;
147
+ /**
148
+ * Build the report from the run's state plus whatever the publisher resolved about where it
149
+ * lands. Null when the block is gone.
150
+ *
151
+ * The block is read here even though {@link PrVerificationReportPublisher.resolveTarget} has
152
+ * just read it too, and that second point read is deliberate rather than overlooked: threading
153
+ * the row through would mean this controller deciding which pull request is the block's, the one
154
+ * judgement `GitHubPrReportPublisher` re-resolves self-containedly precisely so nothing else
155
+ * forms a second opinion about it. Duplicating that rule to save one indexed read by primary key
156
+ * is a bad trade, and it is two reads, never a per-item one.
157
+ */
158
+ private compose;
109
159
  /** Record the published fingerprint, evicting the oldest entry once the cap is reached. */
110
160
  private remember;
111
161
  /**
@@ -182,6 +232,15 @@ export declare class PrVerificationReportController {
182
232
  * and the same one the app deep link beside it produces.
183
233
  */
184
234
  private artifactUrl;
235
+ /**
236
+ * An absolute link to one of this deployment's own backend endpoints, or null when no public
237
+ * backend URL is configured (in which case the report states the ids and no link, rather than
238
+ * a link to nowhere).
239
+ *
240
+ * `path` is already-encoded and starts with `/`. Built by hand rather than with `URL`, for the
241
+ * reason {@link deepLink} gives: orchestration is runtime-neutral and compiles without the DOM.
242
+ */
243
+ private apiLink;
185
244
  private deepLink;
186
245
  }
187
246
  //# sourceMappingURL=PrVerificationReportController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PrVerificationReportController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/PrVerificationReportController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,KAAK,EACL,iBAAiB,EACjB,MAAM,EAEN,6BAA6B,EAC7B,yBAAyB,EACzB,qBAAqB,EAErB,cAAc,EACd,2BAA2B,EAC5B,MAAM,qBAAqB,CAAA;AAuB5B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,kCAAkC;IACjD,eAAe,EAAE,eAAe,CAAA;IAChC,KAAK,EAAE,KAAK,CAAA;IACZ;;;OAGG;IACH,SAAS,CAAC,EAAE,6BAA6B,CAAA;IACzC,+EAA+E;IAC/E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAA;IACzD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAA;IACnE;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,8BAA8B;IA2B7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IA1BjC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAE1D;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAE9C,YAA6B,IAAI,EAAE,kCAAkC,EAAI;IAEzE;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDnF;IAED,2FAA2F;IAC3F,OAAO,CAAC,QAAQ;IAUhB;;;;OAIG;YACW,iBAAiB;IAO/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;YACW,WAAW;IA8BzB,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAE9D,OAAO,CAAC,YAAY;YAUN,YAAY;IAY1B;;;;;;;;;;;;;;OAcG;YACW,kBAAkB;IAiChC;;;;;;;;;OASG;IACH;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;CAmBjB"}
1
+ {"version":3,"file":"PrVerificationReportController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/PrVerificationReportController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,KAAK,EACL,iBAAiB,EACjB,MAAM,EAGN,6BAA6B,EAC7B,yBAAyB,EACzB,qBAAqB,EAErB,cAAc,EACd,2BAA2B,EAC5B,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAoBlE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,kCAAkC;IACjD,eAAe,EAAE,eAAe,CAAA;IAChC,KAAK,EAAE,KAAK,CAAA;IACZ;;;OAGG;IACH,SAAS,CAAC,EAAE,6BAA6B,CAAA;IACzC,+EAA+E;IAC/E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAA;IACzD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAA;IACnE;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,8BAA8B;IA2B7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IA1BjC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAE1D;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAE9C,YAA6B,IAAI,EAAE,kCAAkC,EAAI;IAEzE;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCnF;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAGtC;IAED;;;;;;;;;;OAUG;YACW,OAAO;IA2BrB,2FAA2F;IAC3F,OAAO,CAAC,QAAQ;IAUhB;;;;OAIG;YACW,iBAAiB;IAO/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;YACW,WAAW;IA8BzB,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAE9D,OAAO,CAAC,YAAY;YAUN,YAAY;IAY1B;;;;;;;;;;;;;;OAcG;YACW,kBAAkB;IAiChC;;;;;;;;;OASG;IACH;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;IAMnB;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,QAAQ;CAmBjB"}
@@ -64,30 +64,17 @@ export class PrVerificationReportController {
64
64
  const target = await publisher.resolveTarget(workspaceId, instance.blockId);
65
65
  if (!target)
66
66
  return;
67
- const block = await this.deps.blockRepository.get(workspaceId, instance.blockId);
67
+ const report = await this.compose(workspaceId, instance, target);
68
68
  // Only a task carries an implementation PR; a frame/module run has nothing to report on.
69
- if (!block)
69
+ if (!report)
70
70
  return;
71
- const section = renderPrVerificationReport(composePrVerificationReport(instance, {
72
- block,
73
- issues: await this.linkedIssues(workspaceId, instance.blockId),
74
- repo: target.repo,
75
- provider: target.provider,
76
- runUrl: this.deepLink(workspaceId, instance, 'observability'),
77
- spec: await this.serviceSpec(workspaceId, instance, block.pullRequest?.branch),
78
- environments: {
79
- provisioning: await this.provisioningEvents(workspaceId, instance),
80
- evidenceUrl: this.deepLink(workspaceId, instance, 'test-evidence'),
81
- artifactUrl: (artifactId) => this.artifactUrl(workspaceId, artifactId),
82
- },
83
- now: this.deps.clock.now(),
84
- }));
71
+ const section = renderPrVerificationReport(report);
85
72
  // `generatedAt` changes on every compose, so compare the section with it masked out —
86
73
  // otherwise the cache would never hit and every step would edit the PR.
87
74
  const fingerprint = section.replaceAll(/"generatedAt": \d+/g, '"generatedAt": 0');
88
75
  if (this.lastPublished.get(instance.id) === fingerprint)
89
76
  return;
90
- await publisher.publish(workspaceId, block.id, section);
77
+ await publisher.publish(workspaceId, instance.blockId, section);
91
78
  this.remember(instance.id, fingerprint);
92
79
  }
93
80
  catch (error) {
@@ -101,6 +88,72 @@ export class PrVerificationReportController {
101
88
  });
102
89
  }
103
90
  }
91
+ /**
92
+ * The same report, composed for a READER rather than for the pull request
93
+ * (`GET /api/v1/runs/:runId/report`). Null when the run's block is gone, which is the only way
94
+ * a run has nothing to report on.
95
+ *
96
+ * Three differences from {@link publishForRun}, each deliberate:
97
+ * - **A run with no pull request still gets a report.** The publish path short-circuits on an
98
+ * unresolved target because there is nowhere to write; a reader is asking about the RUN, and
99
+ * a headless job or a run that failed before it pushed is exactly the case a PR-body-scraping
100
+ * consumer could never see. An unresolved target simply leaves `repo`/`provider` null.
101
+ * - **The per-workspace opt-out is not consulted.** `publishPrVerificationReport` says whether
102
+ * this deployment writes onto someone's pull request, which is a statement about a REMOTE
103
+ * surface; it was never a statement about whether the workspace's own evidence may be read
104
+ * back over an authenticated, workspace-scoped key.
105
+ * - **Failures are not swallowed.** Publishing is bookkeeping that must never fail a run; a
106
+ * read that cannot answer must say so rather than hand back a report with holes in it that
107
+ * look like findings.
108
+ *
109
+ * WHAT A CALLER IS BUYING. Composition is not free and this is the one `/api/v1` read that can
110
+ * reach OUTSIDE the deployment: a run whose tester reported pulls the service's `spec/` tree off
111
+ * the run's branch over the VCS API ({@link PrVerificationReportController.serviceSpec}), which
112
+ * is memoised per run but only within one process, so a Worker isolate that has not seen the run
113
+ * pays it again. Everything else is a handful of indexed row reads. That cost is accepted rather
114
+ * than dodged: dropping the spec join on the read path would make the API answer differ from the
115
+ * pull-request body, and one report with two contents is the exact failure serving the report
116
+ * verbatim exists to prevent. It is stated in `backend/docs/public-api.md` so an integration
117
+ * polling every run knows what it is asking for, and left OUT of the app-cache seam on purpose,
118
+ * since the branch it reads keeps moving and the seam is pass-through for mutable state on the
119
+ * Worker anyway: a cache there would add a coherence problem without removing the fetch.
120
+ */
121
+ async composeForRun(workspaceId, instance) {
122
+ const target = (await this.deps.publisher?.resolveTarget(workspaceId, instance.blockId)) ?? null;
123
+ return this.compose(workspaceId, instance, target);
124
+ }
125
+ /**
126
+ * Build the report from the run's state plus whatever the publisher resolved about where it
127
+ * lands. Null when the block is gone.
128
+ *
129
+ * The block is read here even though {@link PrVerificationReportPublisher.resolveTarget} has
130
+ * just read it too, and that second point read is deliberate rather than overlooked: threading
131
+ * the row through would mean this controller deciding which pull request is the block's, the one
132
+ * judgement `GitHubPrReportPublisher` re-resolves self-containedly precisely so nothing else
133
+ * forms a second opinion about it. Duplicating that rule to save one indexed read by primary key
134
+ * is a bad trade, and it is two reads, never a per-item one.
135
+ */
136
+ async compose(workspaceId, instance, target) {
137
+ const block = await this.deps.blockRepository.get(workspaceId, instance.blockId);
138
+ if (!block)
139
+ return null;
140
+ return composePrVerificationReport(instance, {
141
+ block,
142
+ issues: await this.linkedIssues(workspaceId, instance.blockId),
143
+ repo: target?.repo ?? null,
144
+ provider: target?.provider ?? null,
145
+ runUrl: this.deepLink(workspaceId, instance, 'observability'),
146
+ trajectoryUrl: this.apiLink(`/api/v1/debug/runs/${encodeURIComponent(instance.id)}/tool-calls?order=trajectory`),
147
+ reportUrl: this.apiLink(`/api/v1/runs/${encodeURIComponent(instance.id)}/report`),
148
+ spec: await this.serviceSpec(workspaceId, instance, block.pullRequest?.branch),
149
+ environments: {
150
+ provisioning: await this.provisioningEvents(workspaceId, instance),
151
+ evidenceUrl: this.deepLink(workspaceId, instance, 'test-evidence'),
152
+ artifactUrl: (artifactId) => this.artifactUrl(workspaceId, artifactId),
153
+ },
154
+ now: this.deps.clock.now(),
155
+ });
156
+ }
104
157
  /** Record the published fingerprint, evicting the oldest entry once the cap is reached. */
105
158
  remember(executionId, fingerprint) {
106
159
  this.lastPublished.delete(executionId);
@@ -270,10 +323,19 @@ export class PrVerificationReportController {
270
323
  * and the same one the app deep link beside it produces.
271
324
  */
272
325
  artifactUrl(workspaceId, artifactId) {
326
+ return this.apiLink(`/workspaces/${encodeURIComponent(workspaceId)}/artifacts/${encodeURIComponent(artifactId)}/blob`);
327
+ }
328
+ /**
329
+ * An absolute link to one of this deployment's own backend endpoints, or null when no public
330
+ * backend URL is configured (in which case the report states the ids and no link, rather than
331
+ * a link to nowhere).
332
+ *
333
+ * `path` is already-encoded and starts with `/`. Built by hand rather than with `URL`, for the
334
+ * reason {@link deepLink} gives: orchestration is runtime-neutral and compiles without the DOM.
335
+ */
336
+ apiLink(path) {
273
337
  const base = this.deps.apiBaseUrl?.trim();
274
- if (!base)
275
- return null;
276
- return `${base.replace(/\/$/, '')}/workspaces/${encodeURIComponent(workspaceId)}/artifacts/${encodeURIComponent(artifactId)}/blob`;
338
+ return base ? `${base.replace(/\/$/, '')}${path}` : null;
277
339
  }
278
340
  deepLink(workspaceId, instance, view) {
279
341
  const base = this.deps.appBaseUrl?.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"PrVerificationReportController.js","sourceRoot":"","sources":["../../../src/modules/execution/PrVerificationReportController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PrVerificationReportController.js","sourceRoot":"","sources":["../../../src/modules/execution/PrVerificationReportController.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import type { ResolvedRunRiskPolicy } from './policy-types.js';
5
5
  export interface RunMergePolicyDeps {
6
6
  /**
7
7
  * Optional: resolves a task's merge threshold preset (auto-merge ceilings, the per-class
8
- * rules, and the CI-fixer attempt budget). Absent → the built-in {@link DEFAULT_RISK_POLICY}.
8
+ * rules, and the CI-fixer attempt budget). Absent → the built-in `DEFAULT_RISK_POLICY`.
9
9
  */
10
10
  riskPolicyRepository?: RiskPolicyRepository;
11
11
  /**
@@ -39,8 +39,13 @@ export declare class RunMergePolicy {
39
39
  constructor(deps: RunMergePolicyDeps);
40
40
  /**
41
41
  * Resolve the merge threshold preset that governs a task: its explicitly-picked preset, else
42
- * the workspace default, else the built-in {@link DEFAULT_RISK_POLICY}. Returns the thresholds
42
+ * the workspace default, else the built-in `DEFAULT_RISK_POLICY`. Returns the thresholds
43
43
  * the engine compares against, the per-class rules, and the CI attempt budget.
44
+ *
45
+ * Reads through the `riskPolicy` cache slice when wired: the row is slow-moving admin config
46
+ * re-read on every gate evaluation. The resolution itself is shared with the board's preset
47
+ * SELECTION guard (`resolveRiskPolicy`), so the policy a swap is judged against is the same one
48
+ * this will apply when the run settles.
44
49
  */
45
50
  resolve(workspaceId: string, block: Block): Promise<ResolvedRunRiskPolicy>;
46
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"RunMergePolicy.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/RunMergePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,gBAAgB,EAChB,YAAY,EAEZ,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAE9D,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAC3C;;;;OAIG;IACH,eAAe,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;IACxD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,uBAAuB,CAAA;CAC3C;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,kBAAkB,EAAI;IAEzD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAyB/E;IAED;;;;OAIG;IACG,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,GACjC,OAAO,CAAC,IAAI,CAAC,CAUf;IAED;;;;OAIG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;CACF"}
1
+ {"version":3,"file":"RunMergePolicy.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/RunMergePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAE9D,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAC3C;;;;OAIG;IACH,eAAe,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;IACxD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,uBAAuB,CAAA;CAC3C;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,kBAAkB,EAAI;IAEzD;;;;;;;;;OASG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAO/E;IAED;;;;OAIG;IACG,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,GACjC,OAAO,CAAC,IAAI,CAAC,CAUf;IAED;;;;OAIG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;CACF"}
@@ -1,4 +1,4 @@
1
- import { DEFAULT_RISK_POLICY } from '@cat-factory/kernel';
1
+ import { cachedRiskPolicyRead, resolveRiskPolicy } from '../merge/riskPolicyResolution.js';
2
2
  /**
3
3
  * The task's effective MERGE POLICY plus the EVIDENCE behind it, extracted out of
4
4
  * `ExecutionService` as a cohesive collaborator (the `RunDispatcher` controller extractions are
@@ -20,34 +20,21 @@ export class RunMergePolicy {
20
20
  }
21
21
  /**
22
22
  * Resolve the merge threshold preset that governs a task: its explicitly-picked preset, else
23
- * the workspace default, else the built-in {@link DEFAULT_RISK_POLICY}. Returns the thresholds
23
+ * the workspace default, else the built-in `DEFAULT_RISK_POLICY`. Returns the thresholds
24
24
  * the engine compares against, the per-class rules, and the CI attempt budget.
25
+ *
26
+ * Reads through the `riskPolicy` cache slice when wired: the row is slow-moving admin config
27
+ * re-read on every gate evaluation. The resolution itself is shared with the board's preset
28
+ * SELECTION guard (`resolveRiskPolicy`), so the policy a swap is judged against is the same one
29
+ * this will apply when the run settles.
25
30
  */
26
31
  async resolve(workspaceId, block) {
27
- const repo = this.deps.riskPolicyRepository;
28
- if (repo) {
29
- // Read each preset through the cache slice when wired: the row is slow-moving admin config
30
- // re-read on every gate evaluation. Group by workspace (one write drops the whole library),
31
- // keyed per resolved id so a picked preset and the default cache separately. A null (deleted
32
- // id / unseeded default) caches as a value and still falls through, exactly as an uncached
33
- // read would (the `RiskPolicyCacheValue` wrapper).
34
- const read = async (key, load) => {
35
- const cache = this.deps.riskPolicyCache;
36
- if (!cache)
37
- return load();
38
- return (await cache.get(key, workspaceId, async () => ({ policy: await load() }))).policy;
39
- };
40
- if (block.riskPolicyId) {
41
- const id = block.riskPolicyId;
42
- const picked = await read(`picked:${id}`, () => repo.get(workspaceId, id));
43
- if (picked)
44
- return picked;
45
- }
46
- const fallback = await read('default', () => repo.getDefault(workspaceId));
47
- if (fallback)
48
- return fallback;
49
- }
50
- return DEFAULT_RISK_POLICY;
32
+ return resolveRiskPolicy({
33
+ repository: this.deps.riskPolicyRepository,
34
+ workspaceId,
35
+ riskPolicyId: block.riskPolicyId,
36
+ read: cachedRiskPolicyRead(this.deps.riskPolicyCache, workspaceId),
37
+ });
51
38
  }
52
39
  /**
53
40
  * Settle the block's latest merge track record as `human_merged`, tagging the reviewer effort
@@ -1 +1 @@
1
- {"version":3,"file":"RunMergePolicy.js","sourceRoot":"","sources":["../../../src/modules/execution/RunMergePolicy.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAwBzD;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,cAAc;IACI,IAAI;IAAjC,YAA6B,IAAwB;oBAAxB,IAAI;IAAuB,CAAC;IAEzD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,KAAY;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAA;QAC3C,IAAI,IAAI,EAAE,CAAC;YACT,2FAA2F;YAC3F,4FAA4F;YAC5F,6FAA6F;YAC7F,2FAA2F;YAC3F,mDAAmD;YACnD,MAAM,IAAI,GAAG,KAAK,EAChB,GAAW,EACX,IAAsC,EACV,EAAE;gBAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAA;gBACvC,IAAI,CAAC,KAAK;oBAAE,OAAO,IAAI,EAAE,CAAA;gBACzB,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YAC3F,CAAC,CAAA;YACD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAA;gBAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;gBAC1E,IAAI,MAAM;oBAAE,OAAO,MAAM,CAAA;YAC3B,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAA;YAC1E,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAA;QAC/B,CAAC;QACD,OAAO,mBAAmB,CAAA;IAC5B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CACpB,WAAmB,EACnB,OAAe,EACf,YAAkC;QAElC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAA;QACtC,IAAI,CAAC,GAAG;YAAE,OAAM;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;YAC/D,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,OAAM;YAC1C,MAAM,GAAG,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC,CAAA;QAC1F,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,WAAmB,EAAE,WAAmB;QAC5D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;QACzF,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"RunMergePolicy.js","sourceRoot":"","sources":["../../../src/modules/execution/RunMergePolicy.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAuB1F;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,cAAc;IACI,IAAI;IAAjC,YAA6B,IAAwB;oBAAxB,IAAI;IAAuB,CAAC;IAEzD;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,KAAY;QAC7C,OAAO,iBAAiB,CAAC;YACvB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB;YAC1C,WAAW;YACX,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC;SACnE,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CACpB,WAAmB,EACnB,OAAe,EACf,YAAkC;QAElC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAA;QACtC,IAAI,CAAC,GAAG;YAAE,OAAM;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;YAC/D,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,OAAM;YAC1C,MAAM,GAAG,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC,CAAA;QAC1F,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,WAAmB,EAAE,WAAmB;QAC5D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;QACzF,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;CACF"}
@@ -13,6 +13,25 @@ export declare function pendingFollowUpCount(state: FollowUpsStepState | null |
13
13
  * (the answer steers the next pass). Filed / dismissed items are excluded.
14
14
  */
15
15
  export declare function followUpsToSendBack(state: FollowUpsStepState): FollowUpItem[];
16
+ /**
17
+ * The send-back budget as the engine READS it: passes spent, and the ceiling they stop at.
18
+ *
19
+ * Both fields are typed required (the wire schema defaults them: 0 and
20
+ * {@link DEFAULT_FOLLOW_UP_MAX_LOOPS}), and both are nonetheless read defensively, because step
21
+ * state is persisted as one JSON blob and read back with `JSON.parse` rather than a schema parse,
22
+ * so a row written before a field existed reaches this code missing it, defaults and all. A missing
23
+ * ceiling reads as 0, which stops the loop rather than running it unbounded: the safe direction for
24
+ * a value that spends model calls.
25
+ *
26
+ * Stated once because two callers must agree on it. {@link shouldLoopCoder} decides with these
27
+ * numbers and the public decision projection REPORTS them, so a projection that defaulted the
28
+ * ceiling differently would tell a caller it had budget for a send-back the engine was never going
29
+ * to spend, and the run would advance instead of looping with no error anywhere.
30
+ */
31
+ export declare function followUpLoopBudget(state: FollowUpsStepState): {
32
+ loops: number;
33
+ maxLoops: number;
34
+ };
16
35
  /** Whether the gate should loop the Coder now: there are unsent send-back items and budget remains. */
17
36
  export declare function shouldLoopCoder(state: FollowUpsStepState): boolean;
18
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"followUp.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/followUp.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAS3E,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAE9C,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzF;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGzF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAI7E;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAGlE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CA2BlE"}
1
+ {"version":3,"file":"followUp.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/followUp.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAS3E,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAE9C,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzF;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGzF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAI7E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAC7D,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAEA;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAIlE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CA2BlE"}
@@ -26,11 +26,30 @@ export function pendingFollowUpCount(state) {
26
26
  export function followUpsToSendBack(state) {
27
27
  return state.items.filter((item) => (item.status === 'queued' || item.status === 'answered') && !item.sentToCoder);
28
28
  }
29
+ /**
30
+ * The send-back budget as the engine READS it: passes spent, and the ceiling they stop at.
31
+ *
32
+ * Both fields are typed required (the wire schema defaults them: 0 and
33
+ * {@link DEFAULT_FOLLOW_UP_MAX_LOOPS}), and both are nonetheless read defensively, because step
34
+ * state is persisted as one JSON blob and read back with `JSON.parse` rather than a schema parse,
35
+ * so a row written before a field existed reaches this code missing it, defaults and all. A missing
36
+ * ceiling reads as 0, which stops the loop rather than running it unbounded: the safe direction for
37
+ * a value that spends model calls.
38
+ *
39
+ * Stated once because two callers must agree on it. {@link shouldLoopCoder} decides with these
40
+ * numbers and the public decision projection REPORTS them, so a projection that defaulted the
41
+ * ceiling differently would tell a caller it had budget for a send-back the engine was never going
42
+ * to spend, and the run would advance instead of looping with no error anywhere.
43
+ */
44
+ export function followUpLoopBudget(state) {
45
+ return { loops: state.loops ?? 0, maxLoops: state.maxLoops ?? 0 };
46
+ }
29
47
  /** Whether the gate should loop the Coder now: there are unsent send-back items and budget remains. */
30
48
  export function shouldLoopCoder(state) {
31
49
  if (hasPendingFollowUps(state))
32
50
  return false;
33
- return followUpsToSendBack(state).length > 0 && (state.loops ?? 0) < (state.maxLoops ?? 0);
51
+ const budget = followUpLoopBudget(state);
52
+ return followUpsToSendBack(state).length > 0 && budget.loops < budget.maxLoops;
34
53
  }
35
54
  /**
36
55
  * Render the queued follow-ups + answered questions into the rework feedback the Coder
@@ -1 +1 @@
1
- {"version":3,"file":"followUp.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/followUp.logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"followUp.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/followUp.logic.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,13 @@ export interface PrReportInputs {
11
11
  provider?: 'github' | 'gitlab' | null;
12
12
  /** Deep link into the run's observability panel; null when no public app URL is configured. */
13
13
  runUrl: string | null;
14
+ /**
15
+ * The two MACHINE links, built from the deployment's public backend URL: the run's tool-call
16
+ * trajectory and this report served live. Null when no such URL is configured, exactly as
17
+ * {@link PrReportInputs.runUrl} is for the app link.
18
+ */
19
+ trajectoryUrl: string | null;
20
+ reportUrl: string | null;
14
21
  /**
15
22
  * The service's in-repo `spec/` tree, reassembled from the run's branch, for the
16
23
  * requirement → evidence join. `null`/absent when it could not be read at all (no VCS
@@ -1 +1 @@
1
- {"version":3,"file":"prReport.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/prReport.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,iBAAiB,EAKjB,aAAa,EAEb,oBAAoB,EAEpB,OAAO,EAER,MAAM,qBAAqB,CAAA;AAI5B,OAAO,EACL,KAAK,yBAAyB,EAG/B,MAAM,4BAA4B,CAAA;AAuFnC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,2FAA2F;IAC3F,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAA;IACrC,+FAA+F;IAC/F,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACrB;;;;OAIG;IACH,YAAY,EAAE,yBAAyB,CAAA;IACvC,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAA;CACZ;AA8WD,oFAAoF;AACpF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,cAAc,GACrB,oBAAoB,CA6CtB;AA0OD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoD/E"}
1
+ {"version":3,"file":"prReport.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/prReport.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,iBAAiB,EAKjB,aAAa,EAEb,oBAAoB,EAEpB,OAAO,EAER,MAAM,qBAAqB,CAAA;AAI5B,OAAO,EACL,KAAK,yBAAyB,EAG/B,MAAM,4BAA4B,CAAA;AAuFnC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,2FAA2F;IAC3F,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAA;IACrC,+FAA+F;IAC/F,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACrB;;;;OAIG;IACH,YAAY,EAAE,yBAAyB,CAAA;IACvC,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAA;CACZ;AA8WD,oFAAoF;AACpF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,cAAc,GACrB,oBAAoB,CAiDtB;AA0PD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoD/E"}
@@ -437,7 +437,11 @@ export function composePrVerificationReport(instance, inputs) {
437
437
  environments: composeEnvironments(instance, inputs.environments, (items, label) => cap(items, label, truncations)),
438
438
  merge: composeMerge(instance),
439
439
  judges: composeJudges(instance, truncations),
440
- observability: { runUrl: inputs.runUrl },
440
+ observability: {
441
+ runUrl: inputs.runUrl,
442
+ trajectoryUrl: inputs.trajectoryUrl,
443
+ reportUrl: inputs.reportUrl,
444
+ },
441
445
  truncations,
442
446
  };
443
447
  }
@@ -598,7 +602,7 @@ function renderJudges(judges) {
598
602
  }
599
603
  return out;
600
604
  }
601
- function renderRun(run, runUrl) {
605
+ function renderRun(run, observability) {
602
606
  const out = [
603
607
  '### Run',
604
608
  '',
@@ -611,8 +615,20 @@ function renderRun(run, runUrl) {
611
615
  if (run.issues.length) {
612
616
  out.push(`**Tracker issues:** ${run.issues.map((i) => `[${hostMarkdown.inline(i.title)}](${i.url})`).join(', ')}`);
613
617
  }
614
- if (runUrl)
615
- out.push(`**Observability:** [Model activity / Provided context](${runUrl})`);
618
+ if (observability.runUrl) {
619
+ out.push(`**Observability:** [Model activity / Provided context](${observability.runUrl})`);
620
+ }
621
+ // The two machine links are rendered in the PROSE as well as carried in the JSON block, and
622
+ // that is the point of the feature rather than a duplication: the reader who needs to check a
623
+ // claim in this report is often a person, and a trajectory nobody can find is not an audit
624
+ // trail. Both endpoints are key-authenticated, so a reader without a credential gets a 401,
625
+ // the same honest refusal the app link beside them produces.
626
+ if (observability.trajectoryUrl) {
627
+ out.push(`**Trajectory (API):** [Every tool call, in order](${observability.trajectoryUrl})`);
628
+ }
629
+ if (observability.reportUrl) {
630
+ out.push(`**This report (API):** [Live JSON](${observability.reportUrl})`);
631
+ }
616
632
  out.push('', '| # | Step | State | Model |', '| --- | --- | --- | --- |');
617
633
  for (const step of run.steps) {
618
634
  out.push(`| ${step.index + 1} | ${hostMarkdown.cell(step.agentKind)} | ${hostMarkdown.cell(step.state)} | ${step.model ? hostMarkdown.cell(step.model) : '—'} |`);
@@ -645,7 +661,7 @@ export function renderPrVerificationReport(report) {
645
661
  '_Maintained by cat-factory. These are captured facts from the run that produced this PR,',
646
662
  "not the agent's own claims. It is rewritten in place as the run progresses._",
647
663
  '',
648
- ...renderRun(report.run, report.observability.runUrl),
664
+ ...renderRun(report.run, report.observability),
649
665
  ...renderCi(report.ci),
650
666
  // The two CAPTURED-OUTPUT sections sit beside CI rather than at the end: they answer the same
651
667
  // question a reviewer asks first ("does it work?"), and unlike CI they are the platform's own