@cat-factory/orchestration 0.298.1 → 0.300.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 (76) hide show
  1. package/dist/container/execution-service.d.ts.map +1 -1
  2. package/dist/container/execution-service.js +5 -0
  3. package/dist/container/execution-service.js.map +1 -1
  4. package/dist/modules/bootstrap/BootstrapService.d.ts +17 -8
  5. package/dist/modules/bootstrap/BootstrapService.d.ts.map +1 -1
  6. package/dist/modules/bootstrap/BootstrapService.js +114 -44
  7. package/dist/modules/bootstrap/BootstrapService.js.map +1 -1
  8. package/dist/modules/bootstrap/MonorepoBootstrapController.d.ts +0 -2
  9. package/dist/modules/bootstrap/MonorepoBootstrapController.d.ts.map +1 -1
  10. package/dist/modules/bootstrap/MonorepoBootstrapController.js +1 -5
  11. package/dist/modules/bootstrap/MonorepoBootstrapController.js.map +1 -1
  12. package/dist/modules/bootstrap/bootstrapDelivery.d.ts +20 -0
  13. package/dist/modules/bootstrap/bootstrapDelivery.d.ts.map +1 -0
  14. package/dist/modules/bootstrap/bootstrapDelivery.js +83 -0
  15. package/dist/modules/bootstrap/bootstrapDelivery.js.map +1 -0
  16. package/dist/modules/execution/BugFishingController.d.ts +277 -0
  17. package/dist/modules/execution/BugFishingController.d.ts.map +1 -0
  18. package/dist/modules/execution/BugFishingController.js +644 -0
  19. package/dist/modules/execution/BugFishingController.js.map +1 -0
  20. package/dist/modules/execution/DeployFixController.d.ts.map +1 -1
  21. package/dist/modules/execution/DeployFixController.js +13 -3
  22. package/dist/modules/execution/DeployFixController.js.map +1 -1
  23. package/dist/modules/execution/EnvironmentInvestigationController.d.ts.map +1 -1
  24. package/dist/modules/execution/EnvironmentInvestigationController.js +42 -9
  25. package/dist/modules/execution/EnvironmentInvestigationController.js.map +1 -1
  26. package/dist/modules/execution/ExecutionService.d.ts +9 -0
  27. package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
  28. package/dist/modules/execution/ExecutionService.js +37 -11
  29. package/dist/modules/execution/ExecutionService.js.map +1 -1
  30. package/dist/modules/execution/ExecutionServiceDependencies.d.ts +16 -1
  31. package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
  32. package/dist/modules/execution/PollCompletionController.d.ts +3 -0
  33. package/dist/modules/execution/PollCompletionController.d.ts.map +1 -1
  34. package/dist/modules/execution/PollCompletionController.js +16 -0
  35. package/dist/modules/execution/PollCompletionController.js.map +1 -1
  36. package/dist/modules/execution/RunDispatcher.d.ts +1 -0
  37. package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
  38. package/dist/modules/execution/RunDispatcher.js +6 -1
  39. package/dist/modules/execution/RunDispatcher.js.map +1 -1
  40. package/dist/modules/execution/RunDispatcherDependencies.d.ts +2 -0
  41. package/dist/modules/execution/RunDispatcherDependencies.d.ts.map +1 -1
  42. package/dist/modules/execution/RunDispatcherDependencies.js.map +1 -1
  43. package/dist/modules/execution/StepGraph.d.ts.map +1 -1
  44. package/dist/modules/execution/StepGraph.js +10 -6
  45. package/dist/modules/execution/StepGraph.js.map +1 -1
  46. package/dist/modules/execution/bugFishing.logic.d.ts +129 -0
  47. package/dist/modules/execution/bugFishing.logic.d.ts.map +1 -0
  48. package/dist/modules/execution/bugFishing.logic.js +284 -0
  49. package/dist/modules/execution/bugFishing.logic.js.map +1 -0
  50. package/dist/modules/execution/deployer.logic.d.ts +41 -0
  51. package/dist/modules/execution/deployer.logic.d.ts.map +1 -1
  52. package/dist/modules/execution/deployer.logic.js +86 -0
  53. package/dist/modules/execution/deployer.logic.js.map +1 -1
  54. package/dist/modules/execution/dispatcher-registries.d.ts +4 -2
  55. package/dist/modules/execution/dispatcher-registries.d.ts.map +1 -1
  56. package/dist/modules/execution/dispatcher-registries.js +69 -1
  57. package/dist/modules/execution/dispatcher-registries.js.map +1 -1
  58. package/dist/modules/execution/gate-window-controllers.d.ts +22 -1
  59. package/dist/modules/execution/gate-window-controllers.d.ts.map +1 -1
  60. package/dist/modules/execution/gate-window-controllers.js +29 -0
  61. package/dist/modules/execution/gate-window-controllers.js.map +1 -1
  62. package/dist/modules/execution/prReport.environments.d.ts +2 -1
  63. package/dist/modules/execution/prReport.environments.d.ts.map +1 -1
  64. package/dist/modules/execution/prReport.environments.js +265 -12
  65. package/dist/modules/execution/prReport.environments.js.map +1 -1
  66. package/dist/modules/execution/run-decision-surfaces.d.ts +16 -3
  67. package/dist/modules/execution/run-decision-surfaces.d.ts.map +1 -1
  68. package/dist/modules/execution/run-decision-surfaces.js +26 -2
  69. package/dist/modules/execution/run-decision-surfaces.js.map +1 -1
  70. package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -1
  71. package/dist/modules/recurring/RecurringPipelineService.js +1 -0
  72. package/dist/modules/recurring/RecurringPipelineService.js.map +1 -1
  73. package/dist/modules/settings/workspaceSettingsMerge.d.ts.map +1 -1
  74. package/dist/modules/settings/workspaceSettingsMerge.js +6 -0
  75. package/dist/modules/settings/workspaceSettingsMerge.js.map +1 -1
  76. package/package.json +11 -11
@@ -0,0 +1,129 @@
1
+ import { type BugFishingAgentOutput, type BugFishingFinding, type BugFishingPhase, type BugFishingSpawn, type BugFishingStepState } from '@cat-factory/kernel';
2
+ export { BUG_FISHING_SPAWN_CLAIM_TTL_MS, bugFishingSpawnIsClaimable } from '@cat-factory/kernel';
3
+ /**
4
+ * Plan the angles an expedition will fish.
5
+ *
6
+ * `selected` is the creator's pick, held as bare strings (a task authored against a later
7
+ * build's angle list must still parse here). An id this build does not ship is DROPPED and
8
+ * returned in `unknown`, so the caller can say so in the plan rather than silently fishing
9
+ * fewer angles than the person asked for. An empty or entirely-unrecognised selection falls
10
+ * back to the whole catalog, which is the intended default: an expedition exists to cover
11
+ * ground nobody thought to look at, so narrowing it is the deliberate act.
12
+ *
13
+ * Order follows the CATALOG rather than the selection, so two expeditions on the same board
14
+ * fish their shared angles in the same order and their phase lists read alike.
15
+ */
16
+ export declare function planBugFishingPhases(selected: readonly string[] | undefined): {
17
+ phases: BugFishingPhase[];
18
+ unknown: string[];
19
+ };
20
+ /**
21
+ * Turn ONE pass's raw output into stamped, severity-ordered findings.
22
+ *
23
+ * A finding with neither a title nor a detail is dropped: the lenient agent schema fills both
24
+ * with `''` rather than failing the parse, so an entry carrying neither is an artefact of that
25
+ * leniency and not something a human could triage. Everything else is kept, including a finding
26
+ * with no path — an expedition can legitimately report a gap that spans files, and blanking the
27
+ * row would be the platform deciding it did not happen.
28
+ */
29
+ export declare function coerceBugFishingFindings(output: BugFishingAgentOutput | undefined, phaseId: string, mintId: () => string): {
30
+ findings: BugFishingFinding[];
31
+ dropped: number;
32
+ };
33
+ /**
34
+ * Record a COMPLETED pass: settle its phase with the summary it gave, append its findings, and
35
+ * move the cursor to the next angle.
36
+ *
37
+ * The returned status is `fishing` while an angle is still pending and `awaiting_triage` once
38
+ * the last one settles — the state's own answer to "is there more coming", which the window
39
+ * renders and the controller uses to decide between re-arming the step and parking the run.
40
+ */
41
+ export declare function recordBugFishingPhase(state: BugFishingStepState, phaseIndex: number, outcome: {
42
+ summary: string | null;
43
+ findings: BugFishingFinding[];
44
+ dropped: number;
45
+ at: number;
46
+ }): BugFishingStepState;
47
+ /**
48
+ * Record a pass that FAILED (its container job crashed, or produced nothing usable). The phase
49
+ * is settled as `failed` carrying the reason and the expedition moves on to the next angle.
50
+ *
51
+ * One angle failing must never cost the expedition the angles that already landed, nor the ones
52
+ * still to come: the passes are independent by construction, which is the point of running them
53
+ * as separate dispatches. The failure is NAMED on the phase rather than dropped, because a phase
54
+ * that silently reported nothing reads exactly like a phase that found nothing.
55
+ */
56
+ export declare function failBugFishingPhase(state: BugFishingStepState, phaseIndex: number, reason: string | null, at: number): BugFishingStepState;
57
+ /** Mark the phase at `phaseIndex` as being fished right now (the dispatch just went out). */
58
+ export declare function startBugFishingPhase(state: BugFishingStepState, phaseIndex: number): BugFishingStepState;
59
+ /**
60
+ * CLAIM a finding for a spawn, BEFORE the task it names is created.
61
+ *
62
+ * The claim is what makes marking safe against two callers at once: it is written under the
63
+ * run's compare-and-swap, so exactly one of them lands and the loser's transform is a no-op on
64
+ * a finding that is no longer claimable. The claimer recognises its own by the `taskId` it minted
65
+ * and put in the claim, exactly as the initiative loop recognises its own spawn by block id —
66
+ * which is what lets {@link settleBugFishingSpawn} refuse to overwrite a claim it does not own.
67
+ *
68
+ * A no-op on an unknown, dismissed or already-claimed finding. The caller re-reads the finding
69
+ * afterwards and compares the `taskId`: that comparison, not this function, is how it learns
70
+ * whether it won.
71
+ */
72
+ export declare function claimBugFishingSpawn(state: BugFishingStepState, findingId: string, claim: BugFishingSpawn, now: number): BugFishingStepState;
73
+ /**
74
+ * SETTLE a claim this caller owns: `spawned` once the task and its run exist, or `failed` with
75
+ * the cause when they do not.
76
+ *
77
+ * Matched on `taskId`, so a claim that expired and was re-taken by somebody else is left alone.
78
+ * Overwriting it would report the loser's outcome against the winner's task.
79
+ */
80
+ export declare function settleBugFishingSpawn(state: BugFishingStepState, findingId: string, taskId: string, outcome: {
81
+ status: 'spawned';
82
+ executionId: string | null;
83
+ } | {
84
+ status: 'failed';
85
+ failureReason: string;
86
+ }): BugFishingStepState;
87
+ /**
88
+ * Dismiss a finding: it stays on the record, struck through, and can no longer be marked.
89
+ *
90
+ * Kept rather than removed because the expedition's record is what a human reads to decide
91
+ * whether the hunt was worth running: a finding that was looked at and rejected is evidence
92
+ * about the agent's precision, and deleting it would make every expedition look flawless.
93
+ * Idempotent, and a no-op on a finding whose fix task exists or is being created (that decision
94
+ * is made). A finding whose last mark FAILED is dismissable: nothing was created for it.
95
+ */
96
+ export declare function dismissBugFishingFinding(state: BugFishingStepState, findingId: string, now: number): BugFishingStepState;
97
+ /**
98
+ * Findings with no decision yet: neither dismissed nor carrying a mark that landed.
99
+ *
100
+ * A `failed` spawn counts as UNTRIAGED, because it is: the human made a decision, the platform
101
+ * did not carry it out, and nothing was created. Counting it as done is how "N findings to
102
+ * triage" would come to under-report the work left, on exactly the runs where something went
103
+ * wrong.
104
+ */
105
+ export declare function untriagedBugFishingFindings(state: BugFishingStepState, now: number): readonly BugFishingFinding[];
106
+ /**
107
+ * The finding titles to brief the NEXT pass with, so it does not re-report what earlier angles
108
+ * already caught. Dismissed findings are included deliberately: a human rejecting a finding says
109
+ * they do not want it fixed, not that the next pass should raise it again.
110
+ */
111
+ export declare function priorBugFishingFindingTitles(state: BugFishingStepState): string[];
112
+ /**
113
+ * The angle a phase index names, described from the CATALOG but falling back to what the run
114
+ * itself recorded.
115
+ *
116
+ * Two different absences, and they need different answers. A phase whose id this build retired
117
+ * is described by {@link describeBugFishingPhase} as retired, but the run still knows the title
118
+ * and goal it was planned under, so those win over the placeholder — the expedition genuinely
119
+ * fished that angle and its own record is the better witness. Only an id with no recorded phase
120
+ * at all falls through to the placeholder.
121
+ */
122
+ export declare function describeRecordedPhase(phase: BugFishingPhase): {
123
+ id: string;
124
+ focus: string;
125
+ retired?: boolean;
126
+ title: string;
127
+ goal: string;
128
+ };
129
+ //# sourceMappingURL=bugFishing.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bugFishing.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/bugFishing.logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,qBAAqB,CAAA;AAK5B,OAAO,EAAE,8BAA8B,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAgDhG;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG;IAC7E,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CAiBA;AAQD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,qBAAqB,GAAG,SAAS,EACzC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,MAAM,GACnB;IAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA0BpD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9F,mBAAmB,CAoBrB;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,EAAE,EAAE,MAAM,GACT,mBAAmB,CAkBrB;AAED,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,MAAM,GACjB,mBAAmB,CAQrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,eAAe,EACtB,GAAG,EAAE,MAAM,GACV,mBAAmB,CASrB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EACH;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACjD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC9C,mBAAmB,CASrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,mBAAmB,CASrB;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,MAAM,GACV,SAAS,iBAAiB,EAAE,CAI9B;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAEjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe;;;;;;EAO3D"}
@@ -0,0 +1,284 @@
1
+ import { BUG_FISHING_PHASES, BUG_FISHING_SEVERITY_ORDER, bugFishingSpawnIsClaimable, describeBugFishingPhase, redactSecrets, } from '@cat-factory/kernel';
2
+ // The one rule both this engine and the triage window judge a finding by ("is anything being
3
+ // done about it") lives in contracts, so the window cannot come to offer a mark this refuses.
4
+ // Re-exported so a caller in this module's own layer keeps one import.
5
+ export { BUG_FISHING_SPAWN_CLAIM_TTL_MS, bugFishingSpawnIsClaimable } from '@cat-factory/kernel';
6
+ // ---------------------------------------------------------------------------
7
+ // Pure reductions over a bug-fishing expedition's step state. Everything here is a
8
+ // total function of (state, input) → state so the controller's CAS bodies stay pure
9
+ // and every rule is unit-testable without a run: which angles an expedition plans,
10
+ // how one pass's raw output becomes stamped findings, and what marking or dismissing
11
+ // a finding does to the record.
12
+ //
13
+ // The mirror of `prReview.logic.ts` for the expedition flow.
14
+ // ---------------------------------------------------------------------------
15
+ /** Cap on a single finding's free-text field, so one runaway reply cannot bloat the run blob. */
16
+ const MAX_FINDING_TEXT = 4000;
17
+ /** Cap on a phase summary. */
18
+ const MAX_SUMMARY = 4000;
19
+ /**
20
+ * Most findings one pass may contribute.
21
+ *
22
+ * The state rides the run's persisted `detail` blob, re-serialized on every progress write, and
23
+ * an expedition runs eight passes over it. The cap is generous enough that hitting it means the
24
+ * pass stopped applying the finding bar, which is why the overflow is REPORTED in the phase
25
+ * summary rather than silently trimmed: a reader who assumed a prefix would conclude the tail
26
+ * was never found.
27
+ */
28
+ const MAX_FINDINGS_PER_PHASE = 40;
29
+ /**
30
+ * Trim, SCRUB and cap one field of a finding, in that order.
31
+ *
32
+ * Scrubbing at the mint site rather than at each reader, and BEFORE the cap, for the reason the
33
+ * PR-report composer states: a finding's `evidence` is code the agent quoted out of the
34
+ * repository, so a checked-in credential reaches it the same way it reaches any captured output.
35
+ * From here it lands in the expedition record, in the triage window, in an inbox card, and in the
36
+ * DESCRIPTION of every spawned fix task — four surfaces, only one of which would be an obvious
37
+ * place to remember. Scrubbing before the cap keeps a redacted span from being split in half by
38
+ * it, which would put the tail of a secret back in the text.
39
+ */
40
+ function clamp(text, max) {
41
+ const t = redactSecrets((text ?? '').trim()) ?? '';
42
+ return t.length > max ? `${t.slice(0, max)}…` : t;
43
+ }
44
+ function optionalClamped(text, max) {
45
+ const t = clamp(text, max);
46
+ return t.length > 0 ? t : undefined;
47
+ }
48
+ /**
49
+ * Plan the angles an expedition will fish.
50
+ *
51
+ * `selected` is the creator's pick, held as bare strings (a task authored against a later
52
+ * build's angle list must still parse here). An id this build does not ship is DROPPED and
53
+ * returned in `unknown`, so the caller can say so in the plan rather than silently fishing
54
+ * fewer angles than the person asked for. An empty or entirely-unrecognised selection falls
55
+ * back to the whole catalog, which is the intended default: an expedition exists to cover
56
+ * ground nobody thought to look at, so narrowing it is the deliberate act.
57
+ *
58
+ * Order follows the CATALOG rather than the selection, so two expeditions on the same board
59
+ * fish their shared angles in the same order and their phase lists read alike.
60
+ */
61
+ export function planBugFishingPhases(selected) {
62
+ const picked = new Set((selected ?? []).map((id) => id.trim()).filter((id) => id.length > 0));
63
+ const unknown = [...picked].filter((id) => !BUG_FISHING_PHASES.some((p) => p.id === id));
64
+ const chosen = BUG_FISHING_PHASES.filter((p) => picked.size === 0 || picked.has(p.id));
65
+ const catalog = chosen.length > 0 ? chosen : BUG_FISHING_PHASES;
66
+ return {
67
+ phases: catalog.map((p) => ({
68
+ id: p.id,
69
+ title: p.title,
70
+ goal: p.goal,
71
+ status: 'pending',
72
+ summary: null,
73
+ settledAt: null,
74
+ failureReason: null,
75
+ })),
76
+ unknown,
77
+ };
78
+ }
79
+ /** Severity rank, most severe first; an unrecognised severity sorts last rather than first. */
80
+ function severityRank(severity) {
81
+ const index = BUG_FISHING_SEVERITY_ORDER.indexOf(severity);
82
+ return index === -1 ? BUG_FISHING_SEVERITY_ORDER.length : index;
83
+ }
84
+ /**
85
+ * Turn ONE pass's raw output into stamped, severity-ordered findings.
86
+ *
87
+ * A finding with neither a title nor a detail is dropped: the lenient agent schema fills both
88
+ * with `''` rather than failing the parse, so an entry carrying neither is an artefact of that
89
+ * leniency and not something a human could triage. Everything else is kept, including a finding
90
+ * with no path — an expedition can legitimately report a gap that spans files, and blanking the
91
+ * row would be the platform deciding it did not happen.
92
+ */
93
+ export function coerceBugFishingFindings(output, phaseId, mintId) {
94
+ const raw = (output?.findings ?? []).filter((f) => clamp(f.title, MAX_FINDING_TEXT).length > 0 || clamp(f.detail, MAX_FINDING_TEXT).length > 0);
95
+ const kept = [...raw].sort((a, b) => severityRank(a.severity) - severityRank(b.severity));
96
+ const dropped = Math.max(0, kept.length - MAX_FINDINGS_PER_PHASE);
97
+ return {
98
+ findings: kept.slice(0, MAX_FINDINGS_PER_PHASE).map((f) => ({
99
+ id: mintId(),
100
+ phaseId,
101
+ path: clamp(f.path, 400),
102
+ line: typeof f.line === 'number' && Number.isFinite(f.line) ? f.line : null,
103
+ severity: f.severity,
104
+ kind: f.kind,
105
+ confidence: f.confidence,
106
+ title: clamp(f.title, 300) || clamp(f.detail, 300),
107
+ detail: clamp(f.detail, MAX_FINDING_TEXT),
108
+ failureScenario: optionalClamped(f.failureScenario, MAX_FINDING_TEXT) ?? null,
109
+ evidence: optionalClamped(f.evidence, MAX_FINDING_TEXT) ?? null,
110
+ suggestedFix: optionalClamped(f.suggestedFix, MAX_FINDING_TEXT) ?? null,
111
+ spawn: null,
112
+ dismissed: false,
113
+ })),
114
+ dropped,
115
+ };
116
+ }
117
+ /**
118
+ * Record a COMPLETED pass: settle its phase with the summary it gave, append its findings, and
119
+ * move the cursor to the next angle.
120
+ *
121
+ * The returned status is `fishing` while an angle is still pending and `awaiting_triage` once
122
+ * the last one settles — the state's own answer to "is there more coming", which the window
123
+ * renders and the controller uses to decide between re-arming the step and parking the run.
124
+ */
125
+ export function recordBugFishingPhase(state, phaseIndex, outcome) {
126
+ const phases = (state.phases ?? []).map((phase, i) => i === phaseIndex
127
+ ? {
128
+ ...phase,
129
+ status: 'completed',
130
+ summary: phaseSummary(outcome.summary, outcome.findings.length, outcome.dropped),
131
+ settledAt: outcome.at,
132
+ failureReason: null,
133
+ }
134
+ : phase);
135
+ const next = phaseIndex + 1;
136
+ return {
137
+ ...state,
138
+ phases,
139
+ currentPhaseIndex: next,
140
+ findings: [...(state.findings ?? []), ...outcome.findings],
141
+ status: next < phases.length ? 'fishing' : 'awaiting_triage',
142
+ };
143
+ }
144
+ /**
145
+ * The phase summary as recorded: the agent's own account, plus a sentence naming any findings
146
+ * the per-phase cap dropped.
147
+ *
148
+ * A cap that is not a plain prefix has to say so — a reader who assumed one would conclude the
149
+ * tail was never found, when in fact it was found and discarded.
150
+ */
151
+ function phaseSummary(summary, kept, dropped) {
152
+ const base = clamp(summary, MAX_SUMMARY);
153
+ if (dropped <= 0)
154
+ return base;
155
+ const note = `This pass reported more findings than one phase may record: the ${kept} most severe were ` +
156
+ `kept and ${dropped} lower-severity ones were dropped. Re-run this angle with a narrower ` +
157
+ 'focus to see them.';
158
+ return base ? `${base}\n\n${note}` : note;
159
+ }
160
+ /**
161
+ * Record a pass that FAILED (its container job crashed, or produced nothing usable). The phase
162
+ * is settled as `failed` carrying the reason and the expedition moves on to the next angle.
163
+ *
164
+ * One angle failing must never cost the expedition the angles that already landed, nor the ones
165
+ * still to come: the passes are independent by construction, which is the point of running them
166
+ * as separate dispatches. The failure is NAMED on the phase rather than dropped, because a phase
167
+ * that silently reported nothing reads exactly like a phase that found nothing.
168
+ */
169
+ export function failBugFishingPhase(state, phaseIndex, reason, at) {
170
+ const phases = (state.phases ?? []).map((phase, i) => i === phaseIndex
171
+ ? {
172
+ ...phase,
173
+ status: 'failed',
174
+ settledAt: at,
175
+ failureReason: clamp(reason, 2000) || 'The pass did not complete.',
176
+ }
177
+ : phase);
178
+ const next = phaseIndex + 1;
179
+ return {
180
+ ...state,
181
+ phases,
182
+ currentPhaseIndex: next,
183
+ status: next < phases.length ? 'fishing' : 'awaiting_triage',
184
+ };
185
+ }
186
+ /** Mark the phase at `phaseIndex` as being fished right now (the dispatch just went out). */
187
+ export function startBugFishingPhase(state, phaseIndex) {
188
+ return {
189
+ ...state,
190
+ currentPhaseIndex: phaseIndex,
191
+ phases: (state.phases ?? []).map((phase, i) => i === phaseIndex ? { ...phase, status: 'fishing' } : phase),
192
+ };
193
+ }
194
+ /**
195
+ * CLAIM a finding for a spawn, BEFORE the task it names is created.
196
+ *
197
+ * The claim is what makes marking safe against two callers at once: it is written under the
198
+ * run's compare-and-swap, so exactly one of them lands and the loser's transform is a no-op on
199
+ * a finding that is no longer claimable. The claimer recognises its own by the `taskId` it minted
200
+ * and put in the claim, exactly as the initiative loop recognises its own spawn by block id —
201
+ * which is what lets {@link settleBugFishingSpawn} refuse to overwrite a claim it does not own.
202
+ *
203
+ * A no-op on an unknown, dismissed or already-claimed finding. The caller re-reads the finding
204
+ * afterwards and compares the `taskId`: that comparison, not this function, is how it learns
205
+ * whether it won.
206
+ */
207
+ export function claimBugFishingSpawn(state, findingId, claim, now) {
208
+ return {
209
+ ...state,
210
+ findings: (state.findings ?? []).map((f) => f.id === findingId && !f.dismissed && bugFishingSpawnIsClaimable(f.spawn, now)
211
+ ? { ...f, spawn: claim }
212
+ : f),
213
+ };
214
+ }
215
+ /**
216
+ * SETTLE a claim this caller owns: `spawned` once the task and its run exist, or `failed` with
217
+ * the cause when they do not.
218
+ *
219
+ * Matched on `taskId`, so a claim that expired and was re-taken by somebody else is left alone.
220
+ * Overwriting it would report the loser's outcome against the winner's task.
221
+ */
222
+ export function settleBugFishingSpawn(state, findingId, taskId, outcome) {
223
+ return {
224
+ ...state,
225
+ findings: (state.findings ?? []).map((f) => f.id === findingId && f.spawn?.taskId === taskId
226
+ ? { ...f, spawn: { ...f.spawn, ...outcome } }
227
+ : f),
228
+ };
229
+ }
230
+ /**
231
+ * Dismiss a finding: it stays on the record, struck through, and can no longer be marked.
232
+ *
233
+ * Kept rather than removed because the expedition's record is what a human reads to decide
234
+ * whether the hunt was worth running: a finding that was looked at and rejected is evidence
235
+ * about the agent's precision, and deleting it would make every expedition look flawless.
236
+ * Idempotent, and a no-op on a finding whose fix task exists or is being created (that decision
237
+ * is made). A finding whose last mark FAILED is dismissable: nothing was created for it.
238
+ */
239
+ export function dismissBugFishingFinding(state, findingId, now) {
240
+ return {
241
+ ...state,
242
+ findings: (state.findings ?? []).map((f) => f.id === findingId && bugFishingSpawnIsClaimable(f.spawn, now)
243
+ ? { ...f, dismissed: true }
244
+ : f),
245
+ };
246
+ }
247
+ /**
248
+ * Findings with no decision yet: neither dismissed nor carrying a mark that landed.
249
+ *
250
+ * A `failed` spawn counts as UNTRIAGED, because it is: the human made a decision, the platform
251
+ * did not carry it out, and nothing was created. Counting it as done is how "N findings to
252
+ * triage" would come to under-report the work left, on exactly the runs where something went
253
+ * wrong.
254
+ */
255
+ export function untriagedBugFishingFindings(state, now) {
256
+ return (state.findings ?? []).filter((f) => !f.dismissed && bugFishingSpawnIsClaimable(f.spawn, now));
257
+ }
258
+ /**
259
+ * The finding titles to brief the NEXT pass with, so it does not re-report what earlier angles
260
+ * already caught. Dismissed findings are included deliberately: a human rejecting a finding says
261
+ * they do not want it fixed, not that the next pass should raise it again.
262
+ */
263
+ export function priorBugFishingFindingTitles(state) {
264
+ return (state.findings ?? []).map((f) => f.title).filter((t) => t.trim().length > 0);
265
+ }
266
+ /**
267
+ * The angle a phase index names, described from the CATALOG but falling back to what the run
268
+ * itself recorded.
269
+ *
270
+ * Two different absences, and they need different answers. A phase whose id this build retired
271
+ * is described by {@link describeBugFishingPhase} as retired, but the run still knows the title
272
+ * and goal it was planned under, so those win over the placeholder — the expedition genuinely
273
+ * fished that angle and its own record is the better witness. Only an id with no recorded phase
274
+ * at all falls through to the placeholder.
275
+ */
276
+ export function describeRecordedPhase(phase) {
277
+ const described = describeBugFishingPhase(phase.id);
278
+ return {
279
+ ...described,
280
+ title: phase.title || described.title,
281
+ goal: phase.goal || described.goal,
282
+ };
283
+ }
284
+ //# sourceMappingURL=bugFishing.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bugFishing.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/bugFishing.logic.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,47 @@ export declare function orderProvisionTargets(targets: ReadonlyArray<{
44
44
  * replay of the dispatch still reproduces the same id.
45
45
  */
46
46
  export declare function deployDispatchEpoch(step: PipelineStep): number;
47
+ /**
48
+ * Re-arm a `deployer` step's `deploy-fixer` budget for another provisioning cycle, keeping the
49
+ * rounds already on the record.
50
+ *
51
+ * `phase` is reset to `retrying` because a stale `fixing` routes the re-run's container-backed
52
+ * deploy job to the agent poller that never dispatched it. The two members are both live-loop
53
+ * phases and the poll router asks only whether the phase IS `fixing`, so `retrying` is the one
54
+ * that means "no fixer job is in flight, and the deployer is about to provision".
55
+ */
56
+ export declare function restartDeployFixState(fix: PipelineStep['deployFix']): PipelineStep['deployFix'] | undefined;
57
+ /**
58
+ * Re-arm a `deployer` step's environment-investigation budget for another provisioning cycle,
59
+ * keeping the rounds already on the record.
60
+ *
61
+ * `environmentId` goes, because it names the environment this cycle supersedes and a round run
62
+ * against it would restart, re-probe or tear down infrastructure the re-provision has replaced.
63
+ *
64
+ * `waitExtensions` deliberately does NOT go, unlike the round counter beside it. It is both the
65
+ * bound on `wait` verdicts and the run's only record that one was granted (the bring-up simply
66
+ * runs past the configured ceiling), and a cycle is not always started by a person or a gate:
67
+ * `StepGraph.rerunProducerThrough` resets every step from a producer through its companion and
68
+ * judge, and the judge and below-threshold companion loops both drive it with no human involved.
69
+ * Re-arming it would hand the model a fresh ceiling extension per automatic rework round, and
70
+ * would erase the granted one from the record the verification report reduces.
71
+ */
72
+ export declare function restartEnvironmentInvestigationState(state: PipelineStep['environmentInvestigation']): PipelineStep['environmentInvestigation'] | undefined;
73
+ /**
74
+ * Append one round to a remediation loop's run-long attempt log, dropping the oldest rows past
75
+ * `max` and counting what went.
76
+ *
77
+ * Shared by both loops because both logs have the same shape of problem: they survive the run
78
+ * (the verification report reduces them) while living inside the `ExecutionInstance` JSON blob,
79
+ * which is re-serialized on every step write and compare-and-swapped on every persist, so an
80
+ * uncapped log grows with every loop-back for the rest of the run. The drop is COUNTED rather
81
+ * than silent: the report reduces the surviving rows, so a dropped round would otherwise read as
82
+ * one that never ran. The model is `appendRalphAttempt`, which caps the same kind of log.
83
+ */
84
+ export declare function appendAttemptLog<T>(log: readonly T[] | null | undefined, entry: T, max: number, dropped: number | null | undefined): {
85
+ attemptLog: T[];
86
+ droppedAttempts: number;
87
+ };
47
88
  /**
48
89
  * Whether the ENABLED chain contains a `deployer` step. The Deployer-config gate fires only then:
49
90
  * a pipeline with no enabled deployer stands no environment up, so its provisioning config is
@@ -1 +1 @@
1
- {"version":3,"file":"deployer.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/deployer.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG3F;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAMxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,EAC/D,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GACpD,MAAM,EAAE,CAuBV;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAG9D;AAgBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GACtC,OAAO,CAET;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAC5C,MAAM,EAAE,CAcV;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,sHAAsH;IACtH,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC;;;;OAIG;IACH,iBAAiB,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,GAAG,eAAe,CAAA;KAAE,CAAA;IAC3E;;;;OAIG;IACH,cAAc,CAAC,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACnD;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,2BAA2B,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC9E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,aAAa,EAAE,YAAY,GAAG,eAAe,CAAA;CAAE,GAC3F;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhE;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,sBAAsB,CAqBvF"}
1
+ {"version":3,"file":"deployer.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/deployer.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG3F;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAMxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,EAC/D,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GACpD,MAAM,EAAE,CAuBV;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAG9D;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,GAC7B,YAAY,CAAC,WAAW,CAAC,GAAG,SAAS,CASvC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,YAAY,CAAC,0BAA0B,CAAC,GAC9C,YAAY,CAAC,0BAA0B,CAAC,GAAG,SAAS,CAStD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,GAAG,EAAE,SAAS,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,CAAC,EACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC;IAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAO9C;AAgBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GACtC,OAAO,CAET;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAC5C,MAAM,EAAE,CAcV;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,sHAAsH;IACtH,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC;;;;OAIG;IACH,iBAAiB,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,GAAG,eAAe,CAAA;KAAE,CAAA;IAC3E;;;;OAIG;IACH,cAAc,CAAC,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACnD;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,2BAA2B,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC9E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,aAAa,EAAE,YAAY,GAAG,eAAe,CAAA;CAAE,GAC3F;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhE;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,sBAAsB,CAqBvF"}
@@ -76,6 +76,92 @@ export function deployDispatchEpoch(step) {
76
76
  return evictions + Math.max(0, (step.attempts ?? 1) - 1);
77
77
  }
78
78
  // ---------------------------------------------------------------------------
79
+ // Re-arming the two remediation loops for a fresh provisioning cycle.
80
+ //
81
+ // A `deployer` step is re-run WITHIN one run whenever something loops back to it (the `human-test`
82
+ // gate rebuilding the environment a person is testing, a producer re-run through it), and each of
83
+ // these keeps the two halves the loops need kept apart:
84
+ //
85
+ // - The COUNTERS are per provisioning CYCLE. A re-run provisions from scratch, so it is a fresh
86
+ // failure if it fails, and carrying the spent `attempts` across sends its FIRST failure
87
+ // straight to the give-up: a `deploy_blocked` card raised with zero repair rounds actually
88
+ // run, or a terminal failure explained by the PREVIOUS environment's verdict.
89
+ // - The ATTEMPT LOG is per RUN, because it is what the run's verification report reduces. A
90
+ // frame repaired by one cycle and re-deployed cleanly by the next was still machine-edited,
91
+ // and dropping the log makes the report say nothing was ever attempted. Each row carries the
92
+ // CYCLE it ran in, which is what lets a reader of the run-long log tell the rounds the live
93
+ // budget was spent on from the ones a superseded environment's cycle spent.
94
+ //
95
+ // Both return undefined for a step that carries no such state, so a caller can spread them
96
+ // unconditionally. The retry path (`retry.logic.resetStep`) deliberately drops both by omission:
97
+ // a retry is a NEW run with a report of its own, so nothing there is history worth keeping.
98
+ // ---------------------------------------------------------------------------
99
+ /**
100
+ * Re-arm a `deployer` step's `deploy-fixer` budget for another provisioning cycle, keeping the
101
+ * rounds already on the record.
102
+ *
103
+ * `phase` is reset to `retrying` because a stale `fixing` routes the re-run's container-backed
104
+ * deploy job to the agent poller that never dispatched it. The two members are both live-loop
105
+ * phases and the poll router asks only whether the phase IS `fixing`, so `retrying` is the one
106
+ * that means "no fixer job is in flight, and the deployer is about to provision".
107
+ */
108
+ export function restartDeployFixState(fix) {
109
+ if (!fix)
110
+ return undefined;
111
+ return {
112
+ ...fix,
113
+ phase: 'retrying',
114
+ attempts: 0,
115
+ cycle: (fix.cycle ?? 0) + 1,
116
+ attemptLog: fix.attemptLog ?? [],
117
+ };
118
+ }
119
+ /**
120
+ * Re-arm a `deployer` step's environment-investigation budget for another provisioning cycle,
121
+ * keeping the rounds already on the record.
122
+ *
123
+ * `environmentId` goes, because it names the environment this cycle supersedes and a round run
124
+ * against it would restart, re-probe or tear down infrastructure the re-provision has replaced.
125
+ *
126
+ * `waitExtensions` deliberately does NOT go, unlike the round counter beside it. It is both the
127
+ * bound on `wait` verdicts and the run's only record that one was granted (the bring-up simply
128
+ * runs past the configured ceiling), and a cycle is not always started by a person or a gate:
129
+ * `StepGraph.rerunProducerThrough` resets every step from a producer through its companion and
130
+ * judge, and the judge and below-threshold companion loops both drive it with no human involved.
131
+ * Re-arming it would hand the model a fresh ceiling extension per automatic rework round, and
132
+ * would erase the granted one from the record the verification report reduces.
133
+ */
134
+ export function restartEnvironmentInvestigationState(state) {
135
+ if (!state)
136
+ return undefined;
137
+ return {
138
+ ...state,
139
+ attempts: 0,
140
+ environmentId: null,
141
+ cycle: (state.cycle ?? 0) + 1,
142
+ attemptLog: state.attemptLog ?? [],
143
+ };
144
+ }
145
+ /**
146
+ * Append one round to a remediation loop's run-long attempt log, dropping the oldest rows past
147
+ * `max` and counting what went.
148
+ *
149
+ * Shared by both loops because both logs have the same shape of problem: they survive the run
150
+ * (the verification report reduces them) while living inside the `ExecutionInstance` JSON blob,
151
+ * which is re-serialized on every step write and compare-and-swapped on every persist, so an
152
+ * uncapped log grows with every loop-back for the rest of the run. The drop is COUNTED rather
153
+ * than silent: the report reduces the surviving rows, so a dropped round would otherwise read as
154
+ * one that never ran. The model is `appendRalphAttempt`, which caps the same kind of log.
155
+ */
156
+ export function appendAttemptLog(log, entry, max, dropped) {
157
+ const appended = [...(log ?? []), entry];
158
+ const overflow = Math.max(appended.length - max, 0);
159
+ return {
160
+ attemptLog: overflow > 0 ? appended.slice(overflow) : appended,
161
+ droppedAttempts: (dropped ?? 0) + overflow,
162
+ };
163
+ }
164
+ // ---------------------------------------------------------------------------
79
165
  // Run-start Deployer-config gate (pure half).
80
166
  //
81
167
  // When a pipeline INCLUDES an enabled `deployer` step, the environment it will stand up must be
@@ -1 +1 @@
1
- {"version":3,"file":"deployer.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/deployer.logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deployer.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/deployer.logic.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { AgentRunResult, Block, BlockRepository, BrainstormSession, ClarityReview, Clock, ExecutionInstance, GateDefinition, JudgeDefinition, PipelineStep, RequirementReview, RunInitiatorScope, StepCompletionResolver, StepResolverRegistry } from '@cat-factory/kernel';
1
+ import type { AgentRunContext, AgentRunResult, Block, BlockRepository, BrainstormSession, ClarityReview, Clock, ExecutionInstance, GateDefinition, JudgeDefinition, PipelineStep, RequirementReview, RunInitiatorScope, StepCompletionResolver, StepResolverRegistry } from '@cat-factory/kernel';
2
2
  import type { AgentKindRegistry } from '@cat-factory/agents';
3
3
  import type { EnvironmentProvisioningService } from '@cat-factory/integrations';
4
4
  import type { DeployerStepController } from './DeployerStepController.js';
@@ -10,6 +10,7 @@ import type { ReviewGateController, ReviewKind } from './ReviewGateController.js
10
10
  import type { BinaryCandidateController } from './BinaryCandidateController.js';
11
11
  import type { ForkDecisionController } from './ForkDecisionController.js';
12
12
  import { PrReviewController } from './PrReviewController.js';
13
+ import { BugFishingController } from './BugFishingController.js';
13
14
  import type { InterviewGateController } from './InterviewGateController.js';
14
15
  import type { TesterController } from './TesterController.js';
15
16
  import type { RalphController } from './RalphController.js';
@@ -43,6 +44,7 @@ export interface DispatcherRegistryDeps {
43
44
  forkDecisionController: ForkDecisionController;
44
45
  binaryCandidateController: BinaryCandidateController;
45
46
  prReviewController: PrReviewController;
47
+ bugFishingController: BugFishingController;
46
48
  mergeResolver: MergeResolver;
47
49
  requirementsKind: ReviewKind<RequirementReview>;
48
50
  clarityKind: ReviewKind<ClarityReview>;
@@ -65,7 +67,7 @@ export interface DispatcherRegistryDeps {
65
67
  judgeFor: (agentKind: string) => JudgeDefinition | undefined;
66
68
  handleForkDecisionPhase: (ctx: StepHandlerContext) => Promise<AdvanceResult>;
67
69
  handlePrReviewResolution: (ctx: StepHandlerContext) => Promise<AdvanceResult>;
68
- handleAgentStep: (ctx: StepHandlerContext) => Promise<AdvanceResult>;
70
+ handleAgentStep: (ctx: StepHandlerContext, dispatchKind?: string, augmentContext?: (context: AgentRunContext) => void) => Promise<AdvanceResult>;
69
71
  ingestBlueprint: (workspaceId: string, blockId: string, rawService: unknown) => Promise<void>;
70
72
  ingestSpec: (workspaceId: string, rawDoc: unknown) => Promise<void>;
71
73
  }