fix(execute): clear the wave record only on the main-merge gate's confirm (green)
1. Step 6 cleared the orders dir before Phase 8's main-merge gate asked,
so a declined gate lost the merged-waves record and the next run
prepared wave 1 again on merged code. The clear now sits only under
the gate's "On confirm" (wave path, next-wave none, Step 4 passed);
Step 6 and a declined gate keep the record, so a re-run goes
next-wave none -> Step 4 -> back to the gate.
2. The gate's Decline row and Recovery surface now say what holds on the
wave path: the waves are already merged on the current branch,
nothing is finalized, the record is kept, and re-running the same
command (not --resume, which Phase 2.5 runs as a single session)
re-runs master verification and returns to the gate. The branch name
is trek/{slug}/session-N; the push-before-cleanup note now holds only
where the push succeeded. The single-session --resume line stays.
3. The report footer adds the multi-session way to continue.
4. wave.json stores the branch the wave was prepared on (write
--branch); Step 3's status call passes the current branch and stops,
touching nothing, when the main checkout is on another branch.
npm test: 1277 tests, 1275 pass, 0 fail, 2 skipped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d9e091c143
commit
d70e3d2af7
2 changed files with 72 additions and 45 deletions
|
|
@ -6,12 +6,13 @@
|
|||
// only reads the plan, writes order files and reads progress files.
|
||||
//
|
||||
// Subcommands (CLI shim at the bottom):
|
||||
// write --plan <repo-relative plan> --wave <W> --session-dir <dir>
|
||||
// write --plan <repo-relative plan> --wave <W> --session-dir <dir> [--branch <b>]
|
||||
// writes <dir>/orders/wave-<W>-session-<N>.md + <dir>/orders/wave.json
|
||||
// and prints the starters
|
||||
// status --plan <repo-relative plan> --wave <W> --session-dir <dir>
|
||||
// (with the branch the wave is prepared on) and prints the starters
|
||||
// status --plan <repo-relative plan> --wave <W> --session-dir <dir> [--branch <b>]
|
||||
// prints JSON: each session's raw progress-file status and its state
|
||||
// (completed | running | ended-bad), running, ended_bad, all_completed
|
||||
// (completed | running | ended-bad), running, ended_bad, all_completed;
|
||||
// refuses when the main checkout is on another branch than wave.json's
|
||||
// archive --plan <repo-relative plan> --wave <W> --session-dir <dir>
|
||||
// copies each progress file to <dir>/orders/wave-<W>-session-<N>.progress.json
|
||||
// (the worktree copy goes with the worktree)
|
||||
|
|
@ -164,13 +165,13 @@ export function buildWaveOrders({ strategy, wave, planPath, sessionDir }) {
|
|||
});
|
||||
}
|
||||
|
||||
export function writeWaveOrders({ strategy, wave, planPath, planSha256, sessionDir, now = new Date() }) {
|
||||
export function writeWaveOrders({ strategy, wave, planPath, planSha256, branch = null, sessionDir, now = new Date() }) {
|
||||
const orders = buildWaveOrders({ strategy, wave, planPath, sessionDir });
|
||||
const dir = join(sessionDir, 'orders');
|
||||
mkdirSync(dir, { recursive: true });
|
||||
for (const o of orders) writeFileSync(join(dir, o.orderFile), o.body);
|
||||
const state = {
|
||||
wave, plan: planPath, plan_sha256: planSha256, sessions: orders.map(o => o.session),
|
||||
wave, plan: planPath, plan_sha256: planSha256, original_branch: branch, sessions: orders.map(o => o.session),
|
||||
status: 'awaiting-sessions', created_at: now.toISOString(),
|
||||
};
|
||||
writeFileSync(join(dir, 'wave.json'), JSON.stringify(state, null, 2) + '\n');
|
||||
|
|
@ -196,11 +197,16 @@ function samePlan(file, rec, planPath, planSha256, what) {
|
|||
+ `not ${planPath} (plan sha256 ${short(planSha256)})`);
|
||||
}
|
||||
|
||||
export function waveStatus({ strategy, wave, planPath, planSha256, sessionDir }) {
|
||||
export function waveStatus({ strategy, wave, planPath, planSha256, branch = null, sessionDir }) {
|
||||
const waveFile = join(sessionDir, 'orders', 'wave.json');
|
||||
if (existsSync(waveFile)) {
|
||||
samePlan(waveFile, JSON.parse(readFileSync(waveFile, 'utf-8')), planPath, planSha256,
|
||||
'was written for another plan or another version of it:');
|
||||
const state = JSON.parse(readFileSync(waveFile, 'utf-8'));
|
||||
samePlan(waveFile, state, planPath, planSha256, 'was written for another plan or another version of it:');
|
||||
// The wave merges back into the branch it was prepared on, nowhere else.
|
||||
if (state.original_branch && state.original_branch !== branch) {
|
||||
throw new Error(`the wave in ${waveFile} was prepared on branch ${state.original_branch}, `
|
||||
+ `but the main checkout is on ${branch || 'an unnamed branch'}. Switch back to ${state.original_branch} and re-run.`);
|
||||
}
|
||||
}
|
||||
const members = strategy.sessions.filter(s => s.wave === wave);
|
||||
if (members.length === 0) throw new Error(`no sessions in wave ${wave}`);
|
||||
|
|
@ -285,6 +291,7 @@ function parseArgs(argv) {
|
|||
if (a === '--plan') out.plan = argv[++i];
|
||||
else if (a === '--wave') out.wave = Number(argv[++i]);
|
||||
else if (a === '--session-dir') out.sessionDir = argv[++i];
|
||||
else if (a === '--branch') out.branch = argv[++i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
@ -296,7 +303,7 @@ const NEEDS = {
|
|||
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const usage = 'usage: session-orders.mjs write|status|archive|record-merged --plan <repo-relative plan> --wave <W> --session-dir <dir>\n'
|
||||
const usage = 'usage: session-orders.mjs write|status|archive|record-merged --plan <repo-relative plan> --wave <W> --session-dir <dir> [--branch <b>]\n'
|
||||
+ ' session-orders.mjs next-wave --plan <repo-relative plan> --session-dir <dir>\n'
|
||||
+ ' session-orders.mjs clear --session-dir <dir>';
|
||||
const needs = NEEDS[args.cmd];
|
||||
|
|
@ -312,7 +319,7 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|||
const planBytes = readFileSync(args.plan);
|
||||
const strategy = parseExecutionStrategy(planBytes.toString('utf-8'));
|
||||
const planSha256 = createHash('sha256').update(planBytes).digest('hex');
|
||||
const opts = { strategy, wave: args.wave, planPath: args.plan, planSha256, sessionDir: args.sessionDir };
|
||||
const opts = { strategy, wave: args.wave, planPath: args.plan, planSha256, branch: args.branch || null, sessionDir: args.sessionDir };
|
||||
if (args.cmd === 'status') {
|
||||
process.stdout.write(JSON.stringify(waveStatus(opts), null, 2) + '\n');
|
||||
} else if (args.cmd === 'archive') {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue