@ai-dev-methodologies/rlp-desk 0.16.0 → 0.18.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/CHANGELOG.md +54 -0
- package/docs/rlp-desk/getting-started.md +1 -1
- package/docs/rlp-desk/protocol-reference.md +1 -1
- package/package.json +5 -5
- package/scripts/uninstall.js +12 -0
- package/src/commands/rlp-desk.md +1 -1
- package/src/governance.md +20 -4
- package/src/node/run.mjs +25 -33
- package/src/node/runner/campaign-main-loop.mjs +1 -1
- package/src/scripts/.run_src_verify.zsh +3725 -0
- package/src/scripts/init_ralph_desk.zsh +4 -3
- package/src/scripts/lib_ralph_desk.zsh +126 -6
- package/src/scripts/run_ralph_desk.zsh +668 -126
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/context/loop-test-latest.md +0 -0
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/memos/loop-test-memory.md +0 -0
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/plans/prd-loop-test.md +0 -0
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/plans/test-spec-loop-test.md +0 -0
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/prompts/loop-test.verifier.prompt.md +0 -0
- /package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/prompts/loop-test.worker.prompt.md +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,60 @@ For pre-v0.15.4 versions, refer to `git log` and individual GitHub release notes
|
|
|
11
11
|
- Post-v0.15.6: remove `RLP_LIFECYCLE_METRICS` flag entirely (per plan v3 ADR follow-ups).
|
|
12
12
|
- Phase D.1 (handoff documents) + Phase D.2 (per-stage agent role specialization) — both deferred per `docs/plans/v0.15.4-release-runbook.md` §7.6.
|
|
13
13
|
|
|
14
|
+
## [0.18.0] — 2026-06-24
|
|
15
|
+
|
|
16
|
+
**Leader hardening: campaigns that complete.** The `--mode tmux` leader's decision
|
|
17
|
+
gates used to TERMINATE where they should RECOVER, so campaigns could stall at
|
|
18
|
+
`--max-iter` or block on a single transient slip. This release resolves that
|
|
19
|
+
"never completes" failure class.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- A single transient `blocked` verdict no longer ends the campaign. A fresh-context
|
|
23
|
+
Worker/Verifier mis-emitting `blocked` once now gets grace (soft-fail + retry);
|
|
24
|
+
termination only on a genuine infra failure or a repeated/consecutive block.
|
|
25
|
+
- Verifier phrasing variants (`completed`/`done`, lowercase `all`) no longer strand a
|
|
26
|
+
genuinely-complete campaign at the iteration cap — recommendation/us_id normalized at read.
|
|
27
|
+
- Mixed-engine dead-pane detection: a dead pane is detected per role when Worker and
|
|
28
|
+
Verifier run different engines (e.g. claude worker + codex verifier).
|
|
29
|
+
- No double-credit of a re-submitted User Story on the verify pass-path.
|
|
30
|
+
- Final verification now retries a single transient poll failure instead of charging a
|
|
31
|
+
false fail at the end of the campaign.
|
|
32
|
+
- Durable sentinels: atomic writes detect truncation (disk-full/SIGPIPE) instead of
|
|
33
|
+
renaming a half-written file into the canonical path.
|
|
34
|
+
- Race-safe locks: the runner-lock and per-slug lock close an ABA/empty-owner race that
|
|
35
|
+
could let two leaders run on one project root.
|
|
36
|
+
- Done-claim freshness gate: auto-synthesis rejects a stale/wrong-US done-claim, preventing
|
|
37
|
+
the wrong User Story from being credited.
|
|
38
|
+
- Model-upgrade state survives relaunch: a resumed campaign keeps the upgraded worker model
|
|
39
|
+
instead of resetting to the CLI default.
|
|
40
|
+
- codex 0.141 worker compatibility: the directory-trust prompt is accepted and MCP disabled
|
|
41
|
+
so codex workers don't block on startup.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- Stronger final verification: `--final-verifier-model` / `--final-verifier-effort` are now
|
|
45
|
+
actually used for the final ALL-verify pass (previously every verify ran at the per-US
|
|
46
|
+
model). "Final = stricter" now holds.
|
|
47
|
+
- Consensus cross-verifier model knobs now take effect: `--consensus-model` (per-US, lighter)
|
|
48
|
+
and `--final-consensus-model` (final, stricter) are wired into the consensus path —
|
|
49
|
+
previously documented but inert.
|
|
50
|
+
- Verifier FORMAT meta-gates softened cross-engine while correctness gates stay strict
|
|
51
|
+
(fewer false fails on phrasing, no weakening of substance).
|
|
52
|
+
|
|
53
|
+
## [0.17.0] — 2026-06-19
|
|
54
|
+
|
|
55
|
+
**BREAKING (ADR-001): `node run.mjs run <slug> --mode agent` (the deprecated Node-leader direct-CLI alpha) now hard-errors.** Per the schedule announced in 0.16.0, the `--mode agent` entry point exits 2 with a redirect, and the Node-CLI default mode flips from `agent` to `tmux` (the canonical production leader). The `src/node/**` engine modules are retained (they back the Native Agent() path and the test suite); only the direct-CLI `--mode agent` *dispatch entry* was removed. **Migration:** replace `node run.mjs run <slug> --mode agent` with `--mode tmux`. The slash command's `--mode native` default is unaffected.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- `node run.mjs run <slug>` (no `--mode`) now defaults to `--mode tmux` and delegates to the zsh leader, instead of the deprecated Node leader.
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
- Four shipped files referenced `docs/multi-mission-orchestration.md`; corrected to the real shipped path `docs/rlp-desk/multi-mission-orchestration.md` (dead link on fresh installs). Added a docs-link-resolve test.
|
|
62
|
+
- `uninstall` now removes the `UNLOCK.md` marker (and unlocks 0o444 files before unlink), so the `ralph-desk/` directory is fully removed.
|
|
63
|
+
- The A4 fallback iteration-signal write now goes through the atomic `atomic_write` helper (temp+rename) instead of a raw redirect.
|
|
64
|
+
|
|
65
|
+
### Changed (packaging)
|
|
66
|
+
- The shipped `examples/calculator` scaffold moved from the legacy `.claude/ralph-desk/` path to `.rlp-desk/` (v0.13.0+ convention) and no longer ships generated runtime state.
|
|
67
|
+
|
|
14
68
|
## [0.16.0] — 2026-06-18
|
|
15
69
|
|
|
16
70
|
Leader consolidation (ADR-001): `--mode tmux` is now the canonical production leader, self-verification works on it, and the deprecated `--mode agent` Node-CLI path is on a dated removal schedule.
|
|
@@ -83,7 +83,7 @@ This creates the scaffold:
|
|
|
83
83
|
|
|
84
84
|
## Step 5: Customize the PRD
|
|
85
85
|
|
|
86
|
-
Edit `.rlp-desk/plans/prd-loop-test.md` to define your user stories and acceptance criteria. See [`examples/calculator/`](../examples/calculator/.
|
|
86
|
+
Edit `.rlp-desk/plans/prd-loop-test.md` to define your user stories and acceptance criteria. See [`examples/calculator/`](../examples/calculator/.rlp-desk/plans/prd-loop-test.md) for a complete example.
|
|
87
87
|
|
|
88
88
|
Key sections:
|
|
89
89
|
- **User Stories** with Given/When/Then acceptance criteria, Task Type, and Risk Level
|
|
@@ -649,5 +649,5 @@ an optional `next_mission_candidate` field:
|
|
|
649
649
|
|
|
650
650
|
The leader propagates the field into `status.json`
|
|
651
651
|
(`status.next_mission_candidate`). Wrappers poll either source. See
|
|
652
|
-
`docs/multi-mission-orchestration.md` for the consumer-side polling
|
|
652
|
+
`docs/rlp-desk/multi-mission-orchestration.md` for the consumer-side polling
|
|
653
653
|
pattern.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-dev-methodologies/rlp-desk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Fresh-context iterative loops for Claude Code — autonomous task completion with independent verification",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"postinstall": "node scripts/postinstall.js",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"scripts/",
|
|
24
24
|
"docs/rlp-desk/*.md",
|
|
25
25
|
"docs/rlp-desk/blueprints/",
|
|
26
|
-
"examples/calculator/.
|
|
27
|
-
"examples/calculator/.
|
|
28
|
-
"examples/calculator/.
|
|
29
|
-
"examples/calculator/.
|
|
26
|
+
"examples/calculator/.rlp-desk/context/",
|
|
27
|
+
"examples/calculator/.rlp-desk/memos/",
|
|
28
|
+
"examples/calculator/.rlp-desk/plans/",
|
|
29
|
+
"examples/calculator/.rlp-desk/prompts/",
|
|
30
30
|
"install.sh",
|
|
31
31
|
"README.md",
|
|
32
32
|
"CHANGELOG.md",
|
package/scripts/uninstall.js
CHANGED
|
@@ -25,10 +25,22 @@ const files = [
|
|
|
25
25
|
path.join(deskDir, "init_ralph_desk.zsh"),
|
|
26
26
|
path.join(deskDir, "run_ralph_desk.zsh"),
|
|
27
27
|
path.join(deskDir, "lib_ralph_desk.zsh"),
|
|
28
|
+
// PKG-6: postinstall writes the UNLOCK.md escape-hatch doc into deskDir. If we
|
|
29
|
+
// skip it here, the empty-dir rmdir below always sees one leftover file and the
|
|
30
|
+
// ralph-desk/ directory is never removed.
|
|
31
|
+
path.join(deskDir, "UNLOCK.md"),
|
|
28
32
|
];
|
|
29
33
|
|
|
30
34
|
for (const targetPath of files) {
|
|
31
35
|
try {
|
|
36
|
+
// Installed files are write-locked (chmod 0o444) per postinstall v5.7 §4.10.
|
|
37
|
+
// Restore write permission before unlink so removal is robust across
|
|
38
|
+
// filesystems (mirrors postinstall's unlock-before-remove).
|
|
39
|
+
try {
|
|
40
|
+
fs.chmodSync(targetPath, 0o644);
|
|
41
|
+
} catch (_) {
|
|
42
|
+
// File may be missing or already writable.
|
|
43
|
+
}
|
|
32
44
|
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
33
45
|
console.log(" - " + targetPath);
|
|
34
46
|
} catch (_) {
|
package/src/commands/rlp-desk.md
CHANGED
|
@@ -374,7 +374,7 @@ This contract MUST be observed in every iteration of the leader loop below. Futu
|
|
|
374
374
|
|
|
375
375
|
#### Direct Node CLI invocation (`node run.mjs run <slug> --mode agent` — deprecated alpha)
|
|
376
376
|
|
|
377
|
-
Direct invocation of `node ~/.claude/ralph-desk/node/run.mjs run <slug> --mode agent`
|
|
377
|
+
Direct invocation of `node ~/.claude/ralph-desk/node/run.mjs run <slug> --mode agent` **hard-errors (exit 2) as of this release** (per [ADR-001](../../docs/plans/adr-001-leader-consolidation.md) §3) — it was the deprecated Node-leader alpha path, and the dated breaking change has now landed. Direct CLI invocation redirects to `--mode tmux` (production) / `--mode native` (slash), and the **Node-CLI default mode is now `tmux`**. This is unrelated to the slash command's legacy `--mode agent` → native redirect — different code, different leader, different lifecycle. The `src/node/**` engine modules (which still back the Native Agent() path and the test suite, and retain SV/flywheel implementations not yet ported to Native Agent()) are **retained** — only the direct-CLI `--mode agent` *entry point* hard-errors. For production tmux orchestration, use `--mode tmux` (the **canonical** leader). For Claude Code Native Agent() campaigns, use `/rlp-desk run <slug> --mode native` from a Claude Code session.
|
|
378
378
|
|
|
379
379
|
**Deprecation schedule** (per [ADR-001](../../docs/plans/adr-001-leader-consolidation.md) §3 — applies to the Node-CLI `--mode agent` entry point ONLY; the `src/node/**` engine modules are retained throughout):
|
|
380
380
|
|
package/src/governance.md
CHANGED
|
@@ -66,9 +66,25 @@ Verification layers:
|
|
|
66
66
|
- L3: E2E Simulation — known input → full pipeline → output comparison. Always required.
|
|
67
67
|
- L4: Deploy Verify — production environment checks. Required when deploying.
|
|
68
68
|
|
|
69
|
-
Layer requirements per US are determined by risk classification (§1c).
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
Layer requirements per US are determined by risk classification (§1c). Layer
|
|
70
|
+
completeness means ACTUAL verification COVERAGE, not test-spec FORMAT: a required
|
|
71
|
+
layer is satisfied when its behavior is genuinely exercised by a concrete, PASSING
|
|
72
|
+
check — e.g. a per-AC command in the Criteria→Verification table counts as L1/L3
|
|
73
|
+
coverage. Explicit "## L1/L2/L3" section headers and "N/A — {reason}" markers are
|
|
74
|
+
recommended but NOT mandatory, and their absence is NOT itself a fail.
|
|
75
|
+
FAIL a required layer ONLY when its verification is genuinely absent, blank, TODO,
|
|
76
|
+
or failing — never merely for a different-but-adequate test-spec format, a missing
|
|
77
|
+
N/A marker, or RED evidence aggregated across the US instead of recorded per-AC.
|
|
78
|
+
The iter-signal.json only identifies WHICH US to verify; whether the Worker wrote
|
|
79
|
+
it or the leader synthesized it does not change the verdict — verify the work, not
|
|
80
|
+
the signal's author. Deliverable COMPLETENESS is NOT exempt: if the work an AC
|
|
81
|
+
requires is absent, uncommitted/untracked, or never actually exercised, the layer
|
|
82
|
+
still FAILs. This rule is IDENTICAL for every verifier engine (claude AND codex):
|
|
83
|
+
do NOT block a PASS on test-spec FORMAT when the acceptance criteria are met and
|
|
84
|
+
their checks are green — but DO fail on missing or unverified substance. This
|
|
85
|
+
preserves strict AC + real layer coverage (IL-4 still governs test sufficiency);
|
|
86
|
+
it removes only format pedantry, never substance — the F-17 cross-engine
|
|
87
|
+
consistency fix (scope narrowed to format-only per the F-18 review).
|
|
72
88
|
See §1d for full layer definitions.
|
|
73
89
|
|
|
74
90
|
**IL-4: Test Sufficiency**
|
|
@@ -584,7 +600,7 @@ for iteration in 1..max_iter:
|
|
|
584
600
|
⑥½ Flywheel direction review (when --flywheel on-fail and consecutive_failures > 0)
|
|
585
601
|
- Dispatch Flywheel agent (fresh context, --flywheel-model)
|
|
586
602
|
- Read flywheel-signal.json for direction decision (hold/pivot/reduce/expand)
|
|
587
|
-
- Optional `next_mission_candidate` field (string | null): when present, the leader propagates it to status.json so consumer wrappers can chain the next mission without code edits. See docs/multi-mission-orchestration.md.
|
|
603
|
+
- Optional `next_mission_candidate` field (string | null): when present, the leader propagates it to status.json so consumer wrappers can chain the next mission without code edits. See docs/rlp-desk/multi-mission-orchestration.md.
|
|
588
604
|
- If --flywheel-guard on:
|
|
589
605
|
- Dispatch Guard agent (fresh context, --flywheel-guard-model)
|
|
590
606
|
- Read flywheel-guard-verdict.json:
|
package/src/node/run.mjs
CHANGED
|
@@ -14,7 +14,11 @@ import {
|
|
|
14
14
|
import { isClaudeEngine } from './cli/command-builder.mjs';
|
|
15
15
|
|
|
16
16
|
const RUN_DEFAULTS = {
|
|
17
|
-
|
|
17
|
+
// ARCH Wave D (ADR-001 §3): the Node-CLI default mode flips from the deprecated
|
|
18
|
+
// 'agent' (Node-leader alpha) to 'tmux' (the canonical production leader) at the
|
|
19
|
+
// same step that makes --mode agent hard-error. A bare `run <slug>` now delegates
|
|
20
|
+
// to the zsh runner, not the deprecated Node leader.
|
|
21
|
+
mode: 'tmux',
|
|
18
22
|
workerModel: 'haiku',
|
|
19
23
|
verifierModel: 'sonnet',
|
|
20
24
|
finalVerifierModel: 'opus',
|
|
@@ -49,14 +53,14 @@ function buildHelpText() {
|
|
|
49
53
|
'Commands:',
|
|
50
54
|
' brainstorm <description> Plan before init (not implemented in the Node rewrite yet)',
|
|
51
55
|
' init <slug> [objective] Create project scaffold',
|
|
52
|
-
' run <slug> [options] Run loop (tmux=zsh leader [production], agent=
|
|
56
|
+
' run <slug> [options] Run loop (tmux=zsh leader [production, default], agent=hard-errors per ADR-001, native=slash-only error)',
|
|
53
57
|
' status <slug> Show loop status',
|
|
54
58
|
' logs <slug> [N] Show iteration log (not implemented in the Node rewrite yet)',
|
|
55
59
|
' clean <slug> [--kill-session] Reset for re-run (removes sentinels + runtime/; preserves PRD/prompts/memory)',
|
|
56
60
|
' resume <slug> Resume loop (not implemented in the Node rewrite yet)',
|
|
57
61
|
'',
|
|
58
62
|
'Run Options:',
|
|
59
|
-
' --mode tmux|agent|native (CLI: tmux=production, agent=
|
|
63
|
+
' --mode tmux|agent|native (CLI: tmux=production [default], agent=hard-errors (ADR-001), native=errors with redirect to slash command)',
|
|
60
64
|
' --worker-model MODEL',
|
|
61
65
|
' --lock-worker-model',
|
|
62
66
|
' --verifier-model MODEL',
|
|
@@ -373,7 +377,7 @@ async function runTmuxViaZsh(slug, options, deps) {
|
|
|
373
377
|
if (unsupported.length > 0) {
|
|
374
378
|
write(
|
|
375
379
|
deps.stderr,
|
|
376
|
-
`WARNING: ${unsupported.join(', ')} not honored in --mode tmux (zsh runner). Flywheel is deprecated (ADR-001)
|
|
380
|
+
`WARNING: ${unsupported.join(', ')} not honored in --mode tmux (zsh runner). Flywheel is deprecated (ADR-001) and unimplemented in the canonical leader.`,
|
|
377
381
|
);
|
|
378
382
|
}
|
|
379
383
|
|
|
@@ -442,7 +446,7 @@ async function runRunCommand(args, deps) {
|
|
|
442
446
|
);
|
|
443
447
|
write(
|
|
444
448
|
deps.stderr,
|
|
445
|
-
'If hang persists, switch to --worker-model gpt-5.5:high (codex)
|
|
449
|
+
'If hang persists, switch to --worker-model gpt-5.5:high (codex).',
|
|
446
450
|
);
|
|
447
451
|
}
|
|
448
452
|
|
|
@@ -468,50 +472,38 @@ async function runRunCommand(args, deps) {
|
|
|
468
472
|
);
|
|
469
473
|
write(
|
|
470
474
|
deps.stderr,
|
|
471
|
-
'or use `--mode tmux` (production)
|
|
475
|
+
'or use `--mode tmux` (production) for direct CLI invocation. `--mode agent` hard-errors (ADR-001).',
|
|
472
476
|
);
|
|
473
477
|
return 2;
|
|
474
478
|
}
|
|
475
479
|
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
) {
|
|
486
|
-
write(
|
|
487
|
-
deps.stderr,
|
|
488
|
-
'WARNING: --mode agent (Node-leader alpha) is deprecated.',
|
|
489
|
-
);
|
|
480
|
+
// ARCH Wave D (ADR-001 §3): --mode agent (Node-leader direct-CLI alpha) HARD-ERRORS
|
|
481
|
+
// as of this release. It is the dated breaking change the deprecation banner
|
|
482
|
+
// announced — direct CLI invocation now exits 2 with a redirect to the canonical
|
|
483
|
+
// production leader (--mode tmux) or the slash-command Native Agent() path
|
|
484
|
+
// (--mode native). This is UNRELATED to the slash command's legacy `--mode agent`
|
|
485
|
+
// → native redirect (different code, different leader). The `src/node/**` engine
|
|
486
|
+
// modules (run()/runCampaign) are RETAINED — they remain the engine the Native
|
|
487
|
+
// Agent() path and the test suite build on; only this direct-CLI dispatch entry
|
|
488
|
+
// hard-errors. Mirror the --mode native slash-only exit-2 pattern above.
|
|
489
|
+
if (options.mode === 'agent') {
|
|
490
490
|
write(
|
|
491
491
|
deps.stderr,
|
|
492
|
-
'
|
|
492
|
+
'ERROR: --mode agent (Node-leader direct-CLI alpha) is no longer supported (ADR-001).',
|
|
493
493
|
);
|
|
494
494
|
write(
|
|
495
495
|
deps.stderr,
|
|
496
|
-
'For production tmux orchestration, use `--mode tmux
|
|
496
|
+
'For production tmux orchestration, use `--mode tmux` (the canonical leader).',
|
|
497
497
|
);
|
|
498
498
|
write(
|
|
499
499
|
deps.stderr,
|
|
500
|
-
'For Claude Code Native Agent() campaigns, use `/rlp-desk run --mode native` from a Claude Code session.',
|
|
500
|
+
'For Claude Code Native Agent() campaigns, use `/rlp-desk run <slug> --mode native` from a Claude Code session.',
|
|
501
501
|
);
|
|
502
|
-
// 2026-05-07 (v0.15.2): rlp-desk is in active stabilization. Goal: reach
|
|
503
|
-
// omc /team/ralph/ralplan level of reliability while preserving
|
|
504
|
-
// rlp-desk's self-driving advantages (multi-engine consensus, multi-mission
|
|
505
|
-
// queue, BLOCK_TAGS taxonomy, structured SV reports). omc is the BENCHMARK,
|
|
506
|
-
// not a replacement. See docs/plans/v0.15-stabilization-plan.md.
|
|
507
502
|
write(
|
|
508
503
|
deps.stderr,
|
|
509
|
-
'
|
|
510
|
-
);
|
|
511
|
-
write(
|
|
512
|
-
deps.stderr,
|
|
513
|
-
'STABILIZATION IN PROGRESS: rlp-desk is hardening against the 10-bug regression pattern observed 2026-05-01..05-07. See docs/plans/v0.15-stabilization-plan.md.',
|
|
504
|
+
'The src/node/** engine modules are retained; only the direct-CLI --mode agent entry point was removed.',
|
|
514
505
|
);
|
|
506
|
+
return 2;
|
|
515
507
|
}
|
|
516
508
|
|
|
517
509
|
const result = await deps.runCampaign(slug, options);
|
|
@@ -1715,7 +1715,7 @@ async function _runCampaignBody(slug, options, paths, rootDir) {
|
|
|
1715
1715
|
// P0-A multi-mission orchestration: optionally captured from flywheel signal.
|
|
1716
1716
|
// null when the flywheel did not suggest a next mission. Consumer wrappers
|
|
1717
1717
|
// poll status.next_mission_candidate to chain missions without code edits.
|
|
1718
|
-
// See docs/multi-mission-orchestration.md.
|
|
1718
|
+
// See docs/rlp-desk/multi-mission-orchestration.md.
|
|
1719
1719
|
state.next_mission_candidate = flywheelSignal.next_mission_candidate ?? null;
|
|
1720
1720
|
// Bug #7 Fix-R cleanup: unlock before unlink so 0o444 doesn't block.
|
|
1721
1721
|
await unlockSentinelFile(paths.flywheelSignalFile);
|