@lifeaitools/rdc-skills 0.37.5 → 0.37.8

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rdc",
3
- "version": "0.37.5",
3
+ "version": "0.37.8",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code — plan, build, review, overnight unattended builds with work-item tracking and TDD enforcement.",
5
5
  "author": {
6
6
  "name": "LIFEAI",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": "lifeai.plugin.v1",
3
3
  "id": "rdc-skills",
4
- "version": "0.37.5",
4
+ "version": "0.37.8",
5
5
  "publisher": "LIFEAI",
6
6
  "core": false,
7
7
  "documentation": {
package/git-sha.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "sha": "a96832c1aa663240fecf042c6b41d7017c8bce47"
2
+ "sha": "b71cf17b326bf3b68432d169032107877bfceb58"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.37.5",
3
+ "version": "0.37.8",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -19,7 +19,7 @@
19
19
  "type": "plugin",
20
20
  "skills": "skills/",
21
21
  "guides": "guides/",
22
- "version": "0.37.5",
22
+ "version": "0.37.8",
23
23
  "commands": "commands/"
24
24
  },
25
25
  "bin": {
@@ -951,7 +951,7 @@ function findCodexTargets() {
951
951
  return targets;
952
952
  }
953
953
 
954
- function registerCodexTarget(targetDir) {
954
+ function registerCodexTarget(targetDir, { install = false } = {}) {
955
955
  fs.mkdirSync(targetDir, { recursive: true });
956
956
 
957
957
  // Clean: remove dirs that are rdc skills — by prefix OR by frontmatter name
@@ -967,11 +967,21 @@ function registerCodexTarget(targetDir) {
967
967
  }
968
968
  }
969
969
 
970
- // Do not reinstall file-based copies. Codex discovers the live catalog via
971
- // [mcp_servers.rdc-skills]. Keeping the same skills in ~/.codex and ~/.agents
972
- // registers every skill two or three times, exhausts Codex's skill metadata
973
- // budget, and emits a red startup error on every session.
974
- return { removed, copied: 0 };
970
+ if (!install) return { removed, copied: 0 };
971
+
972
+ // Install into exactly ONE Codex skill dir. Copies in both ~/.codex and
973
+ // ~/.agents registered every skill twice and exhausted Codex's skill metadata
974
+ // budget; bf88292 answered that by installing none, which left Codex with
975
+ // rdc: skills only while the remote MCP was reachable.
976
+ const skillsSrc = path.join(repoRoot, 'skills');
977
+ let copied = 0;
978
+ for (const entry of fs.readdirSync(skillsSrc, { withFileTypes: true })) {
979
+ if (!entry.isDirectory()) continue;
980
+ if (!fs.existsSync(path.join(skillsSrc, entry.name, 'SKILL.md'))) continue;
981
+ copyDirRecursive(path.join(skillsSrc, entry.name), path.join(targetDir, `rdc-${entry.name}`));
982
+ copied++;
983
+ }
984
+ return { removed, copied };
975
985
  }
976
986
 
977
987
  // ── Step 6: Zip for claude.ai / distribution ─────────────────────────────────
@@ -1372,21 +1382,24 @@ async function main() {
1372
1382
  info('[2.5] MCP — rdc-skills endpoint verified (claude + codex)');
1373
1383
  }
1374
1384
 
1375
- // 2.6. Codex migration: MCP is authoritative; purge legacy file copies.
1385
+ // 2.6. Codex: rdc skill files in ONE dir (the explicit one, else ~/.codex/skills);
1386
+ // every other Codex skill dir is only cleaned, so nothing registers twice.
1376
1387
  const codexTargets = findCodexTargets();
1377
- if (codexTargets.length > 0) {
1378
- let copiedTotal = 0;
1379
- let removedTotal = 0;
1380
- for (const target of codexTargets) {
1381
- const { removed, copied } = registerCodexTarget(target.targetDir);
1382
- copiedTotal += copied;
1383
- removedTotal += removed;
1384
- info(` ${target.label.padEnd(15)}: ${target.targetDir} (${removed} stale removed; MCP authoritative)`);
1385
- }
1386
- ok(`[2.6] Codex — ${removedTotal} stale file-based skill(s) removed across ${codexTargets.length} target(s); MCP authoritative`);
1387
- } else {
1388
- info('[2.6] Codex — skipped (no Codex skill dirs found; use --codex-root or --codex-skill-dir)');
1389
- }
1388
+ const primaryCodexDir = explicitCodexSkillDir || path.join(os.homedir(), '.codex', 'skills');
1389
+ if (!codexTargets.some((t) => t.targetDir === primaryCodexDir)) {
1390
+ codexTargets.unshift({ label: 'global .codex', targetDir: primaryCodexDir });
1391
+ }
1392
+ let copiedTotal = 0;
1393
+ let removedTotal = 0;
1394
+ for (const target of codexTargets) {
1395
+ const install = target.targetDir === primaryCodexDir;
1396
+ const { removed, copied } = registerCodexTarget(target.targetDir, { install });
1397
+ copiedTotal += copied;
1398
+ removedTotal += removed;
1399
+ info(` ${target.label.padEnd(15)}: ${target.targetDir} (${install ? `${copied} installed` : 'cleaned only'}, ${removed} stale removed)`);
1400
+ }
1401
+ if (copiedTotal === 0) throw new Error(`Codex skill install wrote nothing to ${primaryCodexDir}`);
1402
+ ok(`[2.6] Codex — ${copiedTotal} skill(s) installed in ${primaryCodexDir}; ${removedTotal} stale copies removed across ${codexTargets.length} dir(s)`);
1390
1403
 
1391
1404
  // 2.7. Symlinks in regen-root/.claude/skills/ (FS MCP + claude.ai access)
1392
1405
  if (codexRoot) {
@@ -178,10 +178,16 @@ function checkCodex(truth) {
178
178
  const rdcDirs = dirs.filter((e) => /^rdc-/.test(e.name) || readFrontmatterName(path.join(t.dir, e.name, 'SKILL.md'))?.startsWith('rdc:'));
179
179
  results.push({ label: t.label, dir: t.dir, count: rdcDirs.length });
180
180
  }
181
- const pass = results.every((r) => r.count === 0);
182
- const detail = results.map((r) =>
183
- `${r.label}: ${r.count} legacy file-based rdc skill(s)${r.count === 0 ? '' : ' [MCP DUPLICATES PRESENT]'}`
184
- ).join('; ');
181
+ // Codex keeps rdc skills as files in exactly one dir (~/.codex/skills), so it
182
+ // works without the network; any copy elsewhere registers the skill twice.
183
+ const skillsSrc = path.join(repoRoot, 'skills');
184
+ const expected = fs.readdirSync(skillsSrc, { withFileTypes: true })
185
+ .filter((e) => e.isDirectory() && fs.existsSync(path.join(skillsSrc, e.name, 'SKILL.md'))).length;
186
+ const isPrimary = (r) => r.label === 'global .codex';
187
+ const pass = results.some(isPrimary) && results.every((r) => (isPrimary(r) ? r.count === expected : r.count === 0));
188
+ const detail = results.map((r) => (isPrimary(r)
189
+ ? `${r.label}: ${r.count}/${expected} rdc skill(s) installed`
190
+ : `${r.label}: ${r.count} rdc skill(s)${r.count === 0 ? '' : ' [DUPLICATES — would register twice]'}`)).join('; ');
185
191
  return { surface: 'Codex', pass, detail };
186
192
  }
187
193
 
@@ -8,6 +8,11 @@ description: rdc:co-develop (subcommand) - [--wait] — peer-aware Claude/Codex
8
8
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
9
9
  > **Sandbox contract:** This skill honors `RDC_TEST=1` per `guides/agent-bootstrap.md` § RDC_TEST Sandbox Contract. Under the flag, do not create/send/reply to live co-development turns; report the intended clauth command and mark the external relay action as skipped.
10
10
 
11
+ > **⚠️ Transport gone (probed 2026-09-24).** `clauth codevelop …` returns `unknown command 'codevelop'`
12
+ > and `GET /codevelop` returns `Unknown endpoint` on clauth 2.16.8. The commands below cannot run.
13
+ > Use `rdc:collab` (named lane via `pool/collab-lane.mjs`, ask via `pool/collab-ask.mjs`, reply file
14
+ > under `.rdc/reports/`). This skill is kept only until it is retired or re-pointed.
15
+
11
16
  # rdc:co-develop — Peer-Aware Co-Development
12
17
 
13
18
  Use this skill when an RDC workflow needs Claude and Codex to work together in
@@ -67,6 +67,14 @@ that guard just made impossible. That happened on 2026-08-14 and cost a complete
67
67
  negotiation result. **Your reasoning in the reply is always deliverable. A file
68
68
  write may not be.**
69
69
 
70
+ **One exception — a named report.** If the dispatch carries `DELIVERABLE: <path>` and
71
+ the path is under `.rdc/` (a report in `.rdc/reports/`, a plan in
72
+ `.rdc/areas/<domain>/<program>/plans/`, scratch in `.rdc/tmp/`), write exactly that file and no
73
+ other: the start gate exempts `.rdc/**` docs, so it cannot strand, and the reply still carries the
74
+ summary. If the path is anywhere else, do **not** write it: return the content in the reply and
75
+ say `BLOCKED: DELIVERABLE outside .rdc/ would be refused by work-contract-required`. Never create
76
+ a work contract to get past it; that is the initiator's decision.
77
+
70
78
  ---
71
79
 
72
80
  ## What you owe BACK — your responsibilities
@@ -282,7 +290,7 @@ cannot act on a guess it has to verify.
282
290
  | Filing a settled agreement as a lesson | Buries a queryable Decision |
283
291
  | Going silent when blocked | Indistinguishable from being dead |
284
292
  | Editing a document you do not own | Lost work, no error, no trace |
285
- | Writing ANY file during a collab | Not your job here — the reply is the deliverable |
293
+ | Writing ANY file during a collab | Not your job here — the reply is the deliverable. Only exception: the one `DELIVERABLE:` path under `.rdc/` named in the dispatch |
286
294
  | Committing to whatever branch you happen to be on | The change strands where nobody looks for it |
287
295
  | Answering an easier adjacent question | The real point stays open and looks settled |
288
296
  | Attempting a workaround for a guard block | The guard is usually right; the dispatch is usually wrong |
@@ -224,7 +224,7 @@ most common failure and it fails at the guard layer, not the prompt layer.
224
224
 
225
225
  | Collaborator | Invocation | Isolation requirement | Known failure mode |
226
226
  |---|---|---|---|
227
- | **`codex`** | `codex exec [-C <dir>] "<msg>"` · resume: `codex exec resume <session-id> "<msg>"` | **A headless `codex exec` peer is READ-ONLY. It cannot write to any lane — see below.** Never dispatch it from your own lane. | Its managed identity is fixed at session creation and `-C` does **not** change it. Dispatch from your lane and every write is refused with `CODEX MANAGED LANE: App Local must use an owned managed Codex lane` — permanently, for that session's whole life. |
227
+ | **`codex`** | `codex exec [-C <dir>] "<msg>"` · resume: `codex exec resume <session-id> "<msg>"` | **A headless `codex exec` peer can write ONE named report under `.rdc/` (probed 2026-09-24); any other write in a git work tree is refused by `work-contract-required` unless it holds a contract — see the notes below.** Never dispatch it from your own lane, and launch it with its own lane's identity: `env -u CELL_ROLE LIFEAI_CHECKOUT_ROOT=<its lane> codex exec -C <its lane> -m <model> "<prompt>" < /dev/null` (a headless peer inherits your `CELL_ROLE`/`LIFEAI_CHECKOUT_ROOT` and then fails lane recovery with "identity … differs"; probed 2026-09-24: with this env it starts clean). Close stdin with `< /dev/null`: an open pipe makes `codex exec` wait forever. | Its managed identity is fixed at session creation and `-C` does **not** change it. Dispatch from your lane and every write is refused with `CODEX MANAGED LANE: App Local must use an owned managed Codex lane` — permanently, for that session's whole life. |
228
228
 
229
229
  > **`-C` does not establish lane identity — verified 2026-08-14, and an earlier
230
230
  > version of this table said the opposite.** Managed identity is an 8-field record
@@ -235,6 +235,14 @@ most common failure and it fails at the guard layer, not the prompt layer.
235
235
  > `codex exec` has no lane-claim path, so it cannot produce that record — which
236
236
  > means **a headless Codex peer cannot write in any lane, including its own**.
237
237
  >
238
+ > **Correction, probed 2026-09-24.** `codex exec -s workspace-write` wrote a file in a lane
239
+ > it did not own with no identity refusal, so "cannot write in any lane" above is too strong. What
240
+ > stops a peer is the START gate, `work-contract-required` (guard-rules.mjs): a write inside a git
241
+ > work tree needs a work contract, and **only `.rdc/**` files with a doc extension (`md`, `txt`,
242
+ > `json`, `yml`, `csv`, `html`, …) are exempt.** A peer told to write `REVIEW-REPLY.md` at a lane
243
+ > root was refused (2026-09-24) and had to hand the finished report back through its log. The flow
244
+ > does not change this: the rule never reads it. Name the reply path under `.rdc/` (rule 7, Step 2).
245
+ >
238
246
  > Two consequences: (1) `resume` replays the session's *recorded* identity, so a
239
247
  > session created in the wrong cwd is poisoned for life and `-C` will not repair
240
248
  > it — start a new session instead; (2) treat a `codex exec` peer as a
@@ -391,6 +399,21 @@ Rules that make the contract hold:
391
399
  OUT of the collab still lands in a governing document (Step 5); it is the
392
400
  negotiation turns themselves that are conversation-only.
393
401
 
402
+ 7. **A report or plan the peer must hand back goes to ONE named path under `.rdc/`,
403
+ stated in the dispatch.** Add the line `DELIVERABLE: <path>` (or
404
+ `DELIVERABLE: reply-only`) to the contract. Reports: `.rdc/reports/<lane>-<topic>.md`.
405
+ Plans: `.rdc/areas/<domain>/<program>/plans/<name>.md`. Scratch: `.rdc/tmp/`. These are the
406
+ only places a peer without a work contract can write, so the file cannot strand. A path at a
407
+ lane root or in any code or docs directory will be refused, and the peer's answer then
408
+ exists only in its transcript. The peer still returns a short summary in the reply; the file
409
+ is the durable copy. Name the peer the single writer of that one file (Step 4).
410
+
411
+ **Cap the file in the dispatch, or it will not be short.** Peers asked for "the literal result" of
412
+ every probe paste raw dumps (2026-09-24: a 12-finding audit came back as 99 KB). State: findings
413
+ at most 4 lines each, `EVIDENCE` one command plus a one-line result, raw output to
414
+ `.rdc/tmp/<lane>-evidence/` and linked, whole file at most 15 KB, a time box, and "append after each
415
+ point" so a partial report still exists.
416
+
394
417
  ---
395
418
 
396
419
  ## Step 3 — Converge
@@ -571,6 +594,7 @@ and avoids acting on a misread premise (lesson
571
594
  | Escalating a transcript | The human has to find the question themselves |
572
595
  | Two agents editing one document | Lost work, no error |
573
596
  | Writing to the repo during a collab | Your answer may be guard-blocked and stranded; the reply is always deliverable, a write may not be |
597
+ | Naming a reply file outside `.rdc/` (a lane root, `docs/`, a package) | Refused by `work-contract-required`; the finished report has to be dug out of the peer's log. Use `DELIVERABLE: .rdc/reports/<name>.md` |
574
598
  | Using collab to hand off WORK | Wrong skill. Create a work item and use rdc:build or an isolated-worktree agent |
575
599
 
576
600
  ---
@@ -27,6 +27,20 @@ Run it from the regen-root checkout you are working in. That is the whole
27
27
  instruction. There is no checklist to follow, no mode to pick, and no decision
28
28
  for you to make on the success path.
29
29
 
30
+ ## Local build contract
31
+
32
+ Standard dev deployment builds on the workstation first. `DEPLOY_MGR_URL`
33
+ must name a loopback manager whose health response reports `host.role: local`.
34
+ The program requests `builder: local` explicitly; Docker or build failure stops
35
+ the deployment. It never falls back to a remote builder.
36
+
37
+ The target must have a registered image route. Legacy remote build/reload routes
38
+ are refused until a proper local artifact build-and-ship route is implemented.
39
+ Do not enable an image route without its runtime and build configuration.
40
+
41
+ The manager's explicitly requested remote maintenance operations remain separate
42
+ from this standard command. `promote` remains build-free and approval-gated.
43
+
30
44
  ## Exit 0 — you are done
31
45
 
32
46
  Print the URL the program reports, and stop.
@@ -46,8 +60,8 @@ followed by the same record as one line of JSON.
46
60
  | exit | meaning | first move |
47
61
  |---|---|---|
48
62
  | 2 | usage — bad or missing arguments | read the usage line; this program takes a slug and optionally `promote` |
49
- | 3 | deploy manager unreachable | `pm2 restart regen-deploy-mgr` (it is a local PM2 process), then re-run |
50
- | 4 | slug not resolvable or not routable | the block names what is missing — a registry row, or an allowlist entry |
63
+ | 3 | deploy manager unavailable or unsuitable for local building | read the block; restore the workstation manager and its local host identity, then re-run |
64
+ | 4 | slug not resolvable or no local artifact route | the block names the missing registry or image route; repair that route before deployment |
51
65
  | 5 | a submitted job failed or was rejected | the block carries the manager's own step, command, exit code and stderr tail |
52
66
  | 6 | the job succeeded but the health probe did not | bytes shipped, app did not come up — read the job the block names |
53
67
  | 7 | polling exceeded the deadline | the job is NOT cancelled; the block gives the URL to read it |
@@ -110,9 +124,10 @@ manager, where it runs, rather than in a document that hopes to be read.
110
124
 
111
125
  A dev deploy needs no approval. `promote` puts bytes on production and needs
112
126
  explicit go-ahead for that call. The program itself refuses to promote anything
113
- that is not an image-model app, because promote retags the digest dev already
114
- runs — **a promote never builds**, and one that fell back to building would ship
115
- bytes production has never seen under a name claiming it had.
127
+ that is not an image-model app. **A promote never builds**; it retags an existing
128
+ image through the manager. The current manager resolves the configured dev tag
129
+ (normally `develop`); a successful dev deploy alone does not prove that this
130
+ mutable tag still identifies the running dev image when promotion begins.
116
131
 
117
132
  ## Verification
118
133