@ai-dev-methodologies/rlp-desk 0.7.4 → 0.8.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/README.md +58 -0
- package/docs/blueprints/blueprint-pivot-step.md +137 -0
- package/package.json +5 -2
- package/scripts/postinstall.js +91 -51
- package/scripts/uninstall.js +18 -9
- package/src/commands/rlp-desk.md +0 -2
- package/src/governance.md +1 -0
- package/src/node/cli/command-builder.mjs +96 -0
- package/src/node/init/campaign-initializer.mjs +235 -0
- package/src/node/polling/signal-poller.mjs +106 -0
- package/src/node/prompts/prompt-assembler.mjs +213 -0
- package/src/node/reporting/campaign-reporting.mjs +257 -0
- package/src/node/run.mjs +234 -0
- package/src/node/runner/campaign-main-loop.mjs +624 -0
- package/src/node/shared/fs.mjs +23 -0
- package/src/node/shared/paths.mjs +28 -0
- package/src/node/tmux/pane-manager.mjs +77 -0
- package/docs/blueprints/blueprint-v0.4-evolution.md +0 -347
- package/docs/prompts/ralplan-codex-review.md +0 -55
- package/docs/superpowers/plans/2026-04-06-worker-verifier-prompt-restructure.md +0 -179
- package/src/scripts/init_ralph_desk.zsh +0 -885
- package/src/scripts/lib_ralph_desk.zsh +0 -890
- package/src/scripts/run_ralph_desk.zsh +0 -2678
package/README.md
CHANGED
|
@@ -399,6 +399,64 @@ Per-US catches issues early before later stories build on broken foundations.
|
|
|
399
399
|
|
|
400
400
|
Worker completes all stories, then a single verification checks all AC at once. Final verify still applies.
|
|
401
401
|
|
|
402
|
+
## Autonomous Mode
|
|
403
|
+
|
|
404
|
+
By default, Worker and Verifier stop and ask for human input when they encounter document conflicts (e.g., PRD says one thing, test-spec says another) or ambiguous instructions. This breaks unattended execution.
|
|
405
|
+
|
|
406
|
+
**`--autonomous`** enables fully unattended campaigns:
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
/rlp-desk run my-feature --mode tmux --worker-model gpt-5.4:medium --autonomous --debug
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### How it works
|
|
413
|
+
|
|
414
|
+
When `--autonomous` is active:
|
|
415
|
+
|
|
416
|
+
1. **PRD is the single source of truth.** Resolution priority: `PRD > test-spec > context > memory`
|
|
417
|
+
2. **No stopping for questions.** Worker and Verifier make autonomous decisions based on the priority chain
|
|
418
|
+
3. **All conflicts are logged.** Every decision is recorded in `conflict-log.jsonl` for post-campaign review
|
|
419
|
+
|
|
420
|
+
### Conflict log
|
|
421
|
+
|
|
422
|
+
Each conflict is logged as a JSONL entry in `logs/<slug>/conflict-log.jsonl`:
|
|
423
|
+
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"iteration": 1,
|
|
427
|
+
"us_id": "US-001",
|
|
428
|
+
"source_a": "worker-prompt",
|
|
429
|
+
"source_b": "prd",
|
|
430
|
+
"conflict": "US-00 is required by the iteration prompt but is not defined as a PRD user story.",
|
|
431
|
+
"resolution": "Followed PRD as source of truth."
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### When to use
|
|
436
|
+
|
|
437
|
+
- **Long-running campaigns** that run overnight or while you're away
|
|
438
|
+
- **High-iteration tasks** where stopping for every ambiguity wastes hours
|
|
439
|
+
- **Well-defined PRDs** where the PRD is comprehensive and authoritative
|
|
440
|
+
|
|
441
|
+
### When NOT to use
|
|
442
|
+
|
|
443
|
+
- **Exploratory work** where you want to review each decision
|
|
444
|
+
- **Ambiguous PRDs** where conflicts indicate real design gaps that need human judgment
|
|
445
|
+
- **First run of a new project** — run without `--autonomous` first to catch PRD issues interactively
|
|
446
|
+
|
|
447
|
+
### Post-campaign review
|
|
448
|
+
|
|
449
|
+
After the campaign, review the conflict log to identify systemic issues:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
cat .claude/ralph-desk/logs/<slug>/conflict-log.jsonl | jq .
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Common patterns:
|
|
456
|
+
- **Repeated PRD vs test-spec conflicts** — test-spec needs updating to match PRD
|
|
457
|
+
- **Scope lock vs fix contract conflicts** — governance rules may need tuning
|
|
458
|
+
- **Missing PRD definitions** — Worker created stories not in the PRD (add them or tighten the brainstorm)
|
|
459
|
+
|
|
402
460
|
## Project Structure
|
|
403
461
|
|
|
404
462
|
After `init`, your project gets this scaffold:
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Blueprint: Pivot Step (⑤½)
|
|
2
|
+
|
|
3
|
+
> Status: TODO — not yet implemented. Document for future development.
|
|
4
|
+
|
|
5
|
+
## Summary
|
|
6
|
+
|
|
7
|
+
Insert a Pivot Review step between Worker(⑤) and Verifier(⑦) in the Leader loop. Internalizes the core thinking framework from gstack's `plan-ceo-review` (premise challenge, forced alternatives, scope decisions) without depending on external skills.
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
When a Worker repeatedly fails on the same US, the fix loop retries the same approach with progressively stronger models. This works for implementation bugs but fails for **wrong approach** problems. The current CB threshold → BLOCKED pattern wastes iterations before admitting the approach is wrong.
|
|
12
|
+
|
|
13
|
+
## Proposed Solution
|
|
14
|
+
|
|
15
|
+
### New CLI Flags
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
--pivot-mode off|every|on-fail (default: off)
|
|
19
|
+
--pivot-model MODEL (default: opus)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `off`: no pivot review (current behavior)
|
|
23
|
+
- `every`: pivot review after every Worker iteration
|
|
24
|
+
- `on-fail`: pivot review only after Verifier fail verdict
|
|
25
|
+
|
|
26
|
+
### Leader Loop Change
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Current: ① → ② → ③ → ④ → ⑤ worker → ⑥ signal → ⑦ verifier → ⑧ result
|
|
30
|
+
Proposed: ① → ② → ③ → ③½ PIVOT → ④ → ⑤ worker → ⑥ signal → ⑦ verifier → ⑧ result
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Pivot runs BEFORE Worker — it decides direction, then Worker executes that direction.
|
|
34
|
+
|
|
35
|
+
### Tmux Pane Layout (3 panes)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
+------------------+------------------+------------------+
|
|
39
|
+
| Worker pane | Pivot pane | Verifier pane |
|
|
40
|
+
| claude/codex | claude (opus) | claude/codex |
|
|
41
|
+
| implements code | direction review | verifies result |
|
|
42
|
+
+------------------+------------------+------------------+
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pivot pane is reused each iteration (not persistent). Leader launches pivot → waits for memory update → launches Worker in Worker pane.
|
|
46
|
+
|
|
47
|
+
### ③½ Pivot Review Step
|
|
48
|
+
|
|
49
|
+
**Agent mode:**
|
|
50
|
+
```
|
|
51
|
+
Agent(
|
|
52
|
+
description="rlp-desk pivot review iter-NNN",
|
|
53
|
+
model=<pivot_model>,
|
|
54
|
+
mode="bypassPermissions",
|
|
55
|
+
prompt=<pivot_prompt>
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Tmux mode:**
|
|
60
|
+
- Dedicated pivot pane (3rd pane)
|
|
61
|
+
- `DISABLE_OMC=1 claude --model opus --mcp-config '{"mcpServers":{}}' --strict-mcp-config -p "$(cat pivot-prompt.md)"`
|
|
62
|
+
- After pivot completes, verify memory updated → build Worker prompt (④) → launch Worker (⑤)
|
|
63
|
+
|
|
64
|
+
### Pivot Review Responsibilities
|
|
65
|
+
|
|
66
|
+
1. **Analyze iteration result** — what did the Worker actually produce?
|
|
67
|
+
2. **Premise challenge** — is the current approach correct? What assumptions are we making?
|
|
68
|
+
3. **Forced alternatives** — propose minimum 2 alternative approaches
|
|
69
|
+
4. **Scope decision** — EXPAND (add scope), HOLD (keep current), REDUCE (simplify)
|
|
70
|
+
5. **Update campaign memory** — rewrite Next Iteration Contract if approach changes
|
|
71
|
+
6. **Record rejected directions** — prevent future iterations from revisiting dead ends
|
|
72
|
+
|
|
73
|
+
### Pivot Prompt Template (internalized from plan-ceo-review)
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
# Pivot Review — Iteration {N}
|
|
77
|
+
|
|
78
|
+
## Context
|
|
79
|
+
- Campaign: {slug}
|
|
80
|
+
- Current US: {us_id}
|
|
81
|
+
- Worker result: {done-claim summary}
|
|
82
|
+
- Consecutive failures on this US: {N}
|
|
83
|
+
- Previous pivot decisions: {from memory}
|
|
84
|
+
|
|
85
|
+
## Your Task
|
|
86
|
+
|
|
87
|
+
### 1. Premise Check
|
|
88
|
+
For each premise below, state whether evidence supports or contradicts it:
|
|
89
|
+
{list premises from PRD/memory}
|
|
90
|
+
|
|
91
|
+
### 2. Forced Alternatives
|
|
92
|
+
Propose at least 2 alternative approaches to the current US.
|
|
93
|
+
For each: summary, effort (S/M/L), risk, key tradeoff.
|
|
94
|
+
|
|
95
|
+
### 3. Scope Decision
|
|
96
|
+
Choose ONE: EXPAND | HOLD | REDUCE
|
|
97
|
+
Justify with evidence from this iteration.
|
|
98
|
+
|
|
99
|
+
### 4. Next Iteration Contract
|
|
100
|
+
If HOLD: refine the current contract with specific fixes.
|
|
101
|
+
If EXPAND/REDUCE: rewrite the contract for the new approach.
|
|
102
|
+
|
|
103
|
+
### 5. Rejected Directions
|
|
104
|
+
List approaches that should NOT be attempted again, with reason.
|
|
105
|
+
|
|
106
|
+
## Output
|
|
107
|
+
Update campaign memory at: {memory_path}
|
|
108
|
+
- Update "Next Iteration Contract" section
|
|
109
|
+
- Add to "Key Decisions" section
|
|
110
|
+
- Add to "Rejected Directions" section (if any)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Expected Benefits
|
|
114
|
+
|
|
115
|
+
- **Breaks fix loops** — "same approach, stronger model" → "different approach"
|
|
116
|
+
- **Research campaigns** — natural direction pivots without manual intervention
|
|
117
|
+
- **Reuses proven framework** — plan-ceo-review's premise challenge + forced alternatives
|
|
118
|
+
- **Both modes** — works in tmux and agent mode
|
|
119
|
+
|
|
120
|
+
## Implementation Notes
|
|
121
|
+
|
|
122
|
+
- `PIVOT_MODE` variable in `run_ralph_desk.zsh` (pattern: same as `AUTONOMOUS_MODE`)
|
|
123
|
+
- CLI parser: `--pivot-mode`, `--pivot-model` (pattern: same as other model flags)
|
|
124
|
+
- `write_pivot_prompt()` function in `run_ralph_desk.zsh` (pattern: same as `write_worker_trigger`)
|
|
125
|
+
- Pivot review output → campaign memory update (same file, different section)
|
|
126
|
+
- Status.json: add `pivot_decisions` array for tracking
|
|
127
|
+
- Analytics: `campaign.jsonl` add `pivot_action` field per iteration
|
|
128
|
+
|
|
129
|
+
## Dependencies
|
|
130
|
+
|
|
131
|
+
- Requires `--autonomous` mode (pivot review must not stop for questions)
|
|
132
|
+
- Works with any Worker engine (Claude or Codex)
|
|
133
|
+
- Does not require gstack installation
|
|
134
|
+
|
|
135
|
+
## Priority
|
|
136
|
+
|
|
137
|
+
Medium — implement after v1.0 Node.js rewrite is stable. Current CB threshold + model upgrade handles most cases. Pivot step is for research/exploration campaigns where approach flexibility matters.
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-dev-methodologies/rlp-desk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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",
|
|
7
7
|
"uninstall": "node scripts/uninstall.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"src/",
|
|
10
|
+
"src/commands/",
|
|
11
|
+
"src/node/",
|
|
12
|
+
"src/governance.md",
|
|
13
|
+
"src/model-upgrade-table.md",
|
|
11
14
|
"scripts/",
|
|
12
15
|
"docs/",
|
|
13
16
|
"examples/",
|
package/scripts/postinstall.js
CHANGED
|
@@ -4,41 +4,19 @@
|
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const os = require("os");
|
|
7
|
-
const
|
|
7
|
+
const pkg = require(path.join(__dirname, "..", "package.json"));
|
|
8
8
|
|
|
9
9
|
const home = os.homedir();
|
|
10
10
|
const claudeDir = path.join(home, ".claude");
|
|
11
11
|
const commandsDir = path.join(claudeDir, "commands");
|
|
12
12
|
const deskDir = path.join(claudeDir, "ralph-desk");
|
|
13
|
-
const pkgDir = path.join(__dirname, "..");
|
|
14
|
-
const pkg = require(path.join(pkgDir, "package.json"));
|
|
15
|
-
|
|
16
|
-
console.log("");
|
|
17
|
-
console.log(" RLP Desk v" + pkg.version);
|
|
18
|
-
console.log(" ================");
|
|
19
|
-
console.log("");
|
|
20
|
-
|
|
21
|
-
// Create directories
|
|
22
|
-
fs.mkdirSync(commandsDir, { recursive: true });
|
|
23
|
-
fs.mkdirSync(deskDir, { recursive: true });
|
|
24
|
-
|
|
25
|
-
// Create docs subdirectories
|
|
26
13
|
const docsDir = path.join(deskDir, "docs");
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
fs.mkdirSync(docsBlueprintsDir, { recursive: true });
|
|
31
|
-
|
|
32
|
-
// Copy files — must match CLAUDE.md "Local File Sync" section exactly
|
|
33
|
-
const copies = [
|
|
34
|
-
// Runtime files
|
|
14
|
+
const nodeDir = path.join(deskDir, "node");
|
|
15
|
+
const pkgDir = path.join(__dirname, "..");
|
|
16
|
+
const runtimeSources = [
|
|
35
17
|
["src/commands/rlp-desk.md", path.join(commandsDir, "rlp-desk.md")],
|
|
36
18
|
["src/governance.md", path.join(deskDir, "governance.md")],
|
|
37
19
|
["src/model-upgrade-table.md", path.join(deskDir, "model-upgrade-table.md")],
|
|
38
|
-
["src/scripts/init_ralph_desk.zsh", path.join(deskDir, "init_ralph_desk.zsh")],
|
|
39
|
-
["src/scripts/run_ralph_desk.zsh", path.join(deskDir, "run_ralph_desk.zsh")],
|
|
40
|
-
["src/scripts/lib_ralph_desk.zsh", path.join(deskDir, "lib_ralph_desk.zsh")],
|
|
41
|
-
// Reference docs
|
|
42
20
|
["README.md", path.join(deskDir, "README.md")],
|
|
43
21
|
["install.sh", path.join(deskDir, "install.sh")],
|
|
44
22
|
["docs/architecture.md", path.join(docsDir, "architecture.md")],
|
|
@@ -46,42 +24,104 @@ const copies = [
|
|
|
46
24
|
["docs/protocol-reference.md", path.join(docsDir, "protocol-reference.md")],
|
|
47
25
|
["docs/TODO-verification-next.md", path.join(docsDir, "TODO-verification-next.md")],
|
|
48
26
|
];
|
|
27
|
+
const legacyFiles = [
|
|
28
|
+
path.join(deskDir, "init_ralph_desk.zsh"),
|
|
29
|
+
path.join(deskDir, "run_ralph_desk.zsh"),
|
|
30
|
+
path.join(deskDir, "lib_ralph_desk.zsh"),
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
function getNodeVersion() {
|
|
34
|
+
return process.env.RLP_DESK_NODE_VERSION_OVERRIDE || process.version;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isSupportedNodeVersion(version) {
|
|
38
|
+
const match = /^v(\d+)/.exec(version || "");
|
|
39
|
+
return Boolean(match) && Number(match[1]) >= 16;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function ensureDir(dirPath) {
|
|
43
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function removePath(targetPath) {
|
|
47
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function copyFile(sourceRelativePath, targetPath) {
|
|
51
|
+
ensureDir(path.dirname(targetPath));
|
|
52
|
+
fs.copyFileSync(path.join(pkgDir, sourceRelativePath), targetPath);
|
|
53
|
+
console.log(" + " + targetPath);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function copyMarkdownDirectory(sourceRelativeDir, targetDir) {
|
|
57
|
+
const sourceDir = path.join(pkgDir, sourceRelativeDir);
|
|
58
|
+
if (!fs.existsSync(sourceDir)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
49
61
|
|
|
50
|
-
|
|
51
|
-
for (const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
ensureDir(targetDir);
|
|
63
|
+
for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
|
|
64
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
65
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
copyMarkdownDirectory(path.join(sourceRelativeDir, entry.name), targetPath);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
71
|
+
ensureDir(path.dirname(targetPath));
|
|
72
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
73
|
+
console.log(" + " + targetPath);
|
|
58
74
|
}
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
78
|
+
function copyNodeRuntime(sourceDir, targetDir) {
|
|
79
|
+
removePath(targetDir);
|
|
80
|
+
ensureDir(targetDir);
|
|
66
81
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
|
|
83
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
84
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
85
|
+
if (entry.isDirectory()) {
|
|
86
|
+
copyNodeRuntime(sourcePath, targetPath);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (entry.isFile()) {
|
|
90
|
+
ensureDir(path.dirname(targetPath));
|
|
91
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
92
|
+
console.log(" + " + targetPath);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
74
95
|
}
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
console.log("");
|
|
98
|
+
console.log(" RLP Desk v" + pkg.version);
|
|
99
|
+
console.log(" ================");
|
|
100
|
+
console.log("");
|
|
101
|
+
|
|
102
|
+
if (!isSupportedNodeVersion(getNodeVersion())) {
|
|
103
|
+
console.log(" [warn] RLP Desk requires Node.js >= 16 for the Node rewrite runtime.");
|
|
104
|
+
console.log(" Existing zsh installation was left unchanged.");
|
|
82
105
|
console.log("");
|
|
106
|
+
process.exit(0);
|
|
83
107
|
}
|
|
84
108
|
|
|
109
|
+
ensureDir(commandsDir);
|
|
110
|
+
ensureDir(deskDir);
|
|
111
|
+
ensureDir(docsDir);
|
|
112
|
+
|
|
113
|
+
for (const legacyFile of legacyFiles) {
|
|
114
|
+
removePath(legacyFile);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const [sourcePath, targetPath] of runtimeSources) {
|
|
118
|
+
copyFile(sourcePath, targetPath);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
copyMarkdownDirectory("docs/internal", path.join(docsDir, "internal"));
|
|
122
|
+
copyMarkdownDirectory("docs/blueprints", path.join(docsDir, "blueprints"));
|
|
123
|
+
copyNodeRuntime(path.join(pkgDir, "src", "node"), nodeDir);
|
|
124
|
+
|
|
85
125
|
console.log("");
|
|
86
126
|
console.log(" Done! Open Claude Code and run:");
|
|
87
127
|
console.log(" /rlp-desk brainstorm \"your task description\"");
|
package/scripts/uninstall.js
CHANGED
|
@@ -16,22 +16,31 @@ console.log("");
|
|
|
16
16
|
|
|
17
17
|
const files = [
|
|
18
18
|
path.join(commandsDir, "rlp-desk.md"),
|
|
19
|
-
path.join(deskDir, "init_ralph_desk.zsh"),
|
|
20
|
-
path.join(deskDir, "run_ralph_desk.zsh"),
|
|
21
|
-
path.join(deskDir, "lib_ralph_desk.zsh"),
|
|
22
19
|
path.join(deskDir, "governance.md"),
|
|
20
|
+
path.join(deskDir, "model-upgrade-table.md"),
|
|
21
|
+
path.join(deskDir, "README.md"),
|
|
22
|
+
path.join(deskDir, "install.sh"),
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
-
for (const
|
|
25
|
+
for (const targetPath of files) {
|
|
26
26
|
try {
|
|
27
|
-
fs.
|
|
28
|
-
console.log(" - " +
|
|
27
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
28
|
+
console.log(" - " + targetPath);
|
|
29
29
|
} catch (_) {
|
|
30
|
-
//
|
|
30
|
+
// Ignore missing files.
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const subdir of ["docs", "node"]) {
|
|
35
|
+
const targetPath = path.join(deskDir, subdir);
|
|
36
|
+
try {
|
|
37
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
38
|
+
console.log(" - " + targetPath);
|
|
39
|
+
} catch (_) {
|
|
40
|
+
// Ignore missing directories.
|
|
31
41
|
}
|
|
32
42
|
}
|
|
33
43
|
|
|
34
|
-
// Remove ralph-desk dir if empty
|
|
35
44
|
try {
|
|
36
45
|
const remaining = fs.readdirSync(deskDir);
|
|
37
46
|
if (remaining.length === 0) {
|
|
@@ -39,7 +48,7 @@ try {
|
|
|
39
48
|
console.log(" - " + deskDir);
|
|
40
49
|
}
|
|
41
50
|
} catch (_) {
|
|
42
|
-
// Directory may not exist
|
|
51
|
+
// Directory may not exist.
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
console.log("");
|
package/src/commands/rlp-desk.md
CHANGED
|
@@ -372,7 +372,6 @@ If claude engine (default):
|
|
|
372
372
|
```
|
|
373
373
|
Agent(
|
|
374
374
|
description="rlp-desk worker iter-NNN",
|
|
375
|
-
subagent_type="executor",
|
|
376
375
|
model=<worker_model>,
|
|
377
376
|
mode="bypassPermissions",
|
|
378
377
|
prompt=<full worker prompt text>
|
|
@@ -433,7 +432,6 @@ If claude engine (default):
|
|
|
433
432
|
```
|
|
434
433
|
Agent(
|
|
435
434
|
description="rlp-desk verifier iter-NNN (us_id)",
|
|
436
|
-
subagent_type="executor",
|
|
437
435
|
model=<selected_verifier_model>,
|
|
438
436
|
mode="bypassPermissions",
|
|
439
437
|
prompt=<full verifier prompt text with US scope>
|
package/src/governance.md
CHANGED
|
@@ -267,6 +267,7 @@ Verifier records WHY each judgment was made in `verify-verdict.json`:
|
|
|
267
267
|
- Runs commands directly to collect fresh evidence
|
|
268
268
|
- Campaign Memory is for orientation only — not the source of truth
|
|
269
269
|
- Writes verdict (`pass` | `fail` | `request_info`) — if uncertain, use `request_info` with specific questions; Leader decides
|
|
270
|
+
- **Verdict output rule**: MUST write verdict JSON as a FILE (not stdout). Leader polls the file path — terminal output is lost. Evidence strings: include key metrics and exit codes only, do NOT quote full command output or logs verbatim.
|
|
270
271
|
- Delegates deterministic checks (type hints, linting, security) to tools defined in test-spec
|
|
271
272
|
- Focuses on AC verification, semantic review, and smoke tests
|
|
272
273
|
- **Must NEVER modify code or write sentinel files**
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const CLAUDE_BIN = 'claude';
|
|
2
|
+
const CODEX_BIN = 'codex';
|
|
3
|
+
const CLAUDE_MODELS = new Set(['haiku', 'sonnet', 'opus']);
|
|
4
|
+
|
|
5
|
+
function assertTuiMode(mode, builderName) {
|
|
6
|
+
if (mode !== 'tui') {
|
|
7
|
+
throw new Error(`${builderName} unknown mode '${mode}'`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildClaudeCmd(mode, model, options = {}) {
|
|
12
|
+
assertTuiMode(mode, 'buildClaudeCmd');
|
|
13
|
+
|
|
14
|
+
const parts = [
|
|
15
|
+
'DISABLE_OMC=1',
|
|
16
|
+
CLAUDE_BIN,
|
|
17
|
+
'--model',
|
|
18
|
+
model,
|
|
19
|
+
'--mcp-config',
|
|
20
|
+
'\'{"mcpServers":{}}\'',
|
|
21
|
+
'--strict-mcp-config',
|
|
22
|
+
'--dangerously-skip-permissions',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
if (options.effort !== undefined && options.effort !== '') {
|
|
26
|
+
parts.push('--effort', options.effort);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return parts.join(' ');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function buildCodexCmd(mode, model, options = {}) {
|
|
33
|
+
assertTuiMode(mode, 'buildCodexCmd');
|
|
34
|
+
|
|
35
|
+
const parts = [
|
|
36
|
+
CODEX_BIN,
|
|
37
|
+
'-m',
|
|
38
|
+
model,
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
if (options.reasoning !== undefined) {
|
|
42
|
+
parts.push('-c', `model_reasoning_effort="${options.reasoning}"`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
parts.push('--disable', 'plugins', '--dangerously-bypass-approvals-and-sandbox');
|
|
46
|
+
|
|
47
|
+
return parts.join(' ');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function parseModelFlag(value, role = 'worker') {
|
|
51
|
+
const colonCount = [...value].filter((character) => character === ':').length;
|
|
52
|
+
|
|
53
|
+
if (colonCount > 1) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`invalid format for --${role}-model '${value}'. Use 'model:effort' (claude) or 'model:reasoning' (codex).`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (colonCount === 0) {
|
|
60
|
+
if (!value) {
|
|
61
|
+
throw new Error(`--${role}-model model is required`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
engine: 'claude',
|
|
66
|
+
model: value,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const [model, level] = value.split(':');
|
|
71
|
+
if (!model) {
|
|
72
|
+
throw new Error(`--${role}-model model is required`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (CLAUDE_MODELS.has(model)) {
|
|
76
|
+
return {
|
|
77
|
+
engine: 'claude',
|
|
78
|
+
model,
|
|
79
|
+
effort: level,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (model === 'spark') {
|
|
84
|
+
return {
|
|
85
|
+
engine: 'codex',
|
|
86
|
+
model: 'gpt-5.3-codex-spark',
|
|
87
|
+
reasoning: level,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
engine: 'codex',
|
|
93
|
+
model,
|
|
94
|
+
reasoning: level,
|
|
95
|
+
};
|
|
96
|
+
}
|