@ai-dev-methodologies/rlp-desk 0.16.0 → 0.17.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 +15 -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 +1 -1
- package/src/node/run.mjs +25 -33
- package/src/node/runner/campaign-main-loop.mjs +1 -1
- package/src/scripts/init_ralph_desk.zsh +1 -1
- package/src/scripts/lib_ralph_desk.zsh +12 -3
- package/src/scripts/run_ralph_desk.zsh +8 -2
- /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,21 @@ 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.17.0] — 2026-06-19
|
|
15
|
+
|
|
16
|
+
**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.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- `node run.mjs run <slug>` (no `--mode`) now defaults to `--mode tmux` and delegates to the zsh leader, instead of the deprecated Node leader.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- 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.
|
|
23
|
+
- `uninstall` now removes the `UNLOCK.md` marker (and unlocks 0o444 files before unlink), so the `ralph-desk/` directory is fully removed.
|
|
24
|
+
- The A4 fallback iteration-signal write now goes through the atomic `atomic_write` helper (temp+rename) instead of a raw redirect.
|
|
25
|
+
|
|
26
|
+
### Changed (packaging)
|
|
27
|
+
- 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.
|
|
28
|
+
|
|
14
29
|
## [0.16.0] — 2026-06-18
|
|
15
30
|
|
|
16
31
|
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.17.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
|
@@ -584,7 +584,7 @@ for iteration in 1..max_iter:
|
|
|
584
584
|
⑥½ Flywheel direction review (when --flywheel on-fail and consecutive_failures > 0)
|
|
585
585
|
- Dispatch Flywheel agent (fresh context, --flywheel-model)
|
|
586
586
|
- 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.
|
|
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/rlp-desk/multi-mission-orchestration.md.
|
|
588
588
|
- If --flywheel-guard on:
|
|
589
589
|
- Dispatch Guard agent (fresh context, --flywheel-guard-model)
|
|
590
590
|
- 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);
|
|
@@ -761,7 +761,7 @@ Based on your decision, update campaign memory:
|
|
|
761
761
|
current direction. The wrapper polls this field for autonomous
|
|
762
762
|
multi-mission orchestration (rlp-desk does not auto-launch missions —
|
|
763
763
|
the consumer wrapper owns that policy). Field is OPTIONAL; absence is
|
|
764
|
-
treated as null. See docs/multi-mission-orchestration.md for the
|
|
764
|
+
treated as null. See docs/rlp-desk/multi-mission-orchestration.md for the
|
|
765
765
|
consumer-side polling pattern.
|
|
766
766
|
FLYWHEEL_EOF
|
|
767
767
|
|
|
@@ -756,9 +756,18 @@ _lint_test_density() {
|
|
|
756
756
|
us_list=$(grep -oE '^##[[:space:]]+US-[0-9]+' "$prd_file" 2>/dev/null | grep -oE 'US-[0-9]+' | sort -u)
|
|
757
757
|
[[ -z "$us_list" ]] && return 0
|
|
758
758
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
759
|
+
# ZSH-8: prefer the campaign LOGS_DIR. When it is unavailable, avoid a fixed,
|
|
760
|
+
# predictable /tmp name (insecure-temp: symlink/collision risk) by creating a
|
|
761
|
+
# unique temp file via mktemp; fall back to a PID-scoped name only if mktemp
|
|
762
|
+
# is missing.
|
|
763
|
+
local audit_dir="${LOGS_DIR:-}"
|
|
764
|
+
local audit_file
|
|
765
|
+
if [[ -n "$audit_dir" && -d "$audit_dir" ]]; then
|
|
766
|
+
audit_file="$audit_dir/test-density-audit.jsonl"
|
|
767
|
+
else
|
|
768
|
+
audit_file=$(mktemp "${TMPDIR:-/tmp}/test-density-audit.XXXXXX" 2>/dev/null) \
|
|
769
|
+
|| audit_file="${TMPDIR:-/tmp}/test-density-audit.$$.jsonl"
|
|
770
|
+
fi
|
|
762
771
|
|
|
763
772
|
local us
|
|
764
773
|
for us in ${(f)us_list}; do
|
|
@@ -2311,7 +2311,7 @@ poll_for_signal() {
|
|
|
2311
2311
|
# done-claim and a fresh signal_file in that order.
|
|
2312
2312
|
_kill_pane_process "$pane_id" "worker-a4"
|
|
2313
2313
|
_lock_sentinel "$DONE_CLAIM_FILE"
|
|
2314
|
-
echo '{"iteration":'"$ITERATION"',"status":"verify","us_id":"'"$dc_us_id"'","summary":"auto-generated by A4 fallback (done-claim + clean tree)","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}'
|
|
2314
|
+
echo '{"iteration":'"$ITERATION"',"status":"verify","us_id":"'"$dc_us_id"'","summary":"auto-generated by A4 fallback (done-claim + clean tree)","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}' | atomic_write "$signal_file"
|
|
2315
2315
|
_emit_a4_fallback_audit "$dc_us_id" "$ITERATION" "inline_polling_a4_clean"
|
|
2316
2316
|
return 0
|
|
2317
2317
|
else
|
|
@@ -2885,7 +2885,13 @@ main() {
|
|
|
2885
2885
|
log_error "Another instance is already running (PID $lock_pid). Kill $lock_pid or rm $lockfile"
|
|
2886
2886
|
exit 1
|
|
2887
2887
|
fi
|
|
2888
|
-
# Stale lock — overwrite
|
|
2888
|
+
# Stale lock — overwrite.
|
|
2889
|
+
# NOTE (ZSH-4, deferred): a fully race-safe stale-lock recovery is a separate
|
|
2890
|
+
# distributed-lock redesign (codex review found subtle rm/create + mutex-leak
|
|
2891
|
+
# races in patch attempts). This finding is LOW: the outer RUNNER_LOCKDIR mkdir
|
|
2892
|
+
# lock (keyed on the same $ROOT) already serializes runners before this inner
|
|
2893
|
+
# path is reached, so the inner race is unreachable in practice. Left at the
|
|
2894
|
+
# tested baseline pending a dedicated redesign.
|
|
2889
2895
|
log "Stale lock detected (PID ${lock_pid:-unknown} not running), recovering"
|
|
2890
2896
|
echo $$ > "$lockfile"
|
|
2891
2897
|
LOCKFILE_ACQUIRED=1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/prompts/loop-test.verifier.prompt.md
RENAMED
|
File without changes
|
/package/examples/calculator/{.claude/ralph-desk → .rlp-desk}/prompts/loop-test.worker.prompt.md
RENAMED
|
File without changes
|