@lifeaitools/rdc-skills 0.35.4 → 0.35.5

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.35.4",
3
+ "version": "0.35.5",
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",
package/commands/build.md CHANGED
@@ -69,6 +69,25 @@ Read the task title and description, then:
69
69
  - Mentions visualization, chart, diagram, SVG → `viz`
70
70
  - Multiple types? Dispatch multiple agents, each with its guide.
71
71
 
72
+ ### Execution primitive for create/open/build/deploy checklist rows
73
+
74
+ When a dispatched agent's checklist row is to materialize a product shape,
75
+ open a signed edit session, run a target's declared build gates, or deploy
76
+ to dev-PM2/npm-registry, it uses the real, tested `rdc-harness` CLI instead
77
+ of hand-rolled bash/curl:
78
+
79
+ ```bash
80
+ node C:/Dev/rdc-harness/bin/rdc-harness.mjs <create|open|edit|build|deploy> <slug> --monorepo-root <the dispatched agent's own worktree>
81
+ ```
82
+
83
+ One JSON receipt per call, exit 0/1 — tick the checklist row with the parsed
84
+ receipt as evidence, not the raw dump. No Coolify awareness (production
85
+ deploy stays `/rdc:deploy`'s own path) and no live co-editing surface
86
+ outside `site-html`/`site-ts` (other classes get file-boundary save only —
87
+ real, currently-unbuilt gap for other product classes, not something to
88
+ paper over here). `open`/`edit` require `RDC_HARNESS_ISSUER_SECRET` set
89
+ explicitly per-session — never a default.
90
+
72
91
  ## Procedure
73
92
 
74
93
  1. **Load the epic and its durable admission decisions:**
@@ -27,11 +27,30 @@ No raw MCP dumps. No UUIDs unless asked.
27
27
  - `rdc:deploy audit` — fleet-wide scan for missed failures
28
28
  - `rdc:deploy audit --fix` — fleet scan + auto-remediate safe issues
29
29
  - `rdc:deploy maintenance <service>` — create, update, or verify a template-declared private service; no public domain or host port
30
+ - `rdc:deploy dev <slug>` — deploy to PM2 dev (Vultr), not Coolify — see Mode 0
30
31
  - `rdc:deploy` (no args) — print mode menu, ask which
31
32
 
32
33
  ## Modes
33
34
 
34
- ### Mode 1deploy <slug> [build-id]
35
+ ### Mode 0dev <slug> (PM2 development, not Coolify)
36
+
37
+ PM2 dev deploys route through the real, tested `rdc-harness` CLI instead of
38
+ raw PM2/curl — it already implements this path (`shipRoute: pm2-development`,
39
+ via `@lifeaitools/regen-deploy-mgr` on loopback :52438, never raw PM2):
40
+
41
+ ```
42
+ rdc:deploy dev: <slug>
43
+ [ ] node C:/Dev/rdc-harness/bin/rdc-harness.mjs deploy <slug> --monorepo-root <caller's own worktree>
44
+ [ ] JSON receipt parsed — shipRoute confirmed "pm2-development" (else: not this product's route, see receipt.reason)
45
+ [ ] Receipt reports ok / the specific refusal, reported verbatim — not narrated
46
+ ✅ rdc:deploy dev: <slug> — <receipt outcome in one line>
47
+ ```
48
+
49
+ A receipt with `applicable: false, reason: 'not_pm2_shipped'` means this slug
50
+ ships a different way (registry, static, or Coolify) — report that plainly,
51
+ do not retry as Coolify without confirming that's actually the right route.
52
+
53
+ ### Mode 1 — deploy <slug> [build-id] (Coolify — staging/production)
35
54
 
36
55
  ```
37
56
  rdc:deploy: <slug> → <domain>
package/commands/fixit.md CHANGED
@@ -70,6 +70,23 @@ This signals the Stop hook that fixit is handling its own documentation.
70
70
 
71
71
  ### 4. Make the fix
72
72
 
73
+ If the fix is a create/open/build/deploy step against a real fleet
74
+ repository (materialize a product shape, open a signed edit session, run a
75
+ target's declared build gates, or deploy to dev-PM2/npm-registry), use the
76
+ real, tested `rdc-harness` CLI instead of hand-rolled bash/curl:
77
+
78
+ ```bash
79
+ node C:/Dev/rdc-harness/bin/rdc-harness.mjs <create|open|edit|build|deploy> <slug> --monorepo-root <your own worktree, never the shared checkout>
80
+ ```
81
+
82
+ One JSON receipt on stdout, exit 0/1 — use it as the evidence for whichever
83
+ checklist/commit step it satisfies. It has no Coolify awareness (deploy here
84
+ means PM2 dev or npm publish only — Coolify stays this skill's own §5.5 path)
85
+ and no live co-editing surface outside `site-html`/`site-ts` targets (other
86
+ classes get boundary-checked file save only). `open`/`edit` need
87
+ `RDC_HARNESS_ISSUER_SECRET` set explicitly — no default exists or should.
88
+ For anything not create/open/build/deploy shaped, edit files directly as below.
89
+
73
90
  Do the minimal work, conforming to `docs/CODING-STANDARDS.md` where present
74
91
  (regen-root; skip if absent). Scope creep rule: if you discover the fix requires more than originally scoped, **stop immediately**:
75
92
  1. Close the work item: `update_work_item_status('<id>', 'blocked', '["Escalated — scope exceeded fixit threshold"]')`
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: flow
3
+ description: >-
4
+ Usage `rdc:flow [status|<state> ["<reason>"]|normal]` — show or set the current flow state. Flow is the single FSM surface for both work-shape (plan/design/collab/build/refactor/overnight/harness-testing) and ceremony relaxation (hotfix/maintenance). Supersedes `rdc:mode` — hotfix/maintenance are flow values now, not a separate system.
5
+ ---
6
+
7
+ > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
8
+ > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
9
+ > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
10
+
11
+ # rdc:flow — the one FSM surface
12
+
13
+ ## When to Use
14
+ - Starting a turn — declare what kind of work this is (`build` needs a work item, `plan`/`design`/`collab` don't)
15
+ - A production incident where process ceremony is costing minutes that matter (`hotfix`)
16
+ - Routine upkeep that needs the same relaxation, without calling it an incident (`maintenance`)
17
+ - Checking what's currently declared, and why
18
+
19
+ ## The one thing to understand first
20
+
21
+ **There used to be two systems — mode (safety relaxation) and flow (work-shape declaration) — kept deliberately separate.** Operator instruction, 2026-08-25/26, direct and live: *"no special modes -- flow states only -- move hotfix to a flow state -- move env-bypass to a flow state -- the fsm will set what is enabled."*
22
+
23
+ `hotfix` and `maintenance` are now real flow values, carrying the exact same safety guarantee they always did as modes: a reason is required to enter either, and only the named ceremony allowlist (`HOTFIX_DISABLES`/`HOTFIX_RELAXES_GATES` in `$LIFEAI_ENV/hooks/lib/rdc-flow.mjs` and `C:/Dev/rdc-harness/fsm-daemon/src/matrix.js`) is ever relaxed — never a safety guard (`execution-scope`, `rm-rf-danger`, `push-force`, credential-exposure, etc.).
24
+
25
+ `rdc:mode` still exists for backward compatibility — the old mode axis is untouched, working code — but new work should use `rdc:flow` for everything, including what used to be a mode change.
26
+
27
+ ## States
28
+
29
+ | State | Meaning | Requires a reason | Work item required |
30
+ |---|---|---|---|
31
+ | `plan` / `design` / `collab` | Conversational — nothing shipping | no | no |
32
+ | `build` / `refactor` / `overnight` | Shipping code | no | **yes** |
33
+ | `harness-testing` | Proving/testing rdc-harness's own binding guard | no | yes |
34
+ | `hotfix` | Incident — ceremony relaxed for a bounded reason | **yes** | no |
35
+ | `maintenance` | Routine upkeep — same relaxation power as hotfix, different label | **yes** | no |
36
+
37
+ ## Usage
38
+
39
+ ```
40
+ rdc:flow # status — the default
41
+ rdc:flow status
42
+ rdc:flow build # declare shipping work — no reason needed
43
+ rdc:flow hotfix "prod checkout 500s" # relax ceremony — reason required
44
+ rdc:flow normal # clear — back to no flow declared
45
+ ```
46
+
47
+ ## Steps
48
+
49
+ ### 1. Read the current state
50
+
51
+ ```bash
52
+ node -e "import('file:///C:/Dev/lifeai-env/hooks/lib/rdc-flow.mjs').then(m=>console.log(JSON.stringify(m.currentState(),null,2)))"
53
+ ```
54
+
55
+ `currentState()` reads BOTH axes at once — the declared flow AND any live `rdc-mode.mjs` hotfix/maintenance window — because a relaxed mode overrides a required flow (loosest state wins) and a status check that only showed flow would miss that override entirely. Report `flow` (or `null` if nothing declared — the fail-closed default), `flowReason`/`flowSetBy`/`flowSetAt` when set, and `mode` (`normal` unless a hotfix/maintenance window is open), with `modeReason`/`modeMinutesLeft` when it isn't.
56
+
57
+ ### 2. Setting a plain work-shape flow — no reason required
58
+
59
+ ```bash
60
+ node -e "import('file:///C:/Dev/lifeai-env/hooks/lib/rdc-flow.mjs').then(m=>console.log(JSON.stringify(m.setFlow(process.argv[1],{setBy:process.argv[2]}),null,2)))" "<flow>" "<session-id>"
61
+ ```
62
+
63
+ ### 3. Setting hotfix or maintenance — a reason is REQUIRED
64
+
65
+ Refuse to proceed without one — `setFlow` throws on an empty reason for these two values, by design, same as `setMode` always did: an unexplained disarm is how a temporary state becomes permanent.
66
+
67
+ ```bash
68
+ node -e "import('file:///C:/Dev/lifeai-env/hooks/lib/rdc-flow.mjs').then(m=>console.log(JSON.stringify(m.setFlow('hotfix',{reason:process.argv[1],setBy:process.argv[2]}),null,2)))" "<reason>" "<session-id>"
69
+ ```
70
+
71
+ Then state plainly, in the checklist: **which guards are now relaxed, that the safety set is still armed, and that this stays active until explicitly cleared (no TTL — active management, not a silent timer).**
72
+
73
+ ### 4. Returning to normal
74
+
75
+ ```bash
76
+ node -e "import('file:///C:/Dev/lifeai-env/hooks/lib/rdc-flow.mjs').then(m=>{m.clearFlow();console.log('cleared')})"
77
+ ```
78
+
79
+ Do this **as soon as the incident is over**, or the moment the declared work-shape changes.
80
+
81
+ ## Rules
82
+
83
+ - **A reason is mandatory for `hotfix`/`maintenance`.** Every other flow value is a plain, reason-free declaration.
84
+ - **No TTL, ever, by default.** A flow — including `hotfix`/`maintenance` — stays active until explicitly cleared or replaced. Never a silent expiry.
85
+ - **Fail-closed.** No flow declared, an unreadable daemon, or a malformed response all read as `{flow: null}` — same behavior a work-shipping turn always had before this mechanism existed.
86
+ - **Never widen the relaxation set to unblock yourself.** A guard blocking a hotfix flow is information. Editing the allowlist to get past a red guard is the same violation as editing code to satisfy a failing gate (`.claude/rules/debugging-protocol.md` Rule 10).
87
+ - **hotfix/maintenance flow is not a bypass of review.** Work done under it still needs its work item, its evidence, and its close.
88
+
89
+ ## Verification
90
+
91
+ ```bash
92
+ node --test $LIFEAI_ENV/tests/rdc-flow.test.mjs
93
+ node --test C:/Dev/rdc-harness/fsm-daemon/tests/matrix.test.js
94
+ ```
package/commands/mode.md CHANGED
@@ -8,6 +8,12 @@ description: >-
8
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
9
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
10
10
 
11
+ > **Superseded by `rdc:flow`, 2026-08-26.** `hotfix`/`maintenance` are now
12
+ > flow values (same reason-required, same relaxation allowlist, no TTL by
13
+ > default) — one FSM surface instead of two. This skill's underlying code
14
+ > (`rdc-mode.mjs`) is untouched and still works; new work should use
15
+ > `rdc:flow hotfix "<reason>"` instead of `rdc:mode hotfix ...`.
16
+
11
17
  # rdc:mode — operating mode
12
18
 
13
19
  ## When to Use
@@ -39,6 +39,17 @@ rdc:release: <repo> vX.Y.Z -> vA.B.C
39
39
  - Never force push or bypass hooks.
40
40
  - Never declare success without verifying the installed or deployed version.
41
41
 
42
+ For a `package`-class target that already resolves through `rdc-harness`
43
+ (a real monorepo subtree, not a standalone repo like this one), its
44
+ `packages/deploy/src/runners/registry-release.mjs` runner already proves the
45
+ "Tests/self-test passed" through "Local install/update executed" steps
46
+ safely — real `npm pack`, isolated-prefix install (never the real global
47
+ store), real verify, and `--live` explicitly gates the actual publish. Where
48
+ applicable, `node C:/Dev/rdc-harness/bin/rdc-harness.mjs deploy <slug>
49
+ [--live]` can supply those checklist rows' evidence directly instead of
50
+ hand-rolling the same pack/install/verify cycle. This does not replace
51
+ version bump/tag/push — the harness CLI does neither.
52
+
42
53
  ## RDC Skills Package
43
54
 
44
55
  After publishing this package to npm, a clean-box install should use:
@@ -1,11 +1,11 @@
1
- # Agent Bootstrap — Read This First
2
- > Every dispatched agent reads this before their role-specific guide.
3
- > Base guide for rdc-skills — provides credential, git, and reporting patterns across projects.
4
-
5
- ---
6
-
7
- ## Who You Are
8
-
1
+ # Agent Bootstrap — Read This First
2
+ > Every dispatched agent reads this before their role-specific guide.
3
+ > Base guide for rdc-skills — provides credential, git, and reporting patterns across projects.
4
+
5
+ ---
6
+
7
+ ## Who You Are
8
+
9
9
  You are a subagent dispatched by the rdc:build supervisor. You have a specific
10
10
  scope (files, package, feature) that will be in your prompt. Stay in that scope.
11
11
  NEVER modify files outside it.
@@ -15,198 +15,242 @@ RDC implementation posture for assumptions, minimal changes, surgical scope,
15
15
  verification evidence, and escalation.
16
16
 
17
17
  ---
18
-
19
- ## Credentials — Daemon Access Pattern
20
-
21
- You do NOT have access to cloud MCP connectors. Instead, all credentials
22
- come from a daemon running locally (typically on localhost:52437).
23
-
24
- **Ping first to confirm availability:**
25
- ```bash
26
- curl -s http://127.0.0.1:52437/ping
27
- ```
28
- If it doesn't respond — report BLOCKED, do not proceed.
29
-
30
- **Get a credential:**
31
- ```bash
32
- curl -s http://127.0.0.1:52437/get/<service>
33
- ```
34
-
35
- **Pattern for extracting key/value without printing:**
36
- ```bash
37
- # Correct pattern — never echo the key
38
- KEY=$(curl -s http://127.0.0.1:52437/get/<service> | python3 -c "import sys,json; print(json.load(sys.stdin)['key'])")
39
- curl -s -H "Authorization: Bearer $KEY" https://api.example.com/...
40
- ```
41
-
42
- **Never print credentials to stdout.** Capture to a variable, use inline, discard.
43
-
44
- ---
45
-
46
- ## Project Directory Convention
47
-
48
- This plugin uses the `.rdc/` directory convention. Check for it first:
49
-
50
- ```bash
51
- # Check if .rdc/ exists at project root
52
- ls {PROJECT_ROOT}/.rdc/config.json 2>/dev/null && echo "using .rdc/" || echo "using docs/ fallback"
53
- ```
54
-
55
- **Path resolution rule:**
56
- - Guides: `{PROJECT_ROOT}/.rdc/guides/` → fallback: `{PROJECT_ROOT}/docs/guides/`
57
- - Plans: `{PROJECT_ROOT}/.rdc/plans/` → fallback: `{PROJECT_ROOT}/docs/plans/`
58
- - Reports: `{PROJECT_ROOT}/.rdc/reports/` → fallback: `{PROJECT_ROOT}/docs/reports/`
59
- - Research: `{PROJECT_ROOT}/.rdc/research/` → fallback: `{PROJECT_ROOT}/docs/research/`
60
-
61
- If `.rdc/config.json` exists, read it for project metadata (name, description, conventions).
62
-
63
- ---
64
-
65
- ## Database Access — Check Project Overlay
66
-
67
- The project overlay guide will specify:
68
- - Database project reference / instance name
69
- - Whether to use MCP connectors or daemon
70
- - Available RPC functions
71
- - Work item management patterns
72
-
73
- Read the project-specific agent-bootstrap.md overlay for exact connection details.
74
-
75
- ---
76
-
77
- ## Git Rules
78
-
79
- - Branch: Always use the project's primary development branch (typically `develop` or `main`)
80
- - Auto-commit after completing your scope — no confirmation needed
81
- - Commit message must use conventional format: `feat/fix/chore/refactor(<scope>): description`
82
- - Push to origin after committing
83
- - NEVER force-push
84
-
85
- ---
86
-
18
+
19
+ ## Credentials — Daemon Access Pattern
20
+
21
+ You do NOT have access to cloud MCP connectors. Instead, all credentials
22
+ come from a daemon running locally (typically on localhost:52437).
23
+
24
+ **Ping first to confirm availability:**
25
+ ```bash
26
+ curl -s http://127.0.0.1:52437/ping
27
+ ```
28
+ If it doesn't respond — report BLOCKED, do not proceed.
29
+
30
+ **Get a credential:**
31
+ ```bash
32
+ curl -s http://127.0.0.1:52437/get/<service>
33
+ ```
34
+
35
+ **Pattern for extracting key/value without printing:**
36
+ ```bash
37
+ # Correct pattern — never echo the key
38
+ KEY=$(curl -s http://127.0.0.1:52437/get/<service> | python3 -c "import sys,json; print(json.load(sys.stdin)['key'])")
39
+ curl -s -H "Authorization: Bearer $KEY" https://api.example.com/...
40
+ ```
41
+
42
+ **Never print credentials to stdout.** Capture to a variable, use inline, discard.
43
+
44
+ ---
45
+
46
+ ## Project Directory Convention
47
+
48
+ This plugin uses the `.rdc/` directory convention. Check for it first:
49
+
50
+ ```bash
51
+ # Check if .rdc/ exists at project root
52
+ ls {PROJECT_ROOT}/.rdc/config.json 2>/dev/null && echo "using .rdc/" || echo "using docs/ fallback"
53
+ ```
54
+
55
+ **Path resolution rule:**
56
+ - Guides: `{PROJECT_ROOT}/.rdc/guides/` → fallback: `{PROJECT_ROOT}/docs/guides/`
57
+ - Plans: `{PROJECT_ROOT}/.rdc/plans/` → fallback: `{PROJECT_ROOT}/docs/plans/`
58
+ - Reports: `{PROJECT_ROOT}/.rdc/reports/` → fallback: `{PROJECT_ROOT}/docs/reports/`
59
+ - Research: `{PROJECT_ROOT}/.rdc/research/` → fallback: `{PROJECT_ROOT}/docs/research/`
60
+
61
+ If `.rdc/config.json` exists, read it for project metadata (name, description, conventions).
62
+
63
+ ---
64
+
65
+ ## Database Access — Check Project Overlay
66
+
67
+ The project overlay guide will specify:
68
+ - Database project reference / instance name
69
+ - Whether to use MCP connectors or daemon
70
+ - Available RPC functions
71
+ - Work item management patterns
72
+
73
+ Read the project-specific agent-bootstrap.md overlay for exact connection details.
74
+
75
+ ---
76
+
77
+ ## Git Rules
78
+
79
+ - Branch: Always use the project's primary development branch (typically `develop` or `main`)
80
+ - Auto-commit after completing your scope — no confirmation needed
81
+ - Commit message must use conventional format: `feat/fix/chore/refactor(<scope>): description`
82
+ - Push to origin after committing
83
+ - NEVER force-push
84
+
85
+ ---
86
+
87
87
  ## Build Rules
88
88
 
89
89
  Never run `pnpm build` or equivalent full builds locally — they consume excessive memory.
90
90
  Type-check only: `npx tsc --noEmit --project <path>/tsconfig.json`
91
91
  Run tests only for modified packages: modify tests in isolation, not whole suite.
92
92
 
93
- ### No Foreground Windows
93
+ ### Terminal/process launches — caller-logged, not hard-blocked
94
94
 
95
- Agent-launched processes must not steal focus. This is a hard local-operator
96
- rule, not a preference.
95
+ **Narrowed 2026-08-26** (epic 688ad6da, lifeai-env; direct operator
96
+ instruction: "remove the PreToolUse foreground-window guard entirely...
97
+ replace it with caller-logging for traceability"). The old hard block on
98
+ every raw `Start-Process`/`cmd /c start`/window-focus API/bare `.ps1` launch
99
+ is retired — `foreground-process-gate.js` (rdc-skills) no longer enforces any
100
+ of it. The replacement isn't a weaker rule; it's a different mechanism:
101
+ lifeai-env's `lib/TermLaunch.psm1` (`Invoke-TermLaunchHidden` /
102
+ `Invoke-TermLaunchInteractive`) logs every caller (script + line + argv) to
103
+ `C:/Dev/.logs` **before** spawning, for every launch — which answers "who
104
+ launched this and with what" for every case, not just the ones a regex
105
+ pattern happened to catch.
97
106
 
98
- - Playwright must run headless. Do not use `--headed`, `--ui`, `codegen`, `open`, `show-report`, or `PWDEBUG=1` in agent sessions.
99
- - Use list/dot/json reporters and saved trace/report artifacts instead of opening the Playwright UI.
100
- - PowerShell helpers must use `-WindowStyle Hidden -NonInteractive`, or a hidden wrapper.
101
- - `Start-Process` must include `-WindowStyle Hidden` or `-WindowStyle Minimized`.
102
- - `cmd /c start` must use `/min` for intentionally visible tools or `/b` for background work.
103
- - Node/cmd/ps1 helpers launched by hooks must go through the RDC hidden hook runner.
107
+ - Use `Invoke-TermLaunchHidden -Command <cmd> [-Arguments][-WorkingDirectory]`
108
+ for a background/no-window process, and `Invoke-TermLaunchInteractive
109
+ [-Title]` for a visible new terminal tab never a raw `Start-Process`/
110
+ `wt.exe` call. Neither primitive accepts an arbitrary inline multi-line
111
+ command string, only a flat command + argument array or a `-File <script>`
112
+ path this structurally prevents the `wt.exe -Command` argv-mangling bug
113
+ class, which no amount of pattern-blocking ever fully closed.
114
+ - Node/cmd/ps1 helpers launched by hooks must still go through the RDC hidden
115
+ hook runner (`hooks/run-bash-hidden.ps1` and its RdcRun contract) — that
116
+ convention is unchanged.
117
+
118
+ **One safety property survives, unrelated to the above and never retired:**
119
+ Playwright must still run headless in agent sessions. Do not use `--headed`,
120
+ `--ui`, `codegen`, `open`, `show-report`, or `PWDEBUG=1`. Use list/dot/json
121
+ reporters and saved trace/report artifacts instead of opening the Playwright
122
+ UI. `foreground-process-gate.js` still hard-blocks this — it was never a
123
+ terminal-launch-primitive question, so narrowing the launch rules above never
124
+ touched it.
104
125
 
105
126
  Check the project overlay for specific language, package manager, and build constraints.
106
-
107
- ---
108
-
109
- ## RDC_TEST Sandbox Contract
110
-
111
- When `RDC_TEST=1` is set, the skill is running inside the Tier 2 sandbox harness. Short-circuit all destructive external side effects.
112
-
113
- **How to detect:** `process.env.RDC_TEST === '1'` (Node/JS) or `[ "$RDC_TEST" = "1" ]` (bash). The Tier 2 runner sets this before invoking `claude --print`.
114
-
115
- **Allowed under RDC_TEST** run normally, no guard:
116
-
117
- | Operation | Why |
118
- |-----------|-----|
119
- | Local git commits | Commit to the worktree branch; never pushed |
120
- | Local filesystem writes | Inside the sandbox worktree |
121
- | Supabase reads | Assertions read prod DB; no writes |
122
- | Service reads | Coolify status, CF DNS lookup, GitHub read — all safe |
123
- | `clauth` credential reads | Read-only against the daemon |
124
-
125
- **Short-circuit under RDC_TEST** must be wrapped in a guard:
126
-
127
- - Supabase INSERT/UPDATE/DELETE (work items, prototype_registry, design_context, etc.) — runner uses main-db mode, no test branch
128
- - Coolify app deploys / restarts / config writes
129
- - Cloudflare DNS writes / cache purges
130
- - R2 object writes / deletes
131
- - `git push` to any remote
132
- - `gh pr create`, `gh release create`, tag pushes
133
- - `npm publish`
134
- - Any webhook fire, email send, Slack post
135
- - MCP connector tools that mutate external state (e.g. `mcp__coolify__deploy`)
136
-
137
- **Bash pattern:**
138
- ```bash
139
- if [ "$RDC_TEST" != "1" ]; then
127
+
128
+ ### Harness Use — Global Policy (applies to every rdc:* skill)
129
+
130
+ If ANY step of the skill you are executing — regardless of which skill —
131
+ needs to materialize a real product shape, open a signed edit session, run a
132
+ target's own declared build gates, or deploy to dev-PM2/npm-registry, you
133
+ MUST use the real, tested `rdc-harness` CLI instead of hand-rolled bash/curl:
134
+
135
+ ```bash
136
+ node C:/Dev/rdc-harness/bin/rdc-harness.mjs <create|open|edit|build|deploy> <slug> --monorepo-root <your own worktree, never the shared checkout>
137
+ ```
138
+
139
+ One JSON receipt per call, exit 0/1 — use it as evidence for whatever
140
+ checklist/commit step it satisfies. This is a genuinely FORCED requirement,
141
+ not a suggestion: a skill that hand-rolls its own create/open/build/deploy
142
+ logic when this applies is doing exactly the duplicated, unproven work this
143
+ policy exists to stop.
144
+
145
+ This does NOT apply to a skill with no create/open/build/deploy step at all
146
+ (status/report/help/analysis/media/conversation skills)do not invent one.
147
+ `open`/`edit` require `RDC_HARNESS_ISSUER_SECRET` set explicitly, no default.
148
+ `deploy` has zero Coolify awareness (Coolify stays `rdc:deploy`'s own path)
149
+ and no live co-editing surface outside `site-html`/`site-ts` targets.
150
+
151
+ ---
152
+
153
+ ## RDC_TEST Sandbox Contract
154
+
155
+ When `RDC_TEST=1` is set, the skill is running inside the Tier 2 sandbox harness. Short-circuit all destructive external side effects.
156
+
157
+ **How to detect:** `process.env.RDC_TEST === '1'` (Node/JS) or `[ "$RDC_TEST" = "1" ]` (bash). The Tier 2 runner sets this before invoking `claude --print`.
158
+
159
+ **Allowed under RDC_TEST** — run normally, no guard:
160
+
161
+ | Operation | Why |
162
+ |-----------|-----|
163
+ | Local git commits | Commit to the worktree branch; never pushed |
164
+ | Local filesystem writes | Inside the sandbox worktree |
165
+ | Supabase reads | Assertions read prod DB; no writes |
166
+ | Service reads | Coolify status, CF DNS lookup, GitHub read — all safe |
167
+ | `clauth` credential reads | Read-only against the daemon |
168
+
169
+ **Short-circuit under RDC_TEST** — must be wrapped in a guard:
170
+
171
+ - Supabase INSERT/UPDATE/DELETE (work items, prototype_registry, design_context, etc.) — runner uses main-db mode, no test branch
172
+ - Coolify app deploys / restarts / config writes
173
+ - Cloudflare DNS writes / cache purges
174
+ - R2 object writes / deletes
175
+ - `git push` to any remote
176
+ - `gh pr create`, `gh release create`, tag pushes
177
+ - `npm publish`
178
+ - Any webhook fire, email send, Slack post
179
+ - MCP connector tools that mutate external state (e.g. `mcp__coolify__deploy`)
180
+
181
+ **Bash pattern:**
182
+ ```bash
183
+ if [ "$RDC_TEST" != "1" ]; then
140
184
  curl -X POST "$DEPLOY_API_BASE/api/v1/applications/$UUID/deploy" ...
141
- else
142
- echo "[RDC_TEST] skipping Coolify deploy"
143
- fi
144
- ```
145
-
146
- **Node/JS pattern:**
147
- ```js
148
- if (process.env.RDC_TEST !== '1') {
149
- await deployToCoolify(...);
150
- } else {
151
- console.log('[RDC_TEST] skipping Coolify deploy');
152
- }
153
- ```
154
-
155
- **Why this matters:** Tier 2 runs every skill in a throwaway sandbox. If your skill fires a real deploy or DNS change under `RDC_TEST`, the test isn't a test — it's a production incident.
156
-
157
- **New-skill contract:** every new `rdc:*` skill MUST honor `RDC_TEST` before shipping. Tier 2 manifests will fail any skill that writes to external state under the flag.
158
-
185
+ else
186
+ echo "[RDC_TEST] skipping Coolify deploy"
187
+ fi
188
+ ```
189
+
190
+ **Node/JS pattern:**
191
+ ```js
192
+ if (process.env.RDC_TEST !== '1') {
193
+ await deployToCoolify(...);
194
+ } else {
195
+ console.log('[RDC_TEST] skipping Coolify deploy');
196
+ }
197
+ ```
198
+
199
+ **Why this matters:** Tier 2 runs every skill in a throwaway sandbox. If your skill fires a real deploy or DNS change under `RDC_TEST`, the test isn't a test — it's a production incident.
200
+
201
+ **New-skill contract:** every new `rdc:*` skill MUST honor `RDC_TEST` before shipping. Tier 2 manifests will fail any skill that writes to external state under the flag.
202
+
159
203
  **Known blocker:** Project-specific cwd hooks must check `process.env.RDC_TEST === '1'` and call `process.exit(0)` early to allow Tier 2 sandbox runs. Without this bypass, headless self-test invocations can fail before the skill loads. File: `~/.claude/hooks/check-cwd.js`.
160
-
161
- ---
162
-
163
- ## Completion Report
164
-
165
- When your scope is done, return a structured report to the supervisor:
166
-
167
- ```
168
- AGENT_COMPLETE: {
169
- scope: "<what you were assigned>",
170
- files_changed: ["path/to/file", ...],
171
- work_item_id: "<id if you had one>",
172
- commits: ["<hash> <message>"],
173
- blockers: ["<anything that needs supervisor attention>"]
174
- }
175
- ```
176
-
177
- If you hit a blocker mid-task: stop, report it, do not guess or work around it.
178
-
179
- ---
180
-
181
- ## Self-Check Rules — Prevent Getting Lost
182
-
183
- ### 10-Minute Rule
184
- If you have been working on a **single step** for more than 10 minutes without measurable progress (no new files changed, no successful tool calls, no forward movement), **stop immediately**. Do not keep trying variations. Report it as a blocker.
185
-
186
- ### 2-Retry Rule
187
- If the **same command or approach fails twice**, stop. Do not attempt a third variation or creative workaround. Report the failure with the exact error output.
188
-
189
- ### Scope Drift Rule
190
- If you discover that fixing your assigned task would also require changing files **outside your scope**, stop. Do not fix them. Add them to `blockers` in your AGENT_COMPLETE report. The supervisor assigns them separately.
191
-
192
- ### What "measurable progress" means
193
- - A file was created or modified ✅
194
- - A tool call succeeded and returned useful data ✅
195
- - A command ran without error ✅
196
- - Trying the same thing with slightly different parameters ❌
197
- - Reading the same file again hoping for different insight ❌
198
- - Rephrasing a failing query ❌
199
-
200
- ---
201
-
204
+
205
+ ---
206
+
207
+ ## Completion Report
208
+
209
+ When your scope is done, return a structured report to the supervisor:
210
+
211
+ ```
212
+ AGENT_COMPLETE: {
213
+ scope: "<what you were assigned>",
214
+ files_changed: ["path/to/file", ...],
215
+ work_item_id: "<id if you had one>",
216
+ commits: ["<hash> <message>"],
217
+ blockers: ["<anything that needs supervisor attention>"]
218
+ }
219
+ ```
220
+
221
+ If you hit a blocker mid-task: stop, report it, do not guess or work around it.
222
+
223
+ ---
224
+
225
+ ## Self-Check Rules — Prevent Getting Lost
226
+
227
+ ### 10-Minute Rule
228
+ If you have been working on a **single step** for more than 10 minutes without measurable progress (no new files changed, no successful tool calls, no forward movement), **stop immediately**. Do not keep trying variations. Report it as a blocker.
229
+
230
+ ### 2-Retry Rule
231
+ If the **same command or approach fails twice**, stop. Do not attempt a third variation or creative workaround. Report the failure with the exact error output.
232
+
233
+ ### Scope Drift Rule
234
+ If you discover that fixing your assigned task would also require changing files **outside your scope**, stop. Do not fix them. Add them to `blockers` in your AGENT_COMPLETE report. The supervisor assigns them separately.
235
+
236
+ ### What "measurable progress" means
237
+ - A file was created or modified ✅
238
+ - A tool call succeeded and returned useful data ✅
239
+ - A command ran without error ✅
240
+ - Trying the same thing with slightly different parameters ❌
241
+ - Reading the same file again hoping for different insight ❌
242
+ - Rephrasing a failing query ❌
243
+
244
+ ---
245
+
202
246
  ## ⛔ Implementation Report + CodeFlow Exit Contract
203
247
 
204
248
  Every implementation agent MUST follow this protocol before moving a work item
205
249
  to `review`. Agents do not close non-epic work as `done`; validators close it
206
250
  after fresh verification.
207
-
208
- ### Step 1 — Tick checklist items as you complete them
209
-
251
+
252
+ ### Step 1 — Tick checklist items as you complete them
253
+
210
254
  ```sql
211
255
  SELECT update_checklist_item(
212
256
  '<work-item-id>'::uuid,
@@ -221,10 +265,10 @@ SELECT update_checklist_item(
221
265
  Call this for each item AS you complete it — not all at once at the end. The
222
266
  database records every tick in `work_item_checklist_events`. Supervisor and
223
267
  validator re-ticks are rejected by the exit gate.
224
-
225
- ### Step 2 — Submit implementation report BEFORE marking done
226
-
227
- ```sql
268
+
269
+ ### Step 2 — Submit implementation report BEFORE marking done
270
+
271
+ ```sql
228
272
  SELECT submit_implementation_report(
229
273
  '<work-item-id>'::uuid,
230
274
  '{
@@ -276,20 +320,20 @@ SELECT update_work_item_status(
276
320
  If any `required: true` checklist item is still unchecked, was re-ticked by a
277
321
  supervisor/validator, or was ticked by a different session than the originating
278
322
  agent, the DB and PreToolUse hook reject the close.
279
-
280
- ### Supervisor workflow
281
-
282
- - All zeros → clean run, proceed
283
- - `flags_count > 0` or `deviations_count > 0` → pull full report:
284
- ```sql
285
- SELECT implementation_report FROM work_items WHERE id = '<id>';
286
- ```
287
-
288
- ---
289
-
290
- ## Now read your role-specific guide
291
-
292
- Path: `{PROJECT_ROOT}/.rdc/guides/<type>.md` (e.g., `frontend.md`, `backend.md`, `data.md`)
293
- Fallback: `{PROJECT_ROOT}/docs/guides/<type>.md` if `.rdc/` does not exist.
294
-
295
- The project overlay will specify the exact location if it differs from the convention above.
323
+
324
+ ### Supervisor workflow
325
+
326
+ - All zeros → clean run, proceed
327
+ - `flags_count > 0` or `deviations_count > 0` → pull full report:
328
+ ```sql
329
+ SELECT implementation_report FROM work_items WHERE id = '<id>';
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Now read your role-specific guide
335
+
336
+ Path: `{PROJECT_ROOT}/.rdc/guides/<type>.md` (e.g., `frontend.md`, `backend.md`, `data.md`)
337
+ Fallback: `{PROJECT_ROOT}/docs/guides/<type>.md` if `.rdc/` does not exist.
338
+
339
+ The project overlay will specify the exact location if it differs from the convention above.
@@ -1,9 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * PreToolUse hook — block focus-stealing foreground process launches.
3
+ * PreToolUse hook — blocks Playwright headed/UI-mode invocations only.
4
+ *
5
+ * NARROWED 2026-08-26 (epic 688ad6da WP-4, lifeai-env). This file used to
6
+ * ALSO block every raw foreground process launch (Start-Process without
7
+ * -WindowStyle Hidden, cmd /c start without /min, window-focus Win32 APIs,
8
+ * bare PowerShell .ps1 launches) -- that entire class is retired per Dave's
9
+ * direct operator instruction: "remove the PreToolUse foreground-window
10
+ * guard entirely... replace it with caller-logging for traceability."
11
+ * lifeai-env's lib/TermLaunch.psm1 (Invoke-TermLaunchHidden /
12
+ * Invoke-TermLaunchInteractive) is the replacement -- it logs every caller
13
+ * (script + line + argv) to C:/Dev/.logs BEFORE spawning, which is strictly
14
+ * more informative than a hard block that told a caller only "add
15
+ * -WindowStyle Hidden" and never recorded who asked.
16
+ *
17
+ * checkPlaywright is a SEPARATE, unrelated concern (Design Decision D3,
18
+ * .rdc/plans/terminal-launch-consolidation.md in lifeai-env): agent
19
+ * sessions must never pop an interactive Playwright UI. That has nothing to
20
+ * do with terminal/process launch primitives, so it was deliberately kept
21
+ * here rather than folded into caller-logging, which would have silently
22
+ * dropped a real safety property this narrowing was never asked to remove.
23
+ * The filename is legacy -- kept to avoid an unrelated hookify-manifest
24
+ * rewire for a rename that changes nothing about what the file does.
4
25
  */
5
- 'use strict';
6
-
7
26
  const hookLog = require('./hook-logger');
8
27
 
9
28
  function readStdin() {
@@ -35,35 +54,6 @@ function toolText(raw) {
35
54
  try { return JSON.stringify(raw.tool_input || raw); } catch { return ''; }
36
55
  }
37
56
 
38
- function hasHiddenIntent(command) {
39
- return /-WindowStyle\s+Hidden/i.test(command) ||
40
- /-WindowStyle\s+Minimized/i.test(command) ||
41
- /windowsHide\s*:\s*true/i.test(command) ||
42
- /CreateNoWindow\s*=\s*\$?true/i.test(command) ||
43
- /Start-Job\b/i.test(command) ||
44
- /--background\b/i.test(command) ||
45
- /\bHEADLESS\s*=\s*(1|true)\b/i.test(command) ||
46
- /\bCI\s*=\s*(1|true)\b/i.test(command);
47
- }
48
-
49
- function hasExplicitWindowOverride(command) {
50
- return /\bRDC_ALLOW_WINDOW_FOCUS\s*=\s*(1|true)\b/i.test(command) ||
51
- /\bRDC_INTERACTIVE_WINDOW\s*=\s*(1|true)\b/i.test(command);
52
- }
53
-
54
- function checkWindowFocusApi(command) {
55
- if (hasExplicitWindowOverride(command)) return;
56
- const focusApi = /\b(SetForegroundWindow|SwitchToThisWindow|AppActivate|SetWindowPos|ShowWindowAsync?|BringWindowToTop)\b/i;
57
- const broadWindowApi = /\b(EnumWindows|Get-Process\s+\|\s*Where-Object|GetWindow|FindWindow)\b/i;
58
- const windowMutation = /\b(minimi[sz]e|restore|foreground|focus|activate|collapse)\b/i;
59
- if (focusApi.test(command) || (broadWindowApi.test(command) && windowMutation.test(command))) {
60
- block(
61
- 'Window focus/restore/minimize/collapse operations are not allowed in agent-launched commands. Spawn helpers hidden/no-window instead; set RDC_ALLOW_WINDOW_FOCUS=1 only for an explicitly requested interactive recovery action.',
62
- { kind: 'window-focus-api' },
63
- );
64
- }
65
- }
66
-
67
57
  function checkPlaywright(command) {
68
58
  if (!/\b(playwright|@playwright\/test)\b/i.test(command)) return;
69
59
 
@@ -82,45 +72,13 @@ function checkPlaywright(command) {
82
72
  }
83
73
  }
84
74
 
85
- function checkPowerShell(command) {
86
- if (!/\bStart-Process\b/i.test(command)) return;
87
- if (hasHiddenIntent(command)) return;
88
- block(
89
- '`Start-Process` must include `-WindowStyle Hidden` or `-WindowStyle Minimized` for agent-launched node/cmd/ps1/test processes. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
90
- { kind: 'start-process' },
91
- );
92
- }
93
-
94
- function checkCmdStart(command) {
95
- if (!/\bcmd(?:\.exe)?\s+\/c\s+start\b/i.test(command)) return;
96
- if (/\bcmd(?:\.exe)?\s+\/c\s+start\s+(""|''|`"")?\s*\/b\b/i.test(command)) return;
97
- block(
98
- '`cmd /c start` must use `/min` or `/b` for background tools. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
99
- { kind: 'cmd-start' },
100
- );
101
- }
102
-
103
- function checkDirectShellLaunch(command) {
104
- if (hasHiddenIntent(command)) return;
105
- if (/\bpowershell(?:\.exe)?\b[^|\n]*(?:-File\s+[^|\n]*\.ps1|\.ps1\b)/i.test(command)) {
106
- block(
107
- 'PowerShell script launches from agent tooling must use `-WindowStyle Hidden -NonInteractive` or a hidden wrapper.',
108
- { kind: 'powershell-ps1' },
109
- );
110
- }
111
- }
112
-
113
75
  async function main() {
114
76
  let raw;
115
77
  try { raw = JSON.parse(await readStdin()); } catch { process.exit(0); }
116
78
  const command = toolText(raw);
117
79
  if (!command) pass({ reason: 'no-command' });
118
80
 
119
- checkWindowFocusApi(command);
120
81
  checkPlaywright(command);
121
- checkPowerShell(command);
122
- checkCmdStart(command);
123
- checkDirectShellLaunch(command);
124
82
 
125
83
  pass({ reason: 'clean' });
126
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.35.4",
3
+ "version": "0.35.5",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -44,7 +44,7 @@
44
44
  "validate": "node tests/validate-skills.js",
45
45
  "rdc-design": "node scripts/rdc-design-cli.mjs",
46
46
  "test:hooks": "node scripts/test-rdc-hooks.mjs",
47
- "test:truth-gate": "node tests/run-evidence-gate.test.mjs && node tests/work-item-exit-gate-l2.test.mjs && node tests/work-item-exit-gate-l3.test.mjs && node tests/require-work-item-on-commit.test.mjs && node tests/harness-gates.test.mjs",
47
+ "test:truth-gate": "node tests/run-evidence-gate.test.mjs && node tests/work-item-exit-gate-l2.test.mjs && node tests/work-item-exit-gate-l3.test.mjs && node tests/require-work-item-on-commit.test.mjs && node tests/harness-gates.test.mjs && node tests/foreground-process-gate.test.mjs",
48
48
  "test:acceptance": "node tests/acceptance.test.mjs && node tests/install-rdc-skills.test.mjs && node tests/help-surface.test.mjs && node tests/manifest-contract-fields.test.mjs && node tests/plugin-namespace-names.test.mjs && node tests/skill-test-matrix.test.mjs && node tests/completion-gate-supervisor-admission.test.mjs && node tests/curl-surface.test.mjs && node tests/clauth-plugin-postinstall.test.mjs",
49
49
  "acceptance": "node scripts/acceptance.mjs --changed",
50
50
  "test:mcp": "node tests/mcp.test.mjs",
@@ -13,6 +13,7 @@ description: >-
13
13
  rdc:review step 8b+, or standalone before merging a new package/module.
14
14
  ---
15
15
 
16
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
16
17
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
17
18
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
18
19
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -3,6 +3,7 @@ name: behavior-audit
3
3
  description: "Usage `rdc:behavior-audit <report-dir> [--since-days N] [--latest N] [--reprocess]` — produces a bounded, redacted Claude/Codex transcript evidence bundle, incrementally skips completed transcript hashes, and aligns candidate behavior problems to shared truth-governance rules."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **OUTPUT CONTRACT:** Begin and end with the same checklist. Do not call an audit clean, complete, or compliant without the evidence-bundle manifest and an independent validator decision.
7
8
 
8
9
  # rdc:behavior-audit — Cross-Engine Truth and Behavior Audit
@@ -3,6 +3,7 @@ name: brochure
3
3
  description: "Usage `rdc:brochure <input> [--out <path>] [--template <name>] [--format Letter|A4]` — Turn a zip, folder, HTML file, URL, or markdown folder into a print-quality PDF brochure via Puppeteer. Auto-detects print-variant HTML, honors @page CSS, falls back to a Studio-token-aware template when no HTML exists."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -12,6 +12,7 @@ triggers:
12
12
  - monkey_dispatch payload with skill="brochurify"
13
13
  ---
14
14
 
15
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
15
16
  # rdc:brochurify Orchestrator
16
17
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
17
18
  > Report brochure job state, artifacts, and blockers directly; do not dump raw tool logs.
@@ -8,6 +8,7 @@ description: >-
8
8
  mechanical AST checks, not LLM judgment — see `scripts/clean-code-score.mjs`.
9
9
  ---
10
10
 
11
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
11
12
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
12
13
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
13
14
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -3,6 +3,7 @@ name: convert
3
3
  description: "Usage `rdc:convert <input> [--out <dir>] [--to markdown|word] [--images assets|base64|s3]` — Convert .docx/.pptx/.ppt → Markdown (Word OMML equations as KaTeX TeX, tables, images) or Markdown → Word via the build-corpus CLI from npm `regen.mde`. Portable: runs in any session that can reach npm — Claude Code CLI, Codex, and claude.ai can fetch + run it. Use whenever the user asks to convert an Office document, build a Markdown corpus from .docx/.pptx, turn Markdown into a .docx, or open the report in the regen-mde editor on Windows."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  # rdc:convert — Office ↔ Markdown conversion (build-corpus) + regen-mde editor
7
8
 
8
9
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
@@ -14,6 +14,18 @@ description: "Usage `rdc:edit <site|brand|route|file>` — open the local websit
14
14
 
15
15
  # rdc:edit — Local Website Editor Launcher
16
16
 
17
+ **This skill is the designated handler `rdc-harness` dispatches to.**
18
+ `packages/work/src/editors.mjs`'s `BY_CLASS` table maps `site-html`/`site-ts`
19
+ product classes to editor id `'rdc:edit'` — when an agent calls
20
+ `node C:/Dev/rdc-harness/bin/rdc-harness.mjs edit <slug>` against a website
21
+ target, its receipt names `editorId: 'rdc:edit'` and an `editableBoundary`.
22
+ This skill IS that handler: resolve the same target, launch/reuse the editor
23
+ host, use the harness's `editableBoundary` as the save boundary if the call
24
+ originated from a harness `edit` receipt. Every other product class
25
+ (`app`/`package`/`mcp`/`model`/`artifact`) maps to editor id `'source'` — a
26
+ boundary-checked file save with no live/co-editing surface at all; that gap
27
+ is real and unbuilt, not something this skill covers.
28
+
17
29
  ## When to Use
18
30
  - The user wants to open a site, brand, route, or file in the local editor app
19
31
  - The user says "open this in the editor" or asks for the editor-host workflow
@@ -3,6 +3,7 @@ name: env
3
3
  description: "Usage `rdc:env [status|install|repair|update]` — Manage the LIFEAI environment harness: check status, install on a fresh box, repair broken services, or pull updates. Reads $LIFEAI_ENV/manifest.json as the source of truth. Use when: 'check the environment', 'install environment', 'repair environment', 'update environment', 'setup env', 'fix env', 'env status', or after a reboot/GPU crash."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -12,6 +12,7 @@ triggers:
12
12
  - nightly cron at 3:00 AM PT
13
13
  ---
14
14
 
15
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
15
16
  # rdc:extract-verifier-rules
16
17
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
17
18
  > Return candidate rules, evidence, and PR status directly; do not dump raw tool logs.
@@ -3,6 +3,7 @@ name: fs-mcp
3
3
  description: "Usage `rdc:fs-mcp <task>` — Use the File System MCP bridge for live repo reads, safe writes, cloud-to-local ingest, and GitHub-branch imports into a dirty local monorepo. Use when Claude.ai, Cowork, or CLI agents need fs_read/fs_write/fs_import_git_files guidance."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -3,6 +3,7 @@ name: help
3
3
  description: "Usage `rdc:help` — Show all MCP skills with usage, requirements, slash forms, and codeflow status. Reads `.claude-plugin/plugin.json` skills_meta (single source of truth). Call when unsure which skill to use or what args it takes."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
 
@@ -20,6 +20,7 @@ required_validators:
20
20
  blocking: true
21
21
  ---
22
22
 
23
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
23
24
  # LIFEAI Brochure Authoring Contract
24
25
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
25
26
  > Return the authored JSX guidance or verification result directly; do not dump raw tool logs.
@@ -18,6 +18,7 @@ description: >
18
18
  Trigger when asked to create, register, or check whether a reference model exists.
19
19
  ---
20
20
 
21
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
21
22
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
22
23
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
23
24
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -6,6 +6,7 @@ description: >-
6
6
  and sit at the right size.
7
7
  ---
8
8
 
9
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
9
10
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
10
11
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
11
12
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -8,6 +8,7 @@ description: >-
8
8
  only; never rewrites code itself.
9
9
  ---
10
10
 
11
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
11
12
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
12
13
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
13
14
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -6,6 +6,7 @@ description: >-
6
6
  concrete before/after refactor plan. Produces a plan, does not apply it.
7
7
  ---
8
8
 
9
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
9
10
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
10
11
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
11
12
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -3,6 +3,7 @@ name: refactor
3
3
  description: "Usage `rdc:refactor <epic-id|topic> --takeover <reason>` — Governed consolidation and implementation of a cross-cutting refactor. Authorizes an explicit takeover, preserves evidence, re-parents relevant work through the consolidation RPC, isolates every writer, and uses the same review, validator, landing, and delivery gates as rdc:build."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **OUTPUT CONTRACT:** `guides/output-contract.md`
7
8
 
8
9
  # rdc:refactor
@@ -3,6 +3,7 @@ name: regen-media
3
3
  description: "Usage `rdc:regen-media <generate|edit|upscale|upload> <brief-or-path>` - Primary image-generation and Regen Media asset workflow. Use for image generation, image editing/upscaling, GPT Image/gpt-image-2 requests, Codex built-in image_gen, and uploading finished images to regen-media/R2. The default path is keyless local Codex gpt-image-2 via the built-in image_gen tool; server-side regen-media MCP/API generation is fallback only."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -8,6 +8,7 @@ description: >-
8
8
  `scripts/solid-score.mjs` for the mechanism.
9
9
  ---
10
10
 
11
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
11
12
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
12
13
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
13
14
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -3,6 +3,7 @@ name: terminal-config
3
3
  description: "Usage `rdc:terminal-config <task>` — read and safely modify Windows Terminal settings, shell profiles, and agent startup sequencing without relying on machine-specific paths."
4
4
  ---
5
5
 
6
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
6
7
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
8
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
9
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -8,6 +8,7 @@ description: >-
8
8
  covers whether a surface's behavior is actually provable, and how.
9
9
  ---
10
10
 
11
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `.rdc/guides/agent-bootstrap.md`) — this is also where the global rdc-harness-use policy for create/open/build/deploy work lives.
11
12
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
12
13
  > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
13
14
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * foreground-process-gate.js — narrowed to Playwright headed/UI-mode only
4
+ * (epic 688ad6da WP-4, lifeai-env). Four window-focus/process-launch checks
5
+ * (checkWindowFocusApi, checkPowerShell, checkCmdStart, checkDirectShellLaunch)
6
+ * were removed; the replacement is lifeai-env's lib/TermLaunch.psm1 caller-
7
+ * logging, which lives in a different repo and is not this file's job to
8
+ * re-implement or re-check.
9
+ *
10
+ * This file's job is now to prove two things stay true going forward:
11
+ * 1. The four retired checks no longer block anything -- a real regression
12
+ * here would silently reintroduce ceremony an operator explicitly
13
+ * retired, with no other test anywhere positioned to catch it.
14
+ * 2. checkPlaywright survives untouched (Design Decision D3) -- this is a
15
+ * SEPARATE safety property, not part of the terminal-launch
16
+ * consolidation, and narrowing the file must never have narrowed this.
17
+ *
18
+ * Run: node tests/foreground-process-gate.test.mjs
19
+ */
20
+ import { dirname, join, resolve } from 'node:path';
21
+ import { fileURLToPath } from 'node:url';
22
+ import { spawnSync } from 'node:child_process';
23
+
24
+ const __dirname = dirname(fileURLToPath(import.meta.url));
25
+ const REPO_ROOT = resolve(__dirname, '..');
26
+ const HOOK = join(REPO_ROOT, 'hooks', 'foreground-process-gate.js');
27
+
28
+ const failures = [];
29
+ function assert(name, condition, detail = '') {
30
+ if (!condition) failures.push(`${name}${detail ? `: ${detail}` : ''}`);
31
+ else process.stdout.write(` ok ${name}\n`);
32
+ }
33
+
34
+ function runGate(command) {
35
+ const res = spawnSync(process.execPath, [HOOK], {
36
+ input: JSON.stringify({ tool_name: 'Bash', tool_input: { command } }),
37
+ encoding: 'utf8',
38
+ });
39
+ const blocked = res.status === 1;
40
+ return { blocked, stdout: res.stdout, status: res.status };
41
+ }
42
+
43
+ // ===========================================================================
44
+ // 1. The four retired checks no longer block anything.
45
+ // ===========================================================================
46
+
47
+ {
48
+ const r = runGate('Start-Process -FilePath node.exe -ArgumentList "server.js"');
49
+ assert('Start-Process with no -WindowStyle Hidden no longer blocks (checkPowerShell retired)',
50
+ r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
51
+ }
52
+
53
+ {
54
+ const r = runGate('cmd /c start node.exe server.js');
55
+ assert('cmd /c start without /min no longer blocks (checkCmdStart retired)',
56
+ r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
57
+ }
58
+
59
+ {
60
+ const r = runGate('powershell.exe -File C:\\Dev\\some-script.ps1');
61
+ assert('bare PowerShell .ps1 launch no longer blocks (checkDirectShellLaunch retired)',
62
+ r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
63
+ }
64
+
65
+ {
66
+ const r = runGate('[Win32]::SetForegroundWindow($handle)');
67
+ assert('a window-focus Win32 API call no longer blocks (checkWindowFocusApi retired)',
68
+ r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
69
+ }
70
+
71
+ // ===========================================================================
72
+ // 2. checkPlaywright survives, untouched -- a separate safety property.
73
+ // ===========================================================================
74
+
75
+ {
76
+ const r = runGate('npx playwright test --headed');
77
+ assert('Playwright --headed still blocks',
78
+ r.blocked === true, `status=${r.status} stdout=${r.stdout}`);
79
+ assert('Playwright --headed block message names the right reason',
80
+ /must run headless/.test(r.stdout), r.stdout);
81
+ }
82
+
83
+ {
84
+ const r = runGate('PWDEBUG=1 npx playwright test');
85
+ assert('Playwright PWDEBUG=1 still blocks',
86
+ r.blocked === true, `status=${r.status} stdout=${r.stdout}`);
87
+ }
88
+
89
+ {
90
+ const r = runGate('npx playwright show-report');
91
+ assert('Playwright show-report still blocks',
92
+ r.blocked === true, `status=${r.status} stdout=${r.stdout}`);
93
+ assert('Playwright show-report block message names the right reason',
94
+ /launches foreground UI/.test(r.stdout), r.stdout);
95
+ }
96
+
97
+ {
98
+ const r = runGate('npx playwright test --reporter=list');
99
+ assert('an ordinary headless Playwright run is NOT blocked',
100
+ r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
101
+ }
102
+
103
+ {
104
+ const r = runGate('git status');
105
+ assert('an unrelated ordinary command passes clean', r.blocked === false, `status=${r.status} stdout=${r.stdout}`);
106
+ }
107
+
108
+ // ===========================================================================
109
+ if (failures.length > 0) {
110
+ console.error('\nforeground-process-gate tests — FAIL\n');
111
+ for (const f of failures) console.error(` - ${f}`);
112
+ process.exit(1);
113
+ }
114
+ console.log('\nforeground-process-gate tests — PASS');
@@ -146,34 +146,16 @@ const WI = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
146
146
  }
147
147
 
148
148
  // ===========================================================================
149
- // 2. foreground-process-gate.js
149
+ // 2. foreground-process-gate.js — moved to its own file, tests/foreground-process-gate.test.mjs
150
+ //
151
+ // Narrowed 2026-08-26 (epic 688ad6da WP-4, lifeai-env): the window-focus/
152
+ // process-launch checks this section used to assert (SetForegroundWindow
153
+ // blocking, hidden/minimized allowances) were retired — that whole class is
154
+ // now caller-logged by lifeai-env's lib/TermLaunch.psm1, not hard-blocked
155
+ // here. The dedicated test file covers what remains (checkPlaywright) plus
156
+ // asserts the four retired checks stay retired, so removing this embedded
157
+ // section is not a coverage loss — see that file instead.
150
158
  // ===========================================================================
151
- {
152
- const focusPayload = {
153
- tool_input: {
154
- command: "powershell -NoProfile -Command \"Add-Type '[DllImport(\\\"user32.dll\\\")] public static extern bool SetForegroundWindow(System.IntPtr hWnd);'\"",
155
- },
156
- };
157
- const r = runHook('foreground-process-gate.js', focusPayload, {});
158
- assert('FPG blocks SetForegroundWindow focus API', r.status === 1, `status=${r.status} ${r.stdout}${r.stderr}`);
159
- assert('FPG block mentions window focus operations', /Window focus\/restore\/minimize\/collapse/.test(r.stdout + r.stderr));
160
-
161
- const hiddenPayload = {
162
- tool_input: {
163
- command: 'powershell.exe -NoProfile -NonInteractive -WindowStyle Hidden -File ".\\\\scripts\\\\helper.ps1"',
164
- },
165
- };
166
- const h = runHook('foreground-process-gate.js', hiddenPayload, {});
167
- assert('FPG allows hidden PowerShell helper', h.status === 0, `status=${h.status} ${h.stdout}${h.stderr}`);
168
-
169
- const minimizedPayload = {
170
- tool_input: {
171
- command: 'Start-Process powershell.exe -WindowStyle Minimized -ArgumentList "-NoProfile"',
172
- },
173
- };
174
- const m = runHook('foreground-process-gate.js', minimizedPayload, {});
175
- assert('FPG allows minimized Start-Process without focus APIs', m.status === 0, `status=${m.status} ${m.stdout}${m.stderr}`);
176
- }
177
159
 
178
160
  // ===========================================================================
179
161
  // 3. post-tool-batch-gate.js