@coralai/sps-cli 0.6.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.
- package/dist/commands/cardAdd.d.ts +2 -0
- package/dist/commands/cardAdd.d.ts.map +1 -0
- package/dist/commands/cardAdd.js +65 -0
- package/dist/commands/cardAdd.js.map +1 -0
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +264 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/monitorTick.d.ts +2 -0
- package/dist/commands/monitorTick.d.ts.map +1 -0
- package/dist/commands/monitorTick.js +47 -0
- package/dist/commands/monitorTick.js.map +1 -0
- package/dist/commands/pipelineTick.d.ts +2 -0
- package/dist/commands/pipelineTick.d.ts.map +1 -0
- package/dist/commands/pipelineTick.js +44 -0
- package/dist/commands/pipelineTick.js.map +1 -0
- package/dist/commands/pmCommand.d.ts +2 -0
- package/dist/commands/pmCommand.d.ts.map +1 -0
- package/dist/commands/pmCommand.js +159 -0
- package/dist/commands/pmCommand.js.map +1 -0
- package/dist/commands/projectInit.d.ts +2 -0
- package/dist/commands/projectInit.d.ts.map +1 -0
- package/dist/commands/projectInit.js +75 -0
- package/dist/commands/projectInit.js.map +1 -0
- package/dist/commands/qaTick.d.ts +2 -0
- package/dist/commands/qaTick.d.ts.map +1 -0
- package/dist/commands/qaTick.js +43 -0
- package/dist/commands/qaTick.js.map +1 -0
- package/dist/commands/schedulerTick.d.ts +2 -0
- package/dist/commands/schedulerTick.d.ts.map +1 -0
- package/dist/commands/schedulerTick.js +45 -0
- package/dist/commands/schedulerTick.js.map +1 -0
- package/dist/commands/tick.d.ts +14 -0
- package/dist/commands/tick.d.ts.map +1 -0
- package/dist/commands/tick.js +251 -0
- package/dist/commands/tick.js.map +1 -0
- package/dist/commands/workerLaunch.d.ts +2 -0
- package/dist/commands/workerLaunch.d.ts.map +1 -0
- package/dist/commands/workerLaunch.js +56 -0
- package/dist/commands/workerLaunch.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +131 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +23 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +28 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/lock.d.ts +14 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +65 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/logger.d.ts +24 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +62 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +27 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +29 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/queue.d.ts +14 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/queue.js +38 -0
- package/dist/core/queue.js.map +1 -0
- package/dist/core/state.d.ts +32 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +52 -0
- package/dist/core/state.js.map +1 -0
- package/dist/engines/CloseoutEngine.d.ts +60 -0
- package/dist/engines/CloseoutEngine.d.ts.map +1 -0
- package/dist/engines/CloseoutEngine.js +596 -0
- package/dist/engines/CloseoutEngine.js.map +1 -0
- package/dist/engines/ExecutionEngine.d.ts +65 -0
- package/dist/engines/ExecutionEngine.d.ts.map +1 -0
- package/dist/engines/ExecutionEngine.js +603 -0
- package/dist/engines/ExecutionEngine.js.map +1 -0
- package/dist/engines/MonitorEngine.d.ts +39 -0
- package/dist/engines/MonitorEngine.d.ts.map +1 -0
- package/dist/engines/MonitorEngine.js +473 -0
- package/dist/engines/MonitorEngine.js.map +1 -0
- package/dist/engines/SchedulerEngine.d.ts +24 -0
- package/dist/engines/SchedulerEngine.d.ts.map +1 -0
- package/dist/engines/SchedulerEngine.js +195 -0
- package/dist/engines/SchedulerEngine.js.map +1 -0
- package/dist/interfaces/HookProvider.d.ts +9 -0
- package/dist/interfaces/HookProvider.d.ts.map +1 -0
- package/dist/interfaces/HookProvider.js +2 -0
- package/dist/interfaces/HookProvider.js.map +1 -0
- package/dist/interfaces/Notifier.d.ts +11 -0
- package/dist/interfaces/Notifier.d.ts.map +1 -0
- package/dist/interfaces/Notifier.js +2 -0
- package/dist/interfaces/Notifier.js.map +1 -0
- package/dist/interfaces/RepoBackend.d.ts +23 -0
- package/dist/interfaces/RepoBackend.d.ts.map +1 -0
- package/dist/interfaces/RepoBackend.js +2 -0
- package/dist/interfaces/RepoBackend.js.map +1 -0
- package/dist/interfaces/TaskBackend.d.ts +24 -0
- package/dist/interfaces/TaskBackend.d.ts.map +1 -0
- package/dist/interfaces/TaskBackend.js +2 -0
- package/dist/interfaces/TaskBackend.js.map +1 -0
- package/dist/interfaces/WorkerProvider.d.ts +23 -0
- package/dist/interfaces/WorkerProvider.d.ts.map +1 -0
- package/dist/interfaces/WorkerProvider.js +2 -0
- package/dist/interfaces/WorkerProvider.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +226 -0
- package/dist/main.js.map +1 -0
- package/dist/models/types.d.ts +68 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +2 -0
- package/dist/models/types.js.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts +84 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.js +293 -0
- package/dist/providers/ClaudeWorkerProvider.js.map +1 -0
- package/dist/providers/CodexWorkerProvider.d.ts +50 -0
- package/dist/providers/CodexWorkerProvider.d.ts.map +1 -0
- package/dist/providers/CodexWorkerProvider.js +275 -0
- package/dist/providers/CodexWorkerProvider.js.map +1 -0
- package/dist/providers/GitLabRepoBackend.d.ts +42 -0
- package/dist/providers/GitLabRepoBackend.d.ts.map +1 -0
- package/dist/providers/GitLabRepoBackend.js +280 -0
- package/dist/providers/GitLabRepoBackend.js.map +1 -0
- package/dist/providers/MarkdownTaskBackend.d.ts +88 -0
- package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -0
- package/dist/providers/MarkdownTaskBackend.js +414 -0
- package/dist/providers/MarkdownTaskBackend.js.map +1 -0
- package/dist/providers/MatrixNotifier.d.ts +30 -0
- package/dist/providers/MatrixNotifier.d.ts.map +1 -0
- package/dist/providers/MatrixNotifier.js +82 -0
- package/dist/providers/MatrixNotifier.js.map +1 -0
- package/dist/providers/PlaneTaskBackend.d.ts +86 -0
- package/dist/providers/PlaneTaskBackend.d.ts.map +1 -0
- package/dist/providers/PlaneTaskBackend.js +409 -0
- package/dist/providers/PlaneTaskBackend.js.map +1 -0
- package/dist/providers/TrelloTaskBackend.d.ts +53 -0
- package/dist/providers/TrelloTaskBackend.d.ts.map +1 -0
- package/dist/providers/TrelloTaskBackend.js +300 -0
- package/dist/providers/TrelloTaskBackend.js.map +1 -0
- package/dist/providers/registry.d.ts +10 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +29 -0
- package/dist/providers/registry.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import { readState, writeState } from '../core/state.js';
|
|
2
|
+
import { Logger } from '../core/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* CloseoutEngine handles the QA → merge → Done → resource release pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Decision tree per 01 §10.3.2:
|
|
7
|
+
* QA card → check MR exists?
|
|
8
|
+
* ├─ MR not found → NEEDS-FIX
|
|
9
|
+
* └─ MR exists → check MR state
|
|
10
|
+
* ├─ already merged → resource release → Done
|
|
11
|
+
* ├─ open + CI success + can_be_merged → attempt merge
|
|
12
|
+
* ├─ open + CI failed → self-repair or NEEDS-FIX
|
|
13
|
+
* ├─ open + CI running/pending → skip
|
|
14
|
+
* ├─ open + cannot_be_merged → CONFLICT
|
|
15
|
+
* └─ closed (not merged) → NEEDS-FIX
|
|
16
|
+
*/
|
|
17
|
+
export class CloseoutEngine {
|
|
18
|
+
ctx;
|
|
19
|
+
taskBackend;
|
|
20
|
+
repoBackend;
|
|
21
|
+
workerProvider;
|
|
22
|
+
notifier;
|
|
23
|
+
log;
|
|
24
|
+
constructor(ctx, taskBackend, repoBackend, workerProvider, notifier) {
|
|
25
|
+
this.ctx = ctx;
|
|
26
|
+
this.taskBackend = taskBackend;
|
|
27
|
+
this.repoBackend = repoBackend;
|
|
28
|
+
this.workerProvider = workerProvider;
|
|
29
|
+
this.notifier = notifier;
|
|
30
|
+
this.log = new Logger('qa', ctx.projectName, ctx.paths.logsDir);
|
|
31
|
+
}
|
|
32
|
+
async tick() {
|
|
33
|
+
const actions = [];
|
|
34
|
+
const recommendedActions = [];
|
|
35
|
+
const result = {
|
|
36
|
+
project: this.ctx.projectName,
|
|
37
|
+
component: 'qa',
|
|
38
|
+
status: 'ok',
|
|
39
|
+
exitCode: 0,
|
|
40
|
+
actions,
|
|
41
|
+
recommendedActions,
|
|
42
|
+
details: {},
|
|
43
|
+
};
|
|
44
|
+
try {
|
|
45
|
+
const qaCards = await this.taskBackend.listByState('QA');
|
|
46
|
+
if (qaCards.length === 0) {
|
|
47
|
+
this.log.info('No QA cards to process');
|
|
48
|
+
result.details = { reason: 'no_qa_cards' };
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
this.log.info(`Processing ${qaCards.length} QA card(s)`);
|
|
52
|
+
for (const card of qaCards) {
|
|
53
|
+
// Skip cards with BLOCKED label
|
|
54
|
+
if (card.labels.includes('BLOCKED')) {
|
|
55
|
+
this.log.debug(`Skipping seq ${card.seq}: BLOCKED`);
|
|
56
|
+
actions.push({
|
|
57
|
+
action: 'skip',
|
|
58
|
+
entity: `seq:${card.seq}`,
|
|
59
|
+
result: 'skip',
|
|
60
|
+
message: 'Card is BLOCKED',
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await this.processQaCard(card, actions, recommendedActions);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
69
|
+
this.log.error(`Unexpected error processing seq ${card.seq}: ${msg}`);
|
|
70
|
+
actions.push({
|
|
71
|
+
action: 'closeout',
|
|
72
|
+
entity: `seq:${card.seq}`,
|
|
73
|
+
result: 'fail',
|
|
74
|
+
message: `Unexpected error: ${msg}`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
81
|
+
this.log.error(`Closeout tick failed: ${msg}`);
|
|
82
|
+
result.status = 'fail';
|
|
83
|
+
result.exitCode = 1;
|
|
84
|
+
result.details = { error: msg };
|
|
85
|
+
}
|
|
86
|
+
if (actions.some((a) => a.result === 'fail') && result.status === 'ok') {
|
|
87
|
+
result.status = 'degraded';
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
// ─── Core Decision Tree ───────────────────────────────────────
|
|
92
|
+
async processQaCard(card, actions, recommendedActions) {
|
|
93
|
+
const seq = card.seq;
|
|
94
|
+
const branchName = this.buildBranchName(card);
|
|
95
|
+
// Check MR status
|
|
96
|
+
const mrStatus = await this.repoBackend.getMrStatus(branchName);
|
|
97
|
+
if (!mrStatus.exists || mrStatus.state === 'not_found') {
|
|
98
|
+
// MR not found → NEEDS-FIX
|
|
99
|
+
this.log.warn(`seq ${seq}: MR not found for branch ${branchName}`);
|
|
100
|
+
await this.markNeedsFix(seq, 'MR not found — worker may not have created it');
|
|
101
|
+
actions.push({
|
|
102
|
+
action: 'mark-needs-fix',
|
|
103
|
+
entity: `seq:${seq}`,
|
|
104
|
+
result: 'ok',
|
|
105
|
+
message: 'MR not found',
|
|
106
|
+
});
|
|
107
|
+
this.logEvent('closeout-no-mr', seq, 'ok');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// MR exists — check state
|
|
111
|
+
switch (mrStatus.state) {
|
|
112
|
+
case 'merged':
|
|
113
|
+
// Already merged externally (doc 12 §6.2) → resource release → Done
|
|
114
|
+
this.log.info(`seq ${seq}: MR already merged, proceeding to release`);
|
|
115
|
+
await this.releaseAndDone(card, actions);
|
|
116
|
+
return;
|
|
117
|
+
case 'closed':
|
|
118
|
+
// Closed without merge → NEEDS-FIX
|
|
119
|
+
this.log.warn(`seq ${seq}: MR is closed (not merged)`);
|
|
120
|
+
await this.markNeedsFix(seq, 'MR was closed without merging');
|
|
121
|
+
actions.push({
|
|
122
|
+
action: 'mark-needs-fix',
|
|
123
|
+
entity: `seq:${seq}`,
|
|
124
|
+
result: 'ok',
|
|
125
|
+
message: 'MR closed without merge',
|
|
126
|
+
});
|
|
127
|
+
this.logEvent('closeout-mr-closed', seq, 'ok');
|
|
128
|
+
return;
|
|
129
|
+
case 'opened':
|
|
130
|
+
await this.processOpenMr(card, mrStatus, actions, recommendedActions);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async processOpenMr(card, mrStatus, actions, recommendedActions) {
|
|
135
|
+
const seq = card.seq;
|
|
136
|
+
// Check merge conflicts — attempt auto-resolution (L1 rebase → L2 worker)
|
|
137
|
+
if (mrStatus.mergeStatus === 'cannot_be_merged') {
|
|
138
|
+
this.log.warn(`seq ${seq}: MR has merge conflicts, attempting resolution`);
|
|
139
|
+
await this.notifySafe(`seq:${seq} merge conflict detected — attempting auto-resolution`, 'warning');
|
|
140
|
+
const resolved = await this.resolveConflict(card, actions);
|
|
141
|
+
if (resolved) {
|
|
142
|
+
// Conflict resolved — skip this tick, let next tick re-check CI/merge status
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Resolution failed — mark CONFLICT
|
|
146
|
+
await this.addLabelSafe(seq, 'CONFLICT');
|
|
147
|
+
await this.commentSafe(seq, 'Merge conflict could not be auto-resolved. Manual intervention needed.');
|
|
148
|
+
await this.notifySafe(`seq:${seq} conflict auto-resolution FAILED — needs manual fix`, 'error');
|
|
149
|
+
actions.push({
|
|
150
|
+
action: 'mark-conflict',
|
|
151
|
+
entity: `seq:${seq}`,
|
|
152
|
+
result: 'ok',
|
|
153
|
+
message: 'Conflict unresolvable',
|
|
154
|
+
});
|
|
155
|
+
this.logEvent('closeout-conflict', seq, 'ok');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// Check CI status
|
|
159
|
+
switch (mrStatus.ciStatus) {
|
|
160
|
+
case 'running':
|
|
161
|
+
case 'pending':
|
|
162
|
+
case 'created':
|
|
163
|
+
// CI still running → skip, wait for next tick
|
|
164
|
+
this.log.debug(`seq ${seq}: CI is ${mrStatus.ciStatus}, waiting`);
|
|
165
|
+
actions.push({
|
|
166
|
+
action: 'skip',
|
|
167
|
+
entity: `seq:${seq}`,
|
|
168
|
+
result: 'skip',
|
|
169
|
+
message: `CI is ${mrStatus.ciStatus}`,
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
case 'failed':
|
|
173
|
+
await this.handleCiFailure(card, actions, recommendedActions);
|
|
174
|
+
return;
|
|
175
|
+
case 'success':
|
|
176
|
+
if (mrStatus.mergeStatus === 'can_be_merged' && mrStatus.iid != null) {
|
|
177
|
+
await this.attemptMerge(card, mrStatus.iid, actions);
|
|
178
|
+
}
|
|
179
|
+
else if (mrStatus.mergeStatus === 'checking') {
|
|
180
|
+
// Merge status still being determined → skip
|
|
181
|
+
this.log.debug(`seq ${seq}: merge status is 'checking', waiting`);
|
|
182
|
+
actions.push({
|
|
183
|
+
action: 'skip',
|
|
184
|
+
entity: `seq:${seq}`,
|
|
185
|
+
result: 'skip',
|
|
186
|
+
message: 'Merge status checking',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// Unknown merge status with CI success
|
|
191
|
+
this.log.warn(`seq ${seq}: CI passed but merge status is ${mrStatus.mergeStatus}`);
|
|
192
|
+
recommendedActions.push({
|
|
193
|
+
action: `Check MR merge status for seq:${seq}`,
|
|
194
|
+
reason: `CI passed but mergeStatus=${mrStatus.mergeStatus}`,
|
|
195
|
+
severity: 'warning',
|
|
196
|
+
autoExecutable: false,
|
|
197
|
+
requiresConfirmation: true,
|
|
198
|
+
safeToRetry: true,
|
|
199
|
+
});
|
|
200
|
+
actions.push({
|
|
201
|
+
action: 'skip',
|
|
202
|
+
entity: `seq:${seq}`,
|
|
203
|
+
result: 'skip',
|
|
204
|
+
message: `CI passed, mergeStatus=${mrStatus.mergeStatus}`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
default:
|
|
209
|
+
// CI status unknown — check CI_MODE
|
|
210
|
+
if (this.ctx.ciMode === 'none') {
|
|
211
|
+
// No CI configured — treat as success, attempt merge
|
|
212
|
+
if (mrStatus.mergeStatus === 'can_be_merged' && mrStatus.iid != null) {
|
|
213
|
+
await this.attemptMerge(card, mrStatus.iid, actions);
|
|
214
|
+
}
|
|
215
|
+
else if (mrStatus.iid != null) {
|
|
216
|
+
// CI_MODE=none + unknown merge status → still attempt merge
|
|
217
|
+
await this.attemptMerge(card, mrStatus.iid, actions);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
actions.push({
|
|
221
|
+
action: 'skip',
|
|
222
|
+
entity: `seq:${seq}`,
|
|
223
|
+
result: 'skip',
|
|
224
|
+
message: 'No CI, but MR has no iid',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.log.debug(`seq ${seq}: CI status is ${mrStatus.ciStatus}, skipping`);
|
|
230
|
+
actions.push({
|
|
231
|
+
action: 'skip',
|
|
232
|
+
entity: `seq:${seq}`,
|
|
233
|
+
result: 'skip',
|
|
234
|
+
message: `CI status unknown: ${mrStatus.ciStatus}`,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// ─── CI Failure Self-Repair (doc 12 §4) ────────────────────────
|
|
241
|
+
async handleCiFailure(card, actions, _recommendedActions) {
|
|
242
|
+
const seq = card.seq;
|
|
243
|
+
const maxAttempts = this.ctx.config.AUTOFIX_ATTEMPTS;
|
|
244
|
+
// Read autofix attempts from card meta
|
|
245
|
+
let meta;
|
|
246
|
+
try {
|
|
247
|
+
meta = await this.taskBackend.metaRead(seq);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
meta = {};
|
|
251
|
+
}
|
|
252
|
+
const autofixAttempts = typeof meta.autofixAttempts === 'number' ? meta.autofixAttempts : 0;
|
|
253
|
+
if (autofixAttempts < maxAttempts) {
|
|
254
|
+
// Try self-repair: find the worker session for this card
|
|
255
|
+
const state = readState(this.ctx.paths.stateFile, this.ctx.maxWorkers);
|
|
256
|
+
const slotEntry = Object.entries(state.workers).find(([, w]) => w.seq === parseInt(seq, 10) && w.tmuxSession);
|
|
257
|
+
if (slotEntry) {
|
|
258
|
+
const [, slotState] = slotEntry;
|
|
259
|
+
const session = slotState.tmuxSession;
|
|
260
|
+
try {
|
|
261
|
+
const inspection = await this.workerProvider.inspect(session);
|
|
262
|
+
if (inspection.alive) {
|
|
263
|
+
const fixPrompt = `CI pipeline has failed. Please review the CI logs, fix the issues, commit, and push. This is autofix attempt ${autofixAttempts + 1} of ${maxAttempts}.`;
|
|
264
|
+
await this.workerProvider.sendFix(session, fixPrompt);
|
|
265
|
+
// Increment counter
|
|
266
|
+
await this.taskBackend.metaWrite(seq, {
|
|
267
|
+
...meta,
|
|
268
|
+
autofixAttempts: autofixAttempts + 1,
|
|
269
|
+
});
|
|
270
|
+
this.log.info(`seq ${seq}: CI failed, sent fix prompt (attempt ${autofixAttempts + 1}/${maxAttempts})`);
|
|
271
|
+
actions.push({
|
|
272
|
+
action: 'autofix',
|
|
273
|
+
entity: `seq:${seq}`,
|
|
274
|
+
result: 'ok',
|
|
275
|
+
message: `Sent fix prompt (attempt ${autofixAttempts + 1}/${maxAttempts})`,
|
|
276
|
+
});
|
|
277
|
+
this.logEvent('closeout-autofix', seq, 'ok', {
|
|
278
|
+
attempt: autofixAttempts + 1,
|
|
279
|
+
max: maxAttempts,
|
|
280
|
+
});
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
286
|
+
this.log.warn(`seq ${seq}: Failed to send fix prompt: ${msg}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Worker session not found or dead — fall through to NEEDS-FIX
|
|
290
|
+
this.log.warn(`seq ${seq}: CI failed, no live worker session for autofix`);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
this.log.warn(`seq ${seq}: CI failed, autofix attempts exhausted (${autofixAttempts}/${maxAttempts})`);
|
|
294
|
+
}
|
|
295
|
+
// Exhausted or no worker → mark NEEDS-FIX
|
|
296
|
+
await this.markNeedsFix(seq, `CI failed after ${autofixAttempts} autofix attempt(s)`);
|
|
297
|
+
actions.push({
|
|
298
|
+
action: 'mark-needs-fix',
|
|
299
|
+
entity: `seq:${seq}`,
|
|
300
|
+
result: 'ok',
|
|
301
|
+
message: `CI failed, autofix exhausted (${autofixAttempts}/${maxAttempts})`,
|
|
302
|
+
});
|
|
303
|
+
this.logEvent('closeout-ci-fail', seq, 'ok', { autofixAttempts });
|
|
304
|
+
}
|
|
305
|
+
// ─── Merge Attempt ─────────────────────────────────────────────
|
|
306
|
+
async attemptMerge(card, iid, actions) {
|
|
307
|
+
const seq = card.seq;
|
|
308
|
+
this.log.info(`seq ${seq}: Attempting merge (iid=${iid})`);
|
|
309
|
+
try {
|
|
310
|
+
const mergeResult = await this.repoBackend.mergeMr(iid);
|
|
311
|
+
if (mergeResult.merged) {
|
|
312
|
+
this.log.ok(`seq ${seq}: MR merged successfully`);
|
|
313
|
+
await this.releaseAndDone(card, actions);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// Merge failed
|
|
317
|
+
this.log.warn(`seq ${seq}: Merge failed: ${mergeResult.error || 'unknown reason'}`);
|
|
318
|
+
await this.markNeedsFix(seq, `Merge failed: ${mergeResult.error || 'unknown'}`);
|
|
319
|
+
actions.push({
|
|
320
|
+
action: 'mark-needs-fix',
|
|
321
|
+
entity: `seq:${seq}`,
|
|
322
|
+
result: 'ok',
|
|
323
|
+
message: `Merge failed: ${mergeResult.error || 'unknown'}`,
|
|
324
|
+
});
|
|
325
|
+
this.logEvent('closeout-merge-fail', seq, 'ok', { error: mergeResult.error });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
330
|
+
this.log.error(`seq ${seq}: Merge threw: ${msg}`);
|
|
331
|
+
await this.markNeedsFix(seq, `Merge error: ${msg}`);
|
|
332
|
+
actions.push({
|
|
333
|
+
action: 'mark-needs-fix',
|
|
334
|
+
entity: `seq:${seq}`,
|
|
335
|
+
result: 'ok',
|
|
336
|
+
message: `Merge error: ${msg}`,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// ─── Resource Release (01 §10.3.3) ─────────────────────────────
|
|
341
|
+
/**
|
|
342
|
+
* Release resources after successful merge. Each step failure MUST NOT
|
|
343
|
+
* block subsequent steps — log and continue.
|
|
344
|
+
*
|
|
345
|
+
* Order:
|
|
346
|
+
* 1. Move card to Done
|
|
347
|
+
* 2. Release claim in PM
|
|
348
|
+
* 3. Release worker slot in state.json (→ idle)
|
|
349
|
+
* 4. Stop worker session
|
|
350
|
+
* 5. Mark worktree for cleanup
|
|
351
|
+
*/
|
|
352
|
+
async releaseAndDone(card, actions) {
|
|
353
|
+
const seq = card.seq;
|
|
354
|
+
const errors = [];
|
|
355
|
+
// Step 1: Move card to Done
|
|
356
|
+
try {
|
|
357
|
+
await this.taskBackend.move(seq, 'Done');
|
|
358
|
+
this.log.ok(`seq ${seq}: Moved to Done`);
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
362
|
+
this.log.error(`seq ${seq}: Failed to move to Done: ${msg}`);
|
|
363
|
+
errors.push(`move-done: ${msg}`);
|
|
364
|
+
}
|
|
365
|
+
// Step 2: Release claim
|
|
366
|
+
try {
|
|
367
|
+
await this.taskBackend.releaseClaim(seq);
|
|
368
|
+
this.log.ok(`seq ${seq}: Claim released`);
|
|
369
|
+
}
|
|
370
|
+
catch (err) {
|
|
371
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
372
|
+
this.log.error(`seq ${seq}: Failed to release claim: ${msg}`);
|
|
373
|
+
errors.push(`release-claim: ${msg}`);
|
|
374
|
+
}
|
|
375
|
+
// Step 3: Release worker slot in state.json
|
|
376
|
+
const state = readState(this.ctx.paths.stateFile, this.ctx.maxWorkers);
|
|
377
|
+
const slotEntry = Object.entries(state.workers).find(([, w]) => w.seq === parseInt(seq, 10));
|
|
378
|
+
let sessionName = null;
|
|
379
|
+
if (slotEntry) {
|
|
380
|
+
const [slotName, slotState] = slotEntry;
|
|
381
|
+
sessionName = slotState.tmuxSession;
|
|
382
|
+
try {
|
|
383
|
+
state.workers[slotName] = {
|
|
384
|
+
status: 'idle',
|
|
385
|
+
seq: null,
|
|
386
|
+
branch: null,
|
|
387
|
+
worktree: null,
|
|
388
|
+
tmuxSession: null,
|
|
389
|
+
claimedAt: null,
|
|
390
|
+
lastHeartbeat: null,
|
|
391
|
+
};
|
|
392
|
+
delete state.activeCards[seq];
|
|
393
|
+
writeState(this.ctx.paths.stateFile, state, 'closeout-release');
|
|
394
|
+
this.log.ok(`seq ${seq}: Worker slot ${slotName} released`);
|
|
395
|
+
}
|
|
396
|
+
catch (err) {
|
|
397
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
398
|
+
this.log.error(`seq ${seq}: Failed to release slot: ${msg}`);
|
|
399
|
+
errors.push(`release-slot: ${msg}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
// No active slot found — already released (idempotency)
|
|
404
|
+
// Still clean up activeCards entry if present
|
|
405
|
+
if (state.activeCards[seq]) {
|
|
406
|
+
delete state.activeCards[seq];
|
|
407
|
+
try {
|
|
408
|
+
writeState(this.ctx.paths.stateFile, state, 'closeout-release');
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// non-fatal
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
this.log.debug(`seq ${seq}: No active worker slot found (already released)`);
|
|
415
|
+
}
|
|
416
|
+
// Step 4: Stop worker session
|
|
417
|
+
if (sessionName) {
|
|
418
|
+
try {
|
|
419
|
+
await this.workerProvider.stop(sessionName);
|
|
420
|
+
this.log.ok(`seq ${seq}: Worker session ${sessionName} stopped`);
|
|
421
|
+
}
|
|
422
|
+
catch (err) {
|
|
423
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
424
|
+
this.log.error(`seq ${seq}: Failed to stop session: ${msg}`);
|
|
425
|
+
errors.push(`stop-session: ${msg}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// Step 5: Mark worktree for cleanup (don't delete immediately)
|
|
429
|
+
// We record it in state metadata; actual cleanup is a separate concern
|
|
430
|
+
try {
|
|
431
|
+
const freshState = readState(this.ctx.paths.stateFile, this.ctx.maxWorkers);
|
|
432
|
+
const branchName = this.buildBranchName(card);
|
|
433
|
+
const stateAny = freshState;
|
|
434
|
+
const worktreeCleanup = stateAny.worktreeCleanup || [];
|
|
435
|
+
if (!worktreeCleanup.includes(branchName)) {
|
|
436
|
+
worktreeCleanup.push(branchName);
|
|
437
|
+
stateAny.worktreeCleanup = worktreeCleanup;
|
|
438
|
+
writeState(this.ctx.paths.stateFile, freshState, 'closeout-worktree-mark');
|
|
439
|
+
}
|
|
440
|
+
this.log.ok(`seq ${seq}: Worktree marked for cleanup`);
|
|
441
|
+
}
|
|
442
|
+
catch (err) {
|
|
443
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
444
|
+
this.log.error(`seq ${seq}: Failed to mark worktree for cleanup: ${msg}`);
|
|
445
|
+
errors.push(`worktree-mark: ${msg}`);
|
|
446
|
+
}
|
|
447
|
+
// Notify
|
|
448
|
+
if (errors.length === 0) {
|
|
449
|
+
await this.notifySafe(`seq:${seq} merged and released successfully`, 'success');
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
await this.notifySafe(`seq:${seq} merged but release had errors: ${errors.join('; ')}`, 'warning');
|
|
453
|
+
}
|
|
454
|
+
// Record action
|
|
455
|
+
const actionResult = errors.length === 0 ? 'ok' : 'fail';
|
|
456
|
+
actions.push({
|
|
457
|
+
action: 'closeout',
|
|
458
|
+
entity: `seq:${seq}`,
|
|
459
|
+
result: actionResult,
|
|
460
|
+
message: errors.length === 0
|
|
461
|
+
? 'Merged → Done, resources released'
|
|
462
|
+
: `Merged → Done with errors: ${errors.join('; ')}`,
|
|
463
|
+
});
|
|
464
|
+
this.logEvent('closeout', seq, actionResult, errors.length > 0 ? { errors } : undefined);
|
|
465
|
+
}
|
|
466
|
+
// ─── Conflict Resolution (L1 rebase → L2 worker) ──────────────
|
|
467
|
+
/**
|
|
468
|
+
* Attempt to resolve merge conflict automatically.
|
|
469
|
+
* L1: auto rebase + force push
|
|
470
|
+
* L2: send conflict to original worker to resolve
|
|
471
|
+
* Returns true if resolution was initiated (wait for next tick to verify).
|
|
472
|
+
*/
|
|
473
|
+
async resolveConflict(card, actions) {
|
|
474
|
+
const seq = card.seq;
|
|
475
|
+
const branchName = this.buildBranchName(card);
|
|
476
|
+
const state = readState(this.ctx.paths.stateFile, this.ctx.maxWorkers);
|
|
477
|
+
const baseBranch = this.ctx.mergeBranch;
|
|
478
|
+
// Find worktree for this card
|
|
479
|
+
const slotEntry = Object.entries(state.workers).find(([, w]) => w.seq === parseInt(seq, 10));
|
|
480
|
+
const worktree = slotEntry?.[1]?.worktree;
|
|
481
|
+
if (!worktree) {
|
|
482
|
+
this.log.warn(`seq ${seq}: No worktree found for conflict resolution`);
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
// ── L1: Auto rebase ──────────────────────────────────────────
|
|
486
|
+
this.log.info(`seq ${seq}: L1 — attempting auto rebase onto ${baseBranch}`);
|
|
487
|
+
try {
|
|
488
|
+
const rebaseResult = await this.repoBackend.rebase(worktree, baseBranch);
|
|
489
|
+
if (rebaseResult.success) {
|
|
490
|
+
// Rebase succeeded — force push
|
|
491
|
+
await this.repoBackend.push(worktree, branchName, true);
|
|
492
|
+
this.log.ok(`seq ${seq}: L1 rebase succeeded, pushed with --force-with-lease`);
|
|
493
|
+
await this.notifySafe(`seq:${seq} conflict auto-resolved via rebase`, 'success');
|
|
494
|
+
actions.push({
|
|
495
|
+
action: 'conflict-rebase',
|
|
496
|
+
entity: `seq:${seq}`,
|
|
497
|
+
result: 'ok',
|
|
498
|
+
message: 'Auto rebase succeeded, waiting for CI re-check',
|
|
499
|
+
});
|
|
500
|
+
this.logEvent('conflict-rebase', seq, 'ok');
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
// Rebase failed — real conflicts
|
|
504
|
+
this.log.warn(`seq ${seq}: L1 rebase failed, conflicts in: ${(rebaseResult.conflictFiles || []).join(', ')}`);
|
|
505
|
+
await this.notifySafe(`seq:${seq} auto-rebase failed — conflict files: ${(rebaseResult.conflictFiles || []).join(', ')}`, 'warning');
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
509
|
+
this.log.warn(`seq ${seq}: L1 rebase threw: ${msg}`);
|
|
510
|
+
}
|
|
511
|
+
// ── L2: Send to original worker ──────────────────────────────
|
|
512
|
+
if (!slotEntry)
|
|
513
|
+
return false;
|
|
514
|
+
const [, slotState] = slotEntry;
|
|
515
|
+
const session = slotState.tmuxSession;
|
|
516
|
+
if (!session) {
|
|
517
|
+
this.log.warn(`seq ${seq}: No worker session for L2 conflict resolution`);
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
const inspection = await this.workerProvider.inspect(session);
|
|
522
|
+
if (!inspection.alive) {
|
|
523
|
+
this.log.warn(`seq ${seq}: Worker session dead, cannot do L2 resolution`);
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
this.log.info(`seq ${seq}: L2 — sending conflict resolution to worker ${session}`);
|
|
527
|
+
await this.workerProvider.resolveConflict(session, worktree, branchName);
|
|
528
|
+
await this.notifySafe(`seq:${seq} sent conflict resolution instructions to worker`, 'info');
|
|
529
|
+
actions.push({
|
|
530
|
+
action: 'conflict-worker',
|
|
531
|
+
entity: `seq:${seq}`,
|
|
532
|
+
result: 'ok',
|
|
533
|
+
message: 'Sent conflict resolution to worker, waiting for fix',
|
|
534
|
+
});
|
|
535
|
+
this.logEvent('conflict-worker', seq, 'ok');
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
540
|
+
this.log.error(`seq ${seq}: L2 conflict resolution failed: ${msg}`);
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// ─── Helpers ───────────────────────────────────────────────────
|
|
545
|
+
buildBranchName(card) {
|
|
546
|
+
const slug = card.name
|
|
547
|
+
.toLowerCase()
|
|
548
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
549
|
+
.replace(/^-|-$/g, '')
|
|
550
|
+
.slice(0, 40);
|
|
551
|
+
return `feature/${card.seq}-${slug}`;
|
|
552
|
+
}
|
|
553
|
+
async markNeedsFix(seq, reason) {
|
|
554
|
+
await this.addLabelSafe(seq, 'NEEDS-FIX');
|
|
555
|
+
await this.commentSafe(seq, `NEEDS-FIX: ${reason}`);
|
|
556
|
+
await this.notifySafe(`seq:${seq} marked NEEDS-FIX: ${reason}`, 'warning');
|
|
557
|
+
}
|
|
558
|
+
async addLabelSafe(seq, label) {
|
|
559
|
+
try {
|
|
560
|
+
await this.taskBackend.addLabel(seq, label);
|
|
561
|
+
}
|
|
562
|
+
catch (err) {
|
|
563
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
564
|
+
this.log.error(`Failed to add label ${label} to seq ${seq}: ${msg}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async commentSafe(seq, text) {
|
|
568
|
+
try {
|
|
569
|
+
await this.taskBackend.comment(seq, text);
|
|
570
|
+
}
|
|
571
|
+
catch (err) {
|
|
572
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
573
|
+
this.log.error(`Failed to comment on seq ${seq}: ${msg}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
async notifySafe(message, level) {
|
|
577
|
+
if (!this.notifier)
|
|
578
|
+
return;
|
|
579
|
+
try {
|
|
580
|
+
await this.notifier.send(`[${this.ctx.projectName}] ${message}`, level);
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
// Notification failures are never fatal
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
logEvent(action, seq, result, meta) {
|
|
587
|
+
this.log.event({
|
|
588
|
+
component: 'qa',
|
|
589
|
+
action,
|
|
590
|
+
entity: `seq:${seq}`,
|
|
591
|
+
result,
|
|
592
|
+
meta,
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
//# sourceMappingURL=CloseoutEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloseoutEngine.js","sourceRoot":"","sources":["../../src/engines/CloseoutEngine.ts"],"names":[],"mappings":"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"}
|