@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.
- package/.claude-plugin/plugin.json +1 -1
- package/commands/build.md +19 -0
- package/commands/deploy.md +20 -1
- package/commands/fixit.md +17 -0
- package/commands/flow.md +94 -0
- package/commands/mode.md +6 -0
- package/commands/release.md +11 -0
- package/guides/agent-bootstrap.md +248 -204
- package/hooks/foreground-process-gate.js +22 -64
- package/package.json +2 -2
- package/skills/architecture-reviewer/SKILL.md +1 -0
- package/skills/behavior-audit/SKILL.md +1 -0
- package/skills/brochure/SKILL.md +1 -0
- package/skills/brochurify/SKILL.md +1 -0
- package/skills/clean-code-analyzer/SKILL.md +1 -0
- package/skills/convert/SKILL.md +1 -0
- package/skills/edit/SKILL.md +12 -0
- package/skills/env/SKILL.md +1 -0
- package/skills/extract-verifier-rules/SKILL.md +1 -0
- package/skills/fs-mcp/SKILL.md +1 -0
- package/skills/help/SKILL.md +1 -0
- package/skills/lifeai-brochure-author/SKILL.md +1 -0
- package/skills/new-model/SKILL.md +1 -0
- package/skills/package-design/SKILL.md +1 -0
- package/skills/pattern-advisor/SKILL.md +1 -0
- package/skills/pattern-refactoring-guide/SKILL.md +1 -0
- package/skills/refactor/SKILL.md +1 -0
- package/skills/regen-media/SKILL.md +1 -0
- package/skills/solid-validator/SKILL.md +1 -0
- package/skills/terminal-config/SKILL.md +1 -0
- package/skills/testing-strategy/SKILL.md +1 -0
- package/tests/foreground-process-gate.test.mjs +114 -0
- package/tests/harness-gates.test.mjs +9 -27
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:**
|
package/commands/deploy.md
CHANGED
|
@@ -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
|
|
35
|
+
### Mode 0 — dev <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"]')`
|
package/commands/flow.md
ADDED
|
@@ -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
|
package/commands/release.md
CHANGED
|
@@ -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
|
-
###
|
|
93
|
+
### Terminal/process launches — caller-logged, not hard-blocked
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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 —
|
|
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.
|
|
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
|
package/skills/brochure/SKILL.md
CHANGED
|
@@ -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.
|
package/skills/convert/SKILL.md
CHANGED
|
@@ -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`
|
package/skills/edit/SKILL.md
CHANGED
|
@@ -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
|
package/skills/env/SKILL.md
CHANGED
|
@@ -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.
|
package/skills/fs-mcp/SKILL.md
CHANGED
|
@@ -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.
|
package/skills/help/SKILL.md
CHANGED
|
@@ -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.
|
package/skills/refactor/SKILL.md
CHANGED
|
@@ -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
|