@lifeaitools/rdc-skills 0.26.2 → 0.26.4

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.26.0",
3
+ "version": "0.26.3",
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",
@@ -1574,6 +1574,30 @@
1574
1574
  "enabled_default": true,
1575
1575
  "codeflow_required": false
1576
1576
  },
1577
+ "behavior-audit": {
1578
+ "name": "behavior-audit",
1579
+ "slash": "rdc:behavior-audit",
1580
+ "category": "reporting",
1581
+ "usage": "rdc:behavior-audit <report-dir> [--since-days N] [--latest N] [--reprocess]",
1582
+ "args": {
1583
+ "positional": [{ "name": "report-dir", "required": true, "description": "Bounded directory for the evidence bundle.", "accepts": "path" }],
1584
+ "flags": [
1585
+ { "name": "--since-days", "type": "number", "default": 7, "description": "Only include transcripts modified within the window." },
1586
+ { "name": "--latest", "type": "number", "default": null, "description": "Limit to the newest N sessions per engine." },
1587
+ { "name": "--reprocess", "type": "boolean", "default": false, "description": "Intentionally parse completed hashes again without deleting the ledger." }
1588
+ ]
1589
+ },
1590
+ "requires": ["codeflow", "work-items-rpc"],
1591
+ "produces": ["work_items", ".rdc/reports/"],
1592
+ "default_model": "inherit",
1593
+ "triggers": ["audit transcript calls", "audit codex behavior", "audit claude behavior", "truth gate audit", "review behavior evidence", "why did the agent bypass the gate"],
1594
+ "follows": ["workitems"],
1595
+ "leads_to": ["review"],
1596
+ "sandbox_aware": false,
1597
+ "output_contract": "guides/output-contract.md",
1598
+ "enabled_default": true,
1599
+ "codeflow_required": true
1600
+ },
1577
1601
  "onramp": {
1578
1602
  "name": "onramp",
1579
1603
  "slash": "rdc:onramp",
package/README.md CHANGED
@@ -181,7 +181,7 @@ Throughout the skills, the following substitutions have been made to make them p
181
181
 
182
182
  ## Skills Overview
183
183
 
184
- 34 MCP skills organized into 8 manifest categories. Nineteen of these also have
184
+ 36 MCP skills organized into 8 manifest categories. Nineteen of these also have
185
185
  `/rdc:*` command shorthands for Claude Code/plugin callers.
186
186
 
187
187
  Use `rdc_skill_list` for the authoritative live catalog, including names,
@@ -303,6 +303,7 @@ Boundaries:
303
303
 
304
304
  ```
305
305
  skills/
306
+ behavior-audit/SKILL.md (governed behavior and policy audit)
306
307
  brochure/SKILL.md (print-quality PDF rendering)
307
308
  build/SKILL.md (dispatch agents in waves — mandatory validator gate)
308
309
  channel-formatter/SKILL.md (channel-native formatting and content packs)
package/RELEASE.md CHANGED
@@ -27,11 +27,16 @@ git checkout master
27
27
  git pull --ff-only origin master
28
28
  git merge <feature-branch> --no-edit
29
29
 
30
- # 2. Bump the version
30
+ # 2. Bump the version — package.json AND the plugin manifest, they must match.
31
+ # rdc-skills-self-test fails the whole run (plugin manifest FAIL) if they drift,
32
+ # and .claude-plugin/plugin.json ships inside the published npm package, so a
33
+ # stale plugin.json version is a real defect in the release, not a lint nit.
31
34
  npm version patch|minor|major --no-git-tag-version
35
+ # then hand-edit .claude-plugin/plugin.json's top-level "version" field to match —
36
+ # there is no script for this yet, only the self-test catches drift after the fact.
32
37
 
33
38
  # 3. Commit, tag, and push
34
- git add package.json package-lock.json
39
+ git add package.json .claude-plugin/plugin.json
35
40
  git commit -m "release: v$(node -e \"console.log(require('./package.json').version)\")"
36
41
  git tag "v$(node -e \"console.log(require('./package.json').version)\")"
37
42
  git push origin master --tags
@@ -43,6 +48,9 @@ npm view @lifeaitools/rdc-skills version
43
48
  npm install -g @lifeaitools/rdc-skills@latest
44
49
  npm list -g @lifeaitools/rdc-skills --depth=0
45
50
  rdc-skills-self-test
51
+ # ^ run this LAST and read the verdict line, not just the section pass counts —
52
+ # a plugin-manifest version mismatch prints as a single top-line FAIL above the
53
+ # skill/guide tables, which all pass independently of it. Exit code 1 on drift.
46
54
  ```
47
55
 
48
56
  ## Public MCP release gate
@@ -61,11 +69,19 @@ The public `/health` version must equal the released npm version and its skill
61
69
  count must match the packaged catalog. The local installer never restarts or
62
70
  deploys that endpoint.
63
71
 
64
- The Vultr host checks out this repository at `/srv/regen/rdc-skills`. Install or
65
- refresh its standalone systemd unit after pulling `master`:
72
+ The Vultr host checks out this repository at `/srv/regen/rdc-skills` it runs
73
+ straight from the checkout (no `npm install`), so `/health`'s `git_sha` comes
74
+ from `bin/rdc-skills-mcp.mjs`'s runtime `git rev-parse HEAD` fallback, NOT a
75
+ stamped `git-sha.json` (that file is `.gitignore`d on purpose — it's a
76
+ pack-time-only artifact for npm-installed copies; see the comment above its
77
+ `.gitignore` entry). `install-systemd.sh` alone does not restart the running
78
+ process. After pulling `master`:
66
79
 
67
80
  ```bash
68
- sudo ./deploy/install-systemd.sh
81
+ git pull --ff-only origin master
82
+ sudo ./deploy/install-systemd.sh # re-verify/re-enable the unit config
83
+ sudo systemctl restart rdc-skills-mcp.service # actually load the new commit
84
+ curl -fsS https://rdc-skills.regendevcorp.com/health # confirm git_sha == new HEAD
69
85
  ```
70
86
 
71
87
  Port `3110` is reserved for this public MCP ingress. Application fleet manifests
package/commands/build.md CHANGED
@@ -71,12 +71,21 @@ Read the task title and description, then:
71
71
 
72
72
  ## Procedure
73
73
 
74
- 1. **Load the epic:**
74
+ 1. **Load the epic and its durable admission decisions:**
75
75
  ```sql
76
- SELECT get_work_items_by_epic('<epic-id>', 'todo');
76
+ SELECT get_work_items_by_epic('<epic-id>');
77
77
  ```
78
+ - Read `design_review_state` and `status` for every executable child.
79
+ - Only `automatic_approved`, `human_approved`, or legacy `not_required` rows may be considered for dispatch.
80
+ - For `pending`, `needs_human`, or `rejected`, write an `admission_refocus` receipt, keep the child blocked, and route it to the reviewer/planner. **Do not dispatch it, retry it, or call the epic complete.**
78
81
  - Interactive (no args): show open epics, ask which to build
79
82
  - Unattended (no tasks found): escalate via advisor tool
83
+ - **Read the epic's `plan_ref`, `spec_ref`, `architecture_ref`, and `scoping_statement` fields** (returned on the epic row itself). `scoping_statement` bounds what this build may touch — do not silently expand past it. If `architecture_ref` is set, this epic crosses an architectural boundary: read that doc now, before classifying or dispatching any task, and carry it into every agent prompt in step 7.
84
+
85
+ 1a. **Run the durable CodeFlow supervisor before each wave and after every gate-changing action.**
86
+ - Invoke `runOrchestrator()` with the project manifest, `SupabaseStateStore`, and the real phase dispatcher. It is the sole authority for resuming/refocusing a phase DAG; do not reconstruct waves by hand from task prose.
87
+ - A returned `admission_refocus` or `pipeline_blocked` is a durable hold, not a failed attempt to work around. Preserve its task state and route the required Design Review or validator closure.
88
+ - Only a returned `pipeline_complete` whose phase tasks are all design-review admitted **and** durably `done` permits an epic completion claim. If the project lacks a real dispatcher/manifest, report `BLOCKED: CodeFlow supervisor entrypoint unavailable` rather than emulating completion.
80
89
 
81
90
  2. **CHECK FOR EXISTING WORK (mandatory — never skip):**
82
91
  ```sql
@@ -103,7 +112,7 @@ Read the task title and description, then:
103
112
 
104
113
  5. **Classify each task** → assign agent type from the table above.
105
114
 
106
- 6. **Group tasks into waves** — parallelize tasks with no file overlap:
115
+ 6. **Use the supervisor-resolved waves** — parallelize only phases returned by `runOrchestrator()` after its durable admission check:
107
116
  - Wave 1: independent tasks (different packages/files)
108
117
  - Wave 2: tasks that depend on Wave 1 outputs
109
118
  - Wave 3: integration tasks
@@ -114,7 +123,9 @@ Read the task title and description, then:
114
123
  - `"Read {PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md first (fallback: .rdc/guides/agent-bootstrap.md), then {PROJECT_ROOT}/.rdc/guides/<type>.md (fallback: .rdc/guides/<type>.md) before starting."`
115
124
  - Specific files to create/modify
116
125
  - Exact deliverables and commit message
126
+ - The epic's `scoping_statement` — explicit boundary on what this task may and may not touch
117
127
  - `"NEVER run pnpm build/test. NEVER modify files outside your scope."`
128
+ - **If the epic's `architecture_ref` is set:** include `"Read <architecture_ref> before implementing. Your task's checklist requires a checked architecture-fidelity-<slug> row before this item can close — when you tick it, its evidence must cite the specific section/boundary of <architecture_ref> your implementation conforms to, not just 'done'."` A task under an `architecture_ref` epic will hard-fail at the exit gate (step 9) without this row checked with real evidence.
118
129
  - Use `run_in_background: true` for parallel execution
119
130
  - NEVER let agents overlap on the same files
120
131
 
@@ -133,6 +144,8 @@ Read the task title and description, then:
133
144
  - Verify commit landed on the development branch
134
145
  - Push to origin *(skip if `$RDC_TEST=1` — echo `[RDC_TEST] skipping git push` instead)*
135
146
  - Ensure the agent submitted `implementation_report.codeflow_post`, then set the work item to `review`; the validator closes `done`
147
+ - Re-invoke `runOrchestrator()` after the durable status/gate update. A task in `review` remains incomplete even when its phase gate passed.
148
+ - **If the epic's `architecture_ref` is set:** before the validator attempts `done`, confirm the task's checklist has a checked `architecture-fidelity-*` row with real evidence (a cited doc section, not a bare "matches"). `update_work_item_status(..., 'done')` will hard-reject otherwise — catching this here avoids a wasted validator round-trip.
136
149
  - Continue to next wave
137
150
 
138
151
  **If an agent fails:**
@@ -160,7 +173,7 @@ Read the task title and description, then:
160
173
  echo "[RDC_TEST] skipping git push origin {development-branch}"
161
174
  fi
162
175
  ```
163
- - Update epic version: `bump_epic_version()`
176
+ - Re-invoke `runOrchestrator()` and require its `pipeline_complete` receipt before `bump_epic_version()` or any epic completion claim. A clean code review or green test suite is not a substitute for admitted, validator-closed work items.
164
177
  - Report summary with verification evidence quoted
165
178
 
166
179
  ## Agent TDD Requirements
@@ -178,6 +191,7 @@ NEVER run pnpm build or pnpm turbo. Use npx vitest run only.
178
191
  - NEVER run `pnpm build` (crashes system) — code only
179
192
  - Every agent reads its guide file — no exceptions
180
193
  - Update Supabase work items IN REAL TIME — not batch at end
194
+ - **Never dispatch, resume, or complete around `design_review_state`; the durable database result and `runOrchestrator()` receipt win over an agent's narrative**
181
195
  - Push after each wave, not just at the end
182
196
  - Unattended: NEVER pause — continue automatically
183
197
  - Unattended: max 2 retries per task before escalating to advisor
@@ -105,6 +105,19 @@ SELECT insert_work_item(
105
105
  p_source := 'planning'
106
106
  );
107
107
 
108
+ -- Immediately populate governance refs — the handoff's plan doc IS the plan_ref/spec_ref.
109
+ -- Set architecture_ref ONLY when this handoff crosses an architectural boundary (storage
110
+ -- authority, process topology, auth boundary, deployment model, persistence, service
111
+ -- ownership, public contract); leave it NULL for ordinary feature work, or every task
112
+ -- below gets held for a review it doesn't need.
113
+ SELECT set_epic_governance_refs(
114
+ p_epic_id := '<epic-uuid>'::uuid,
115
+ p_plan_ref := '.rdc/plans/<topic-slug>.md',
116
+ p_spec_ref := '.rdc/plans/<topic-slug>.md',
117
+ p_architecture_ref := '<docs/systems/<system>/ARCHITECTURE.md or NULL>',
118
+ p_scoping_statement := '<one paragraph: what is explicitly in scope and what is explicitly out of scope>'
119
+ );
120
+
108
121
  -- Create tasks (one per work package)
109
122
  SELECT insert_work_item(
110
123
  p_title := '<Package Name>',
@@ -121,6 +134,9 @@ Est: <hours>',
121
134
  p_labels := ARRAY['<label>'],
122
135
  p_estimated_hours := 2,
123
136
  p_source := 'planning'
137
+ -- If the epic has architecture_ref set, also add a required
138
+ -- architecture-fidelity-<slug> checklist row via p_checklist here — the exit gate
139
+ -- hard-rejects `done` on any task under an architecture_ref epic that lacks one.
124
140
  );
125
141
  ```
126
142
 
@@ -101,6 +101,7 @@ rdc:plan <epic-id> --unattended
101
101
 
102
102
  Check `PLAN_STATUS.task_count > 0` before continuing.
103
103
  If 0 tasks created: escalate via advisor, then skip if still unresolved.
104
+ If `PLAN_STATUS.held_for_design_review > 0`: do not silently promote those tasks to todo. Log the held task IDs and their durable assessment, request human Design Review, and continue only with the independently admitted portion of the epic.
104
105
 
105
106
  ### 3c. Build
106
107
 
@@ -114,6 +115,7 @@ Agents receive the relevant guide file from `.rdc/guides/` (fallback: `.rdc/guid
114
115
 
115
116
  After each wave: check `BUILD_STATUS`. If `escalated: true`, log the escalation
116
117
  in the overnight doc and continue — don't stop the loop.
118
+ After each wave and after every resumed epic, require the `runOrchestrator()` receipt from `rdc:build`. `admission_refocus` or `pipeline_blocked` means the epic is held for durable Design Review or validator closure; log that state and do not hand-reconstruct a dispatch wave.
117
119
 
118
120
  ### 3d. Review
119
121
 
@@ -122,7 +124,7 @@ rdc:review --unattended
122
124
  ```
123
125
 
124
126
  Check `REVIEW_STATUS.verdict`:
125
- - `"CLEAN"`: mark epic `done` in work_items, push, continue to next epic
127
+ - `"CLEAN"`: re-run the durable CodeFlow supervisor. Mark an epic `done` only when its receipt is `pipeline_complete` and every executable child is design-review admitted and validator-closed (`status = done`); otherwise preserve the epic/task hold and log `admission_refocus` or `pipeline_blocked`.
126
128
  - `"HAS_ISSUES"` with `escalations > 0`: log issues, push what's clean, continue
127
129
  - `"HAS_ISSUES"` with `escalations = 0` (all auto-fixed): push, continue
128
130
 
@@ -215,6 +217,7 @@ Provide the advisor with:
215
217
  - NEVER let agents overlap on the same files
216
218
  - Push after every epic, not just at the end
217
219
  - Update Supabase work items in real time throughout
220
+ - **A clean review never overrides a durable Design Review hold, an incomplete checklist, or missing validator closure**
218
221
  - Max 2 hours per epic — if exceeded, skip and log `TIMEOUT`
219
222
  - If credential daemon goes down mid-session: write current state to overnight doc, push, exit gracefully
220
223
  - If git push fails: log the failure, attempt rebase, retry once — do not force push
package/commands/plan.md CHANGED
@@ -107,6 +107,11 @@ description: >-
107
107
  - Include the guide file path (from `.rdc/guides/`, fallback `.rdc/guides/`) in each work package description
108
108
  - Include any relevant architecture doc, context file, or package CLAUDE.md the agent must read
109
109
  - Estimate: small (1 agent, <500 LOC), medium (1 agent, 500-1500 LOC), large (needs splitting)
110
+ - Attach a **Design Review contract** to every executable package. It must contain:
111
+ - architecture alignment: registered architecture-evidence reference(s), declared target boundary, and a concrete alignment claim;
112
+ - completeness: independently observable acceptance criteria plus at least one required `decomp-*` and `test-*` checklist row; and
113
+ - proportionality: estimated files/LOC, declared surfaces, and change kind.
114
+ - Do not invent architecture evidence. Missing, unregistered, broad-refactor, multi-surface, or disproportionate contracts are intentionally routed to human Design Review.
110
115
 
111
116
  6. **Write plan doc** to `.rdc/plans/<topic-slug>.md` (fallback: `.rdc/plans/<topic-slug>.md` if `.rdc/` does not exist):
112
117
  ```markdown
@@ -127,14 +132,19 @@ description: >-
127
132
 
128
133
  7. **Create Supabase epic + child tasks:**
129
134
  - Epic via `insert_work_item(p_item_type := 'epic', ...)`
130
- - One task per work package via `insert_work_item(p_parent_id := <epic_id>, ...)`
135
+ - Immediately call `set_epic_governance_refs(p_epic_id, p_plan_ref := '.rdc/plans/<topic-slug>.md', p_spec_ref := '.rdc/plans/<topic-slug>.md', p_architecture_ref := '<ARCHITECTURE.md path or NULL — set only when this plan crosses an architectural boundary>', p_scoping_statement := '<in/out of scope, one paragraph>')` so `rdc:build`/`rdc:overnight`/`rdc:fixit`/`rdc:refactor` never have to guess or stall on these fields
136
+ - One task per work package only through `upsert_admitted_work_item(...)`, never a direct `work_items` write. Supply a stable source fingerprint, the package checklist, and the Design Review contract from Step 5.
137
+ - Read the durable result for each package:
138
+ - `dispatchable: true` / `automatic_approved` → task may become `todo`;
139
+ - `dispatchable: false` / `needs_human` or `pending` → keep the task `blocked`, label it `needs-human-design-review`, and include the assessment in the plan status.
140
+ - If (and only if) the epic's `architecture_ref` is set, each task's checklist passed to `upsert_admitted_work_item` MUST also include one required `architecture-fidelity-<slug>` row naming the specific architecture doc + boundary — the exit gate hard-rejects `done` on any task under an `architecture_ref` epic missing this row. Do not add it under an epic with no `architecture_ref` — that holds ordinary work for a review it doesn't need.
131
141
  - Set priorities: urgent/high/normal based on sequencing
132
142
 
133
143
  8. **Report results:**
134
144
  - Interactive: present the plan for approval before building
135
145
  - Unattended: skip approval, proceed immediately, emit status block:
136
146
  ```
137
- PLAN_STATUS: { epic_id, task_count, doc_path, waves, source_docs_read: [list], architecture_conflicts: [] }
147
+ PLAN_STATUS: { epic_id, task_count, dispatchable_task_count, held_for_design_review, doc_path, waves, source_docs_read: [list], architecture_conflicts: [] }
138
148
  ```
139
149
 
140
150
  ## Unattended Escalation
@@ -153,6 +163,7 @@ choose the most conservative/reversible approach and document the decision.
153
163
  - Each work package must be independently executable by an agent
154
164
  - No file overlap between work packages
155
165
  - Include test requirements in every work package
166
+ - **No executable work item is dispatchable without a durable Design Review decision; a planner cannot self-approve by supplying prose-only evidence**
156
167
  - Reference affected CLAUDE.md files and architecture docs in each work package description
157
168
  - Reference the relevant guide file from `.rdc/guides/` (fallback: `.rdc/guides/`) for agent context
158
169
  - Always list source docs read in the output doc header and status block
@@ -39,6 +39,18 @@ SELECT insert_work_item(
39
39
  p_labels := ARRAY['system-label'],
40
40
  p_source := 'planning'
41
41
  );
42
+
43
+ -- Immediately populate governance refs. architecture_ref stays NULL unless this epic
44
+ -- crosses an architectural boundary (storage authority, process topology, auth boundary,
45
+ -- deployment model, persistence, service ownership, public contract) — setting it holds
46
+ -- every child task for a required architecture-fidelity-* checklist row at close time.
47
+ SELECT set_epic_governance_refs(
48
+ p_epic_id := '<epic-uuid>'::uuid,
49
+ p_plan_ref := '.rdc/plans/<n>.md or NULL',
50
+ p_spec_ref := '.rdc/plans/<n>.md or NULL',
51
+ p_architecture_ref := NULL,
52
+ p_scoping_statement := '<one paragraph: what is in scope and what is explicitly out>'
53
+ );
42
54
  ```
43
55
 
44
56
  ## Create Task
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.26.2",
3
+ "version": "0.26.4",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -35,7 +35,7 @@
35
35
  "rdc-design": "node scripts/rdc-design-cli.mjs",
36
36
  "test:hooks": "node scripts/test-rdc-hooks.mjs",
37
37
  "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",
38
- "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/skill-test-matrix.test.mjs && node tests/curl-surface.test.mjs",
38
+ "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/skill-test-matrix.test.mjs && node tests/completion-gate-supervisor-admission.test.mjs && node tests/curl-surface.test.mjs",
39
39
  "acceptance": "node scripts/acceptance.mjs --changed",
40
40
  "test:mcp": "node tests/mcp.test.mjs",
41
41
  "test:mcp:remote": "node tests/mcp.test.mjs --remote",
@@ -27,6 +27,7 @@ const fs = require('fs');
27
27
  const path = require('path');
28
28
  const https = require('https');
29
29
  const http = require('http');
30
+ const { execFileSync } = require('child_process');
30
31
 
31
32
  // ---------------------------------------------------------------------------
32
33
  // CLI argument parsing
@@ -68,7 +69,35 @@ for (let i = 0; i < args.length; i++) {
68
69
  // Constants
69
70
  // ---------------------------------------------------------------------------
70
71
 
71
- const MONOREPO_ROOT = 'C:/Dev/regen-root';
72
+ /**
73
+ * Resolve the regen-root monorepo checkout this run should validate against.
74
+ *
75
+ * 2026-07-26 (lesson 2026-07-26-deploy-worktree-validator-root): hardcoding
76
+ * 'C:/Dev/regen-root' made every check run against the main tree even when
77
+ * this validator was invoked from a registered worktree lane
78
+ * (`C:/Dev/regen-root.wt/<lane>`), so a newly-landed app's PUBLISH.md read as
79
+ * "not found" though the file existed on the lane's own branch.
80
+ *
81
+ * Resolution order: explicit override env var, then `git rev-parse
82
+ * --show-toplevel` from the caller's cwd (works for the main tree AND any
83
+ * worktree lane), then the historical default as a last resort.
84
+ */
85
+ function resolveMonorepoRoot() {
86
+ if (process.env.REGEN_ROOT) return process.env.REGEN_ROOT;
87
+ if (process.env.PROJECT_ROOT) return process.env.PROJECT_ROOT;
88
+ try {
89
+ const top = execFileSync('git', ['rev-parse', '--show-toplevel'], {
90
+ cwd: process.cwd(),
91
+ encoding: 'utf8',
92
+ }).trim();
93
+ if (top) return top;
94
+ } catch {
95
+ // Not inside a git checkout (or git unavailable) — fall through to the default.
96
+ }
97
+ return 'C:/Dev/regen-root';
98
+ }
99
+
100
+ const MONOREPO_ROOT = resolveMonorepoRoot();
72
101
  const CLAUTH_BASE = 'http://127.0.0.1:52437';
73
102
 
74
103
  // Ordered list of root-relative prefixes to probe when looking for app source
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: rdc:behavior-audit
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
+ ---
5
+
6
+ > **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
+ # rdc:behavior-audit — Cross-Engine Truth and Behavior Audit
9
+
10
+ ## When to Use
11
+
12
+ - Audit transcript calls, truth-gate behavior, premature closure, evidence provenance, or cross-engine enforcement drift.
13
+ - Create a bounded redacted evidence bundle for a behavior-governance work item.
14
+ - Do not use this skill to alter source transcripts, deploy services, or self-certify a behavioral conclusion.
15
+
16
+ ## Required Inputs
17
+
18
+ - `<report-dir>`: a bounded output directory, for example `reports/behavior-audit/2026-08-08`.
19
+ - Optional `--since-days N`, `--latest N`, or `--reprocess` scope controls.
20
+ - The current repository must contain `scripts/transcript_call_matrix.py`; block if it is absent rather than inventing a collector.
21
+
22
+ ## Procedure
23
+
24
+ 1. Create or claim a work item before collection. Its checklist must cover scope, provenance, redaction, rule alignment, independent review, and validator closure.
25
+ 2. Resolve the repository root with `git rev-parse --show-toplevel`, then run CodeFlow context before reading project sources.
26
+ 3. Run the collector from the repository root: `python -B scripts/transcript_call_matrix.py --since-days 7 --format none --report-dir <report-dir> --processing-ledger .rdc/state/transcript-call-processing.json`.
27
+ 4. Require `manifest.json`, `tool-call-matrix.html`, `tool-call-totals.csv`, `locators.jsonl`, and `problems.jsonl` in `<report-dir>`.
28
+ 5. Confirm every locator's transcript SHA matches its processed session and that secret-shaped material is absent from problem excerpts.
29
+ 6. Classify each finding as an observation, causal hypothesis, intervention, or validator decision; do not elevate an observation into a diagnosis.
30
+ 7. Align findings to `mission-contract-non-bypassable`, `independent-validator`, `mandatory-independent-review`, `evidence-provenance`, `no-premature-completion`, and `cross-engine-parity`.
31
+ 8. Dispatch independent review and a separate validator for collector or skill changes. The collecting executor cannot close the work item.
32
+
33
+ ## Decision Rules
34
+
35
+ - An empty evidence set is a validator decision (`not_applicable`), not executor proof of compliance.
36
+ - A failed collector or incomplete report leaves transcript hashes unmarked; repair and rerun.
37
+ - A changed transcript hash is new evidence even if the filename and session ID are unchanged.
38
+ - Report structural facts until a verifier attests broader behavior claims.
39
+ - Never deploy, promote, alter enforcement hooks, or rewrite transcripts as part of this audit unless a linked work item explicitly authorizes it.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Behavior Audit"
3
+ short_description: "Audit Claude and Codex behavior against shared rules."
4
+ default_prompt: "Run a behavior audit for the last seven days and write the evidence bundle to a report directory."
@@ -72,10 +72,20 @@ Read the task title and description, then:
72
72
 
73
73
  ## Procedure
74
74
 
75
- 1. **Load the epic and run pre-flight gate:**
75
+ 1. **Load the epic, durable admission decisions, and run the pre-flight gate:**
76
76
  ```sql
77
- SELECT get_work_items_by_epic('<epic-id>', 'todo');
77
+ SELECT get_work_items_by_epic('<epic-id>');
78
78
  ```
79
+ - Read `design_review_state` and `status` for every executable child.
80
+ - Only `automatic_approved`, `human_approved`, or legacy `not_required` rows may be considered for dispatch.
81
+ - For `pending`, `needs_human`, or `rejected`, write an `admission_refocus` receipt, keep the child blocked, and route it to the reviewer/planner. **Do not dispatch it, retry it, or call the epic complete.**
82
+
83
+ 1a. **Run the durable CodeFlow supervisor before each wave and after every gate-changing action.**
84
+ - Invoke `runOrchestrator()` with the project manifest, `SupabaseStateStore`, and the real phase dispatcher. It is the sole authority for resuming/refocusing a phase DAG; do not reconstruct waves by hand from task prose.
85
+ - A returned `admission_refocus` or `pipeline_blocked` is a durable hold, not a failed attempt to work around. Preserve its task state and route the required Design Review or validator closure.
86
+ - Only a returned `pipeline_complete` whose phase tasks are all design-review admitted **and** durably `done` permits an epic completion claim. If the project lacks a real dispatcher/manifest, report `BLOCKED: CodeFlow supervisor entrypoint unavailable` rather than emulating completion.
87
+
88
+ **Read the epic's `plan_ref`, `spec_ref`, `architecture_ref`, and `scoping_statement`** (columns on the epic row). `scoping_statement` bounds what this build may touch. If `architecture_ref` is set, this epic crosses an architectural boundary — read that doc now, before classifying or dispatching any task, and carry it into every agent prompt below.
79
89
 
80
90
  **Session lock — claim the epic immediately (before any agent dispatch):**
81
91
 
@@ -103,6 +113,7 @@ Read the task title and description, then:
103
113
  | Plan doc missing `## Checklist Quality Gate` with `verdict: PASS` | → Invoke `rdc:plan` on this epic. Do NOT dispatch agents. |
104
114
  | Any implementation task lacks `decomp-*` items, has < 10 attested rows, or leaves a declared surface (screen/api/db/tool) uncovered | → Invoke `rdc:plan` on this epic. Coarse/under-decomposed checklists cannot be safely dispatched. |
105
115
  | Any `decomp-*` item lacks route/file, action, expected result, or evidence artifact | → Invoke `rdc:plan` on this epic. Do NOT dispatch agents. |
116
+ | Epic has `architecture_ref` set and any implementation task's checklist lacks a required `architecture-fidelity-*` row | → Invoke `rdc:plan` on this epic. That task will hard-fail the exit gate at close regardless of build quality — catch it here, not after a wasted agent run. |
106
117
  | Tasks exist and have descriptions | → Continue with build. |
107
118
 
108
119
  **Re-planning is not a failure — it is correct behavior.** The build skill is the last gate before agent dispatch; catching an under-specified epic here is cheaper than a wasted agent run.
@@ -296,7 +307,7 @@ Read the task title and description, then:
296
307
  The agent must complete every item on this checklist and return it checked off in AGENT_COMPLETE.
297
308
  A checklist with unchecked items = incomplete work. Do not proceed to next wave with unchecked items.
298
309
 
299
- 6. **Group tasks into waves** — parallelize tasks with no file overlap:
310
+ 6. **Use the supervisor-resolved waves** — parallelize only phases returned by `runOrchestrator()` after its durable admission check:
300
311
  - Wave 1: independent tasks (different packages/files)
301
312
  - Wave 2: tasks that depend on Wave 1 outputs
302
313
  - Wave 3: integration tasks
@@ -488,6 +499,10 @@ Read the task title and description, then:
488
499
  - test-contract-xxx: <description> → verify the export/type/shape exists
489
500
  Tick each item as you complete it. Do NOT batch — tick immediately after each verification.
490
501
  ```
502
+ - **If the epic's `architecture_ref` is set**, the task's checklist carries a required `architecture-fidelity-*` row. Include it verbatim and instruct the agent:
503
+ ```
504
+ ARCHITECTURE FIDELITY — this epic crosses an architectural boundary (<architecture_ref>). Read that doc before implementing. Before ticking architecture-fidelity-<slug>, your implementation must actually conform to it — tick it via update_checklist_item(..., p_actor_role := 'agent') with evidence that cites the specific section/boundary, not a bare "done". update_work_item_status(..., 'done') hard-rejects this task without this row checked.
505
+ ```
491
506
  - Use `run_in_background: true` for parallel execution
492
507
  - NEVER let agents overlap on the same files
493
508
 
@@ -543,6 +558,7 @@ Read the task title and description, then:
543
558
 
544
559
  - Resolve any conflicts before proceeding — do not skip
545
560
  - Worker agents set items to `review` — **do NOT close to `done` yet**
561
+ - Re-invoke `runOrchestrator()` after the durable status/gate update. A task in `review` remains incomplete even when its phase gate passed.
546
562
  - After all branches merged, push once:
547
563
  ```bash
548
564
  if [ "$RDC_TEST" != "1" ]; then
@@ -633,7 +649,7 @@ Read the task title and description, then:
633
649
 
634
650
  11. **After verification passes:**
635
651
  - All wave commits are already on develop and pushed (Step 9 pushes after each wave merge).
636
- - Update epic version: `bump_epic_version()`
652
+ - Re-invoke `runOrchestrator()` and require its `pipeline_complete` receipt before `bump_epic_version()` or any epic completion claim. A clean code review or green test suite is not a substitute for admitted, validator-closed work items.
637
653
  - Report summary with verification evidence quoted
638
654
 
639
655
  ## Agent TDD Requirements
@@ -651,6 +667,7 @@ NEVER run pnpm build or pnpm turbo. Use npx vitest run only.
651
667
  - NEVER run `pnpm build` (crashes system) — code only
652
668
  - Every agent reads its guide file — no exceptions
653
669
  - Update Supabase work items IN REAL TIME — not batch at end
670
+ - **Never dispatch, resume, or complete around `design_review_state`; the durable database result and `runOrchestrator()` receipt win over an agent's narrative**
654
671
  - Push after each wave, not just at the end
655
672
  - Unattended: NEVER pause — continue automatically
656
673
  - Unattended: max 2 retries per task before escalating to advisor
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rdc:deploy
3
- description: "Usage `rdc:deploy <slug> [new|diagnose|audit|promote|convert] [--fix|--hotfix <sha>]` or `rdc:deploy maintenance <service>` Deploy applications or operate a private Coolify infrastructure service with guarded, internal-only checks."
3
+ description: "Usage `rdc:deploy <slug> [promote|diagnose|audit|convert]` registry-resolved PM2 development deployment and Coolify production promotion through clauth's bearer-authenticated job control plane, with status receipts and mandatory content gates."
4
4
  ---
5
5
 
6
6
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
@@ -8,14 +8,14 @@ description: "Usage `rdc:deploy <slug> [new|diagnose|audit|promote|convert] [--f
8
8
  > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
9
9
 
10
10
 
11
- # rdc:deploy — Coolify Operations
11
+ # rdc:deploy — Bearer Deployment Control Plane
12
12
 
13
13
  **READ FIRST:** `guides/output-contract.md`. Checklist-only output. No narration.
14
14
  No raw MCP dumps. No UUIDs unless asked.
15
15
 
16
16
  > **Sandbox contract:** This skill honors `RDC_TEST=1` per `guides/agent-bootstrap.md` § RDC_TEST Sandbox Contract. Destructive external calls short-circuit under the flag.
17
17
  >
18
- > *Under `$RDC_TEST=1`:* Modes 1 (deploy), 2 (new), and 5 (promote) are **entirely skipped** — echo `[RDC_TEST] skipping Coolify deploy/create/promote` and mark every `[ ]` line in those checklists as `[~]`. Modes 3 (diagnose) and 4 (audit without `--fix`) are **read-only and run normally**. Mode 4 with `--fix` skips all remediation — echo `[RDC_TEST] skipping audit --fix remediation` and report findings only. Registry SELECTs, Coolify status reads, HTTP gate probes, TLS checks, and DNS lookups are NOT destructive and run normally. Anything that writes (create app, set watch_paths, deploy trigger, **PR/admin-merge to main**, env var write, DNS write, CF cache purge, registry UPDATE/INSERT) is gated.
18
+ > *Under `$RDC_TEST=1`:* Modes 1 (PM2 dev deploy), 2 (new), and 5 (Coolify promote) are **entirely skipped** — echo `[RDC_TEST] skipping PM2 deploy/create/Coolify promote` and mark every `[ ]` line in those checklists as `[~]`. Modes 3 (diagnose) and 4 (audit without `--fix`) are **read-only and run normally**. Mode 4 with `--fix` skips all remediation — echo `[RDC_TEST] skipping audit --fix remediation` and report findings only. Registry SELECTs, Coolify status reads, HTTP gate probes, TLS checks, and DNS lookups are NOT destructive and run normally. Anything that writes (create app, set watch_paths, deploy trigger, **PR/admin-merge to main**, env var write, DNS write, CF cache purge, registry UPDATE/INSERT) is gated.
19
19
 
20
20
  ## When to Use
21
21
  - Project lead says "deploy", "ship it", "push to production", "update the server"
@@ -28,8 +28,8 @@ No raw MCP dumps. No UUIDs unless asked.
28
28
 
29
29
  ## Arguments
30
30
 
31
- - `rdc:deploy <slug>` — deploy existing app (latest commit on its watched branch)
32
- - `rdc:deploy <slug> <build-id>` — deploy specific commit/tag
31
+ - `rdc:deploy <slug>` — submit the registered `develop` deployment to the PM2 dev target
32
+ - `rdc:deploy <slug> <ref>` — submit one registered manifest ref (never arbitrary shell or repository input)
33
33
  - `rdc:deploy <slug> promote` — promote the verified `develop` change for this app to production (Mode 5)
34
34
  - `rdc:deploy <slug> promote --hotfix <sha>` — promote a specific commit (cherry-pick just that sha to `main`)
35
35
  - `rdc:deploy <slug> convert` — convert a prod app's runtime in place from static→Next (Mode 6); use when dev is Next but prod is still a static Coolify build
@@ -42,25 +42,24 @@ No raw MCP dumps. No UUIDs unless asked.
42
42
 
43
43
  ## Modes
44
44
 
45
- ### Mode 1 — deploy <slug> [build-id]
45
+ ### Mode 1 — deploy <slug> [ref]
46
46
 
47
47
  ```
48
- rdc:deploy: <slug> → <domain>
48
+ rdc:deploy: <slug> → PM2 dev target
49
49
  [ ] Registry lookup (slug, uuid, branch, type, env_vars_needed)
50
50
  [ ] Runtime-source guard: if the source being deployed is static (`sites/<name>`, nixpacks/static) but the registry `runtime` for <slug> is `next`, BLOCK — never deploy a flat/static source over a Next app. A static prototype deploys only under its OWN slug (never an existing Next app's slug), dev only. Changing a slug's runtime is architectural. (`.claude/rules/production-stack-nextjs.md`)
51
- [ ] Git state verified (branch matches Coolify, commit pushed)
52
- [ ] Build-id resolved (default: HEAD of watched branch)
53
- [ ] Env vars present in Coolify (compare to registry)
54
- [ ] Type-specific preflight (see docs/runbooks/coolify-deploy-checklist.md)
51
+ [ ] Git state verified (registered ref is pushed to origin)
52
+ [ ] Dev deployment manifest resolved (application, repo path, fixed build argv, PM2 name, allowed ref, health URL)
53
+ [ ] Local clauth retrieves `vultr-ops-api-token` internally; bearer is never printed or passed by an agent
55
54
  [ ] Mandatory pre-deploy code-review (pr-review-toolkit:code-reviewer on `git diff <last-deployed-sha>..HEAD` for this app's paths). Block deploy on `critical`/`high` findings; record `medium`/`low` and proceed.
56
55
  [ ] PUBLISH.md read from app root (warn if absent; fail if present but invalid)
57
56
  [ ] watch_paths derived from PUBLISH.md surfaces (union of all surface watch_paths arrays) and updated in app_deployments
58
- [ ] Deploy triggered
59
- [ ] Deployment reached "finished" state
57
+ [ ] `clauth ops deploy --endpoint <control-plane> --application <slug> --ref <registered-ref>` accepted (202)
58
+ [ ] Job polled at `GET /v1/ops/jobs/<id>` to terminal state; receipt proves checkout SHA, build, PM2 reload, and health probe
60
59
  [ ] Gate: HTTP 200
61
60
  [ ] Gate: TLS valid (no SSL cipher mismatch)
62
61
  [ ] Gate: cache headers correct on HTML
63
- [ ] Gate: container running on declared port
62
+ [ ] Gate: named PM2 process is online at its declared port
64
63
  [ ] Gate: metadata audit (see § Metadata Audit below) — warn on gaps, do not block deploy
65
64
  [ ] Cloudflare cache purged (if proxied)
66
65
  [ ] artifact_registry INSERT per PUBLISH.md surface (if PUBLISH.md present)
@@ -68,27 +67,19 @@ rdc:deploy: <slug> → <domain>
68
67
  ✅ rdc:deploy: <slug> deployed in Nm Ns
69
68
  ```
70
69
 
71
- #### Static PM2 dev sites — do NOT trust the push webhook (SSH-reset + served-hash gate)
70
+ #### Static PM2 dev sites — bearer job + served-content gate
72
71
 
73
- For a **static** PM2 dev site, `git push` succeeding does NOT mean the live site
74
- updated: the push webhook skips/instruments static apps unreliably, so the host
75
- working tree (and the committed `dist/` it serves) can stay STUCK across several
76
- pushes while HTTP stays 200 and `origin/develop` looks shipped (lesson
77
- 2026-06-11-deploy-static-host-stuck: issho served the v1.10.0 bundle across three
78
- pushes because `/srv/regen/regen-root` never pulled). The only signal is the
79
- SERVED bundle hash vs the local `dist/` hash.
72
+ For a **static** PM2 dev site, a successful `git push` is not deployment proof:
73
+ the formerly unreliable webhook could leave the host working tree and committed
74
+ `dist/` stale while HTTP still returned 200. The agent MUST submit the same
75
+ manifest-scoped `clauth ops deploy` job used by every other dev runtime, then
76
+ record its checkout SHA, declared build, PM2 reload, and health receipt.
80
77
 
81
- After pushing committed `dist/`, SSH-reset the host explicitly, then verify the
82
- served hash:
83
- ```bash
84
- _K=$(mktemp); curl -s http://127.0.0.1:52437/v/vultr-dev-ssh > "$_K"; printf '\n' >> "$_K"; chmod 600 "$_K"
85
- ssh -i "$_K" root@64.237.54.189 'cd /srv/regen/regen-root && git fetch -q origin develop && git reset -q --hard origin/develop && pm2 restart <app> --update-env'
86
- rm -f "$_K"
87
- # Then verify SERVED hash == local build hash (HTTP 200 is NOT proof):
88
- curl -s https://<app>.dev.place.fund/ | grep -oE 'index-[A-Za-z0-9_-]+\.js' # served
89
- grep -oE 'index-[A-Za-z0-9_-]+\.js' sites/<app>/dist/index.html # local
90
- ```
91
- Only when the two hashes match do the content/screenshot gates mean anything.
78
+ Agents MUST NOT retrieve `vultr-dev-ssh`, stage private keys, run raw SSH, reset
79
+ the host checkout, or invoke PM2 directly. If a served-asset hash or content
80
+ marker does not match the declared build after the job reaches `succeeded`, mark
81
+ the deployment verification failed and use `rdc:deploy <slug> diagnose`; only
82
+ the server-operations recovery procedure may perform host-level repair.
92
83
 
93
84
  ### Mode 2 — new <slug>
94
85
 
@@ -246,14 +237,13 @@ rdc:deploy promote: <slug> → <prod-domain>
246
237
  ✅ rdc:deploy promote: <slug> live in prod — <changed-string> verified
247
238
  ```
248
239
 
249
- **The explicit Coolify trigger (the whole point — do not skip):**
250
- ```bash
251
- _COOLIFY=$(curl -s http://127.0.0.1:52437/v/coolify-api)
252
- # Correct endpoint is GET /api/v1/deploy?uuid= NOT POST /applications/<uuid>/deploy (that 404s)
253
- curl -s -H "Authorization: Bearer $_COOLIFY" \
254
- "$DEPLOY_API_BASE/api/v1/deploy?uuid=<PROD_UUID>&force=true"
255
- # → {"deployments":[{"deployment_uuid":"...","message":"...deployment queued."}]}
256
- ```
240
+ **The explicit Coolify trigger (the whole point — do not skip):** submit
241
+ `clauth ops promote --endpoint <control-plane> --application <registered-coolify-uuid>`.
242
+ The local client retrieves `vultr-ops-api-token` internally; the server-side
243
+ allowlist owns the Coolify UUID and keeps `coolify-api` out of agent inputs and
244
+ transcripts. Poll the returned job or subscribe to
245
+ `GET /v1/ops/jobs/<id>/events` until the redacted receipt reaches a terminal
246
+ state.
257
247
 
258
248
  **Why each guard exists (lessons from 2026-06-05 EF Hooper promote):**
259
249
  - `main` branch protection rejects PR merge without `--admin`; a raw `git push …:main` is blocked by the main-push hook → must go branch → PR → admin-merge.
@@ -487,52 +477,27 @@ ON CONFLICT (entity_slug, surface_id) DO UPDATE SET
487
477
 
488
478
  If the INSERT fails, surface the failure in the deploy output but **do NOT roll back the deploy**. The artifact registry is a post-deploy record, not a deploy gate.
489
479
 
490
- ## Coolify Access — clauth + REST API
480
+ ## Control-plane Access — clauth bearer jobs
491
481
 
492
- All Coolify operations use the clauth daemon and the Coolify REST API directly.
493
- There is no Coolify MCP server. Do not reference `@masonator/coolify-mcp`.
482
+ There is no Coolify MCP server. Agent-facing deploy and promotion operations use
483
+ the clauth control plane, not raw PM2, SSH, or the Coolify deploy-trigger API.
484
+ The local fixed client obtains `vultr-ops-api-token` from local clauth and sends
485
+ it as `Authorization: Bearer`; it never prints the token.
494
486
 
495
487
  ```bash
496
- # Get token (plain text — no JSON parsing needed)
497
- _COOLIFY=$(curl -s http://127.0.0.1:52437/v/coolify-api)
498
-
499
- # List applications
500
- curl -s -H "Authorization: Bearer $_COOLIFY" \
501
- "$DEPLOY_API_BASE/api/v1/applications"
502
-
503
- # Get application details
504
- curl -s -H "Authorization: Bearer $_COOLIFY" \
505
- "$DEPLOY_API_BASE/api/v1/applications/<uuid>"
506
-
507
- # Deploy (trigger) — correct endpoint is GET /api/v1/deploy?uuid=
508
- # (POST /applications/<uuid>/deploy returns {"message":"Not found."})
509
- curl -s -H "Authorization: Bearer $_COOLIFY" \
510
- "$DEPLOY_API_BASE/api/v1/deploy?uuid=<uuid>&force=true"
511
-
512
- # Get deployment logs
513
- curl -s -H "Authorization: Bearer $_COOLIFY" \
514
- "$DEPLOY_API_BASE/api/v1/deployments/<deployment-id>"
515
-
516
- # Set env var
517
- curl -s -X POST -H "Authorization: Bearer $_COOLIFY" \
518
- -H "Content-Type: application/json" \
519
- -d '{"key":"<KEY>","value":"<VALUE>"}' \
520
- "$DEPLOY_API_BASE/api/v1/applications/<uuid>/envs"
521
-
522
- # Set watch_paths
523
- curl -s -X PATCH -H "Authorization: Bearer $_COOLIFY" \
524
- -H "Content-Type: application/json" \
525
- -d '{"watch_paths":"apps/<name>/**\npackages/**"}' \
526
- "$DEPLOY_API_BASE/api/v1/applications/<uuid>"
527
-
528
- # Change the app's domain — the writable field is "domains", NOT "fqdn"
529
- # (Coolify v4 PATCH rejects {"fqdn":...} with "This field is not allowed"; fqdn is read-only/derived)
530
- curl -s -X PATCH -H "Authorization: Bearer $_COOLIFY" \
531
- -H "Content-Type: application/json" \
532
- -d '{"domains":"https://<host>"}' \
533
- "$DEPLOY_API_BASE/api/v1/applications/<uuid>"
488
+ clauth ops catalog --endpoint <control-plane>
489
+ clauth ops list --endpoint <control-plane>
490
+ clauth ops describe --endpoint <control-plane> --target <pm2-name>
491
+ clauth ops deploy --endpoint <control-plane> --application <slug> --ref <registered-ref>
492
+ clauth ops promote --endpoint <control-plane> --application <registered-coolify-uuid>
493
+ clauth ops job --endpoint <control-plane> --job <job-id>
534
494
  ```
535
495
 
496
+ Returns are accepted jobs (`202`) and the server persists redacted `queued`,
497
+ `running`, `building`, `waiting`, and terminal events. Generic PM2 catalog
498
+ operations are policy-disabled unless the server owner explicitly allowlists the
499
+ operation and target.
500
+
536
501
  **Domain change / namespace migration** (lesson 2026-06-13-deploy-media-manager-namespace-migration):
537
502
  PATCH `applications/<uuid>` with `{"domains":"https://<host>"}` — never `fqdn`.
538
503
  For an app NEW to main (first prod deploy) also bring the app + a lockfile importer
@@ -127,6 +127,19 @@ SELECT insert_work_item(
127
127
  p_source := 'planning'
128
128
  );
129
129
 
130
+ -- Immediately populate governance refs — the handoff's plan doc IS the plan_ref/spec_ref.
131
+ -- Set architecture_ref ONLY when this handoff crosses an architectural boundary (storage
132
+ -- authority, process topology, auth boundary, deployment model, persistence, service
133
+ -- ownership, public contract); leave it NULL for ordinary feature work, or every task
134
+ -- below gets held for a review it doesn't need.
135
+ SELECT set_epic_governance_refs(
136
+ p_epic_id := '<epic-uuid>'::uuid,
137
+ p_plan_ref := '.rdc/plans/<topic-slug>.md',
138
+ p_spec_ref := '.rdc/plans/<topic-slug>.md',
139
+ p_architecture_ref := '<docs/systems/<system>/ARCHITECTURE.md or NULL>',
140
+ p_scoping_statement := '<one paragraph: what is explicitly in scope and what is explicitly out of scope>'
141
+ );
142
+
130
143
  -- Create tasks (one per work package)
131
144
  SELECT insert_work_item(
132
145
  p_title := '<Package Name>',
@@ -249,6 +249,16 @@ SELECT insert_work_item(
249
249
  p_project_node_id := '<project_node_id>'::uuid,
250
250
  p_labels := ARRAY['onramp','<archetype>']
251
251
  );
252
+
253
+ -- Immediately populate governance refs. architecture_ref stays NULL — onramp phases are
254
+ -- data/content pipeline work (research, brand, site build), not an architectural-boundary
255
+ -- change; setting it would hold every phase task for a review it doesn't need.
256
+ SELECT set_epic_governance_refs(
257
+ p_epic_id := '<epic-uuid>'::uuid,
258
+ p_spec_ref := 'BRIDGE-MODE-SPEC.md',
259
+ p_architecture_ref := NULL,
260
+ p_scoping_statement := 'Enroll <slug> through the 7 onramp phases: enroll, research + document integration, conflict resolution, brand book + imagery, Regen Score gate, site build, deploy dev.'
261
+ );
252
262
  ```
253
263
 
254
264
  ### 1.5 Disk Tree + Directory Verification
@@ -126,6 +126,7 @@ rdc:plan <epic-id> --unattended
126
126
 
127
127
  Check `PLAN_STATUS.task_count > 0` before continuing.
128
128
  If 0 tasks created: escalate via advisor, then skip if still unresolved.
129
+ If `PLAN_STATUS.held_for_design_review > 0`: do not silently promote those tasks to todo. Log the held task IDs and their durable assessment, request human Design Review, and continue only with the independently admitted portion of the epic.
129
130
 
130
131
  ### 3c. Build
131
132
 
@@ -139,6 +140,7 @@ Agents receive the relevant guide file from `.rdc/guides/` (fallback: `.rdc/guid
139
140
 
140
141
  After each wave: check `BUILD_STATUS`. If `escalated: true`, log the escalation
141
142
  in the overnight doc and continue — don't stop the loop.
143
+ After each wave and after every resumed epic, require the `runOrchestrator()` receipt from `rdc:build`. `admission_refocus` or `pipeline_blocked` means the epic is held for durable Design Review or validator closure; log that state and do not hand-reconstruct a dispatch wave.
142
144
 
143
145
  **Mandatory code-review gate inherited from rdc:build (Step 9b).** Every wave inside `rdc:build` runs a `pr-review-toolkit:code-reviewer` pass before the next wave dispatches. Critical/high findings reopen the affected work items to `todo` and the next wave fixes them. Overnight does not skip or weaken this gate. If a wave's code-review escalates twice, advisor decides; otherwise the loop continues.
144
146
 
@@ -149,7 +151,7 @@ rdc:review --unattended
149
151
  ```
150
152
 
151
153
  Check `REVIEW_STATUS.verdict`:
152
- - `"CLEAN"`: mark epic `done` in work_items, push, continue to next epic
154
+ - `"CLEAN"`: re-run the durable CodeFlow supervisor. Mark an epic `done` only when its receipt is `pipeline_complete` and every executable child is design-review admitted and validator-closed (`status = done`); otherwise preserve the epic/task hold and log `admission_refocus` or `pipeline_blocked`.
153
155
  - `"HAS_ISSUES"` with `escalations > 0`: log issues, push what's clean, continue
154
156
  - `"HAS_ISSUES"` with `escalations = 0` (all auto-fixed): push, continue
155
157
 
@@ -242,6 +244,7 @@ Provide the advisor with:
242
244
  - NEVER let agents overlap on the same files
243
245
  - Push after every epic, not just at the end
244
246
  - Update Supabase work items in real time throughout
247
+ - **A clean review never overrides a durable Design Review hold, an incomplete checklist, or missing validator closure**
245
248
  - Max 2 hours per epic — if exceeded, skip and log `TIMEOUT`
246
249
  - If credential daemon goes down mid-session: write current state to overnight doc, push, exit gracefully
247
250
  - If git push fails: log the failure, attempt rebase, retry once — do not force push
@@ -234,15 +234,31 @@ description: "Usage `rdc:plan <topic>` — No epic exists and you need architect
234
234
  - Epic via `insert_work_item(p_item_type := 'epic', p_definition_of_done := '[...]'::jsonb, ...)`
235
235
  - Epic DoD MUST include: `{"id":"test-plan-verified","text":"All test plan items implemented and passing","required":true,"checked":false}`
236
236
  - Set `p_definition_of_done` on the epic — child tasks inserted under it will auto-inherit it as their checklist
237
- - One task per work package via `insert_work_item(p_parent_id := <epic_id>, ...)` checklist auto-hydrated from epic's DoD
237
+ - **Immediately after creating the epic, call `set_epic_governance_refs`** so downstream execution (`rdc:build`, `rdc:overnight`, `rdc:fixit`, `rdc:refactor`) never has to guess or stall waiting on these fields:
238
+ ```sql
239
+ SELECT set_epic_governance_refs(
240
+ p_epic_id := '<epic_id>',
241
+ p_plan_ref := '.rdc/plans/<topic-slug>.md', -- the doc written in step 6
242
+ p_spec_ref := '.rdc/plans/<topic-slug>.md', -- same doc unless a dedicated spec doc exists for this topic
243
+ p_architecture_ref := '<docs/systems/<system>/ARCHITECTURE.md or NULL>', -- set ONLY when this plan crosses an architectural boundary (storage authority, process topology, auth boundary, deployment model, persistence, service ownership, public contract) — leave NULL for ordinary feature/bugfix work, or every task gets held for human review that doesn't need it
244
+ p_scoping_statement := '<one paragraph: what is explicitly in scope and what is explicitly out of scope for this epic>'
245
+ );
246
+ ```
247
+ - Attach a **Design Review contract** to every executable work package. It must contain registered architecture-evidence reference(s), declared target boundary, and a concrete alignment claim; independently observable acceptance criteria plus required `decomp-*` and `test-*` rows; and estimated files/LOC, declared surfaces, and change kind.
248
+ - One executable task per work package only through `upsert_admitted_work_item(...)`, never a direct `work_items` write. Supply a stable source fingerprint, the task checklist, and the Design Review contract. `insert_work_item` remains valid for the parent epic only.
249
+ - Do not invent architecture evidence. Missing or unregistered evidence, broad refactors, multi-surface work, or disproportionate contracts intentionally route to human Design Review.
250
+ - Read the durable result for each package: `dispatchable: true` / `automatic_approved` may become `todo`; `dispatchable: false` / `needs_human` or `pending` stays `blocked`, gets `needs-human-design-review`, and is reported as held.
238
251
  - **Additionally, write decomposition rows as checklist items** on each task, using id format `decomp-<surface>-<slug>`.
239
252
  The task checklist MUST include both the atomic `decomp-*` rows and the `test-*` verification rows.
240
253
  The `decomp-*` row text must include the route/file, action, expected result, and evidence artifact.
241
- - **Write test plan items as checklist items** on each task, using id format `test-<type>-<slug>`:
254
+ - **Write test plan items as checklist items** on each task, using id format `test-<type>-<slug>`.
255
+ - **If (and only if) the epic's `architecture_ref` is set** (this work package crosses an architectural boundary), ALSO write one required `architecture-fidelity-<slug>` checklist row on that task: text names the specific architecture doc + the boundary being touched, e.g. `"implementation matches docs/systems/codeflow/ARCHITECTURE.md § local-index registration"`. This is checked at CLOSE time by `update_work_item_status(..., 'done')`, independently of the Design Review contract's own `dispatchable`/`needs_human` admission check above — the exit gate hard-rejects closure on any task under an architecture_ref epic that lacks this row. Do not add it to tasks under an epic with no `architecture_ref`; that would hold ordinary work for a review it doesn't need.
242
256
  ```sql
243
- SELECT insert_work_item(
257
+ SELECT upsert_admitted_work_item(
258
+ p_source_fingerprint := 'plan:<epic-id>:wp-2-ast-scanner:v1',
244
259
  p_parent_id := '<epic_id>',
245
260
  p_title := 'WP-2: AST Scanner',
261
+ p_description := 'Bounded scanner work package with its durable Design Review contract.',
246
262
  p_checklist := '[
247
263
  {"id":"decomp-api-scan-success","text":"api: GET /api/layout/scan?dir=apps/studio/src returns 200 JSON with roots[] and warnings[]; evidence: route probe output","required":true,"checked":false},
248
264
  {"id":"test-assert-scanner-filters","text":"assert: scanFile returns only container components","required":true,"checked":false},
@@ -250,10 +266,16 @@ description: "Usage `rdc:plan <topic>` — No epic exists and you need architect
250
266
  {"id":"test-smoke-scan-api","text":"smoke: GET /api/layout/scan returns 200","required":true,"checked":false},
251
267
  {"id":"test-contract-scanresult","text":"contract: ScanResult shape matches spec","required":true,"checked":false},
252
268
  {"id":"tsc-clean","text":"npx tsc --noEmit passes","required":true,"checked":false}
253
- ]'::jsonb
269
+ -- Only add an architecture-fidelity-* row here too if this task's epic has architecture_ref set.
270
+ ]'::jsonb,
271
+ p_design_review := '{
272
+ "architecture":{"alignment_claim":"Scanner change stays within the declared analysis boundary.","evidence_refs":["<registered-reference>"],"target_boundaries":["<declared-boundary>"]},
273
+ "acceptance":{"criteria":["scanner focused test passes"]},
274
+ "proportionality":{"estimated_files":2,"estimated_loc":180,"declared_surfaces":["<surface>"],"change_kind":"feature"}
275
+ }'::jsonb
254
276
  );
255
277
  ```
256
- - Agents MUST tick each `decomp-*` and `test-*` checklist item as they implement/verify it via `update_checklist_item(..., p_actor_session_id := '<agent-session-id>', p_actor_role := 'agent')`
278
+ - Agents MUST tick each `decomp-*`, `test-*`, and (when present) `architecture-fidelity-*` checklist item as they implement/verify it via `update_checklist_item(..., p_actor_session_id := '<agent-session-id>', p_actor_role := 'agent')`
257
279
  - Agents submit `implementation_report.codeflow_post`, then move work to `review`; validators close `done`
258
280
  - `update_work_item_status('done', ..., p_actor_role := 'validator')` rejects missing reports, unchecked required items, and supervisor/validator re-ticks
259
281
  - Set priorities: urgent/high/normal based on sequencing
@@ -262,7 +284,7 @@ description: "Usage `rdc:plan <topic>` — No epic exists and you need architect
262
284
  - Interactive: present the plan for approval before building
263
285
  - Unattended: skip approval, proceed immediately, emit status block:
264
286
  ```
265
- PLAN_STATUS: { epic_id, task_count, doc_path, waves }
287
+ PLAN_STATUS: { epic_id, task_count, dispatchable_task_count, held_for_design_review, doc_path, waves }
266
288
  ```
267
289
 
268
290
  ## Unattended Escalation
@@ -280,6 +302,7 @@ choose the most conservative/reversible approach and document the decision.
280
302
  - Each work package must be independently executable by an agent
281
303
  - No file overlap between work packages
282
304
  - Include test requirements in every work package
305
+ - **No executable work item is dispatchable without a durable Design Review decision; a planner cannot self-approve with prose-only evidence**
283
306
  - Reference affected CLAUDE.md files in each work package description
284
307
  - Reference the relevant guide file from `.rdc/guides/` (fallback: `.rdc/guides/`) for agent context
285
308
  - **If a work package involves creating a new deployed app:** the task description MUST say "Use `rdc:deploy new <slug>` — do NOT create the Coolify app manually. Read `docs/runbooks/coolify-app-templates.json` first." Assign it to an `infra` agent. This is a hard rule — manually created apps have consistently been misconfigured.
@@ -1,6 +1,6 @@
1
1
  # RDC Skill Test Suite Matrix
2
2
 
3
- Current coverage: 35 manifests for 35 skill directories.
3
+ Current coverage: 36 manifests for 36 skill directories.
4
4
 
5
5
  The manifest layer verifies each skill can be started from a realistic caller prompt in an isolated `RDC_TEST=1` sandbox. The acceptance harness can run either Claude (`--engine claude`) or Codex (`--engine codex`) against the same manifests and records the engine stream, extracted tool calls, stdout/stderr artifacts, rendered assistant output, failures, lessons learned, and next build optimizations under `.rdc/reports/`.
6
6
 
@@ -8,6 +8,7 @@ The manifest layer verifies each skill can be started from a realistic caller pr
8
8
 
9
9
  | Skill | Manifest | Fixture prompt class | Assertions | Acceptance depth |
10
10
  |---|---|---|---|---|
11
+ | `rdc:behavior-audit` | `rdc-behavior-audit.test.json` | Bounded transcript-audit fixture | `commits_made`, `exit_code`, `stdout_contains` | Redacted evidence bundle, independent validator, and no-deploy/no-self-certify checks |
11
12
  | `rdc:brochure` | `rdc-brochure.test.json` | HTML-to-PDF brochure fixture | `exit_code`, `stdout_contains` | PDF artifact, page/size/source output, and no upload/deploy/source-modification checks |
12
13
  | `rdc:build` | `rdc-build.test.json` | Unattended build from sandbox label | `commits_made`, `exit_code`, `stdout_contains` | Dispatch guide, code-review, validator, sandbox, and no-push/no-skip checks |
13
14
  | `rdc:channel-formatter` | `rdc-channel-formatter.test.json` | Long article to social content pack | `exit_code`, `stdout_contains` | Output contains, output not contains, tool-call routing |
@@ -1,7 +1,7 @@
1
1
  # Tier 2 Test Manifests
2
2
 
3
3
  Each RDC skill directory has a colocated test manifest at `skills/tests/rdc-<name>.test.json`.
4
- There are currently 35 manifests for 35 skill directories. These drive the Tier 2
4
+ There are currently 36 manifests for 36 skill directories. These drive the Tier 2
5
5
  behavioral runner and the build acceptance harness for both Claude and Codex.
6
6
 
7
7
  See `MATRIX.md` for the current skill-by-skill coverage table.
@@ -0,0 +1,12 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "skill": "rdc:behavior-audit",
4
+ "description": "Behavior audit requires a bounded output path and preserves transcript evidence as redacted, validator-governed artifacts.",
5
+ "fixture": { "prompt": "rdc:behavior-audit reports/behavior-audit/test --since-days 7", "env": { "RDC_TEST": "1" } },
6
+ "assertions": { "exit_code": 0, "commits_made": { "min": 0 }, "stdout_contains": ["manifest.json", "locators.jsonl", "independent", "validator"] },
7
+ "acceptance": {
8
+ "output_contains": ["manifest.json", "redacted", "validator"],
9
+ "output_not_contains": ["deploy", "rewrite transcripts", "self-certify"]
10
+ },
11
+ "teardown": { "reset_branch": true }
12
+ }
@@ -53,6 +53,18 @@ SELECT insert_work_item(
53
53
  p_labels := ARRAY['system-label'],
54
54
  p_source := 'planning'
55
55
  );
56
+
57
+ -- Immediately populate governance refs. architecture_ref stays NULL unless this epic
58
+ -- crosses an architectural boundary (storage authority, process topology, auth boundary,
59
+ -- deployment model, persistence, service ownership, public contract) — setting it holds
60
+ -- every child task for a required architecture-fidelity-* checklist row at close time.
61
+ SELECT set_epic_governance_refs(
62
+ p_epic_id := '<epic-uuid>'::uuid,
63
+ p_plan_ref := '.rdc/plans/<n>.md or NULL',
64
+ p_spec_ref := '.rdc/plans/<n>.md or NULL',
65
+ p_architecture_ref := NULL,
66
+ p_scoping_statement := '<one paragraph: what is in scope and what is explicitly out>'
67
+ );
56
68
  ```
57
69
 
58
70
  ## Create Task
@@ -0,0 +1,33 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { getSkillBody } from '../lib/catalog.mjs';
4
+
5
+ const served = (name) => {
6
+ const body = getSkillBody(name);
7
+ assert.ok(body, `${name} must have a live catalog body`);
8
+ return body;
9
+ };
10
+
11
+ test('live rdc_skill_get planning body creates executable work through the durable admission contract', () => {
12
+ const plan = served('rdc:plan');
13
+ assert.match(plan, /upsert_admitted_work_item/);
14
+ assert.match(plan, /Design Review contract/);
15
+ assert.match(plan, /needs_human/);
16
+ assert.doesNotMatch(plan, /One task per work package via `insert_work_item/);
17
+ });
18
+
19
+ test('live rdc_skill_get build body routes work through CodeFlow admission and validator closure', () => {
20
+ const build = served('rdc:build');
21
+ assert.match(build, /runOrchestrator\(\)/);
22
+ assert.match(build, /SupabaseStateStore/);
23
+ assert.match(build, /admission_refocus/);
24
+ assert.match(build, /pipeline_complete/);
25
+ assert.match(build, /durably `done`/);
26
+ });
27
+
28
+ test('live rdc_skill_get overnight body cannot map CLEAN directly to an incomplete epic', () => {
29
+ const overnight = served('rdc:overnight');
30
+ assert.match(overnight, /only when its receipt is `pipeline_complete`/i);
31
+ assert.match(overnight, /validator-closed/);
32
+ assert.doesNotMatch(overnight, /"CLEAN"`: mark epic `done` in work_items, push, continue to next epic/);
33
+ });
@@ -35,7 +35,7 @@ for (const [name, text] of Object.entries(docs)) {
35
35
  assert.doesNotMatch(text, /https:\/\/rdc-skills\.dev\.regendevcorp\.com\/mcp/, `${name} must not point callers at dev MCP`);
36
36
  }
37
37
 
38
- assert.match(docs.readme, /34 MCP skills organized into 8 manifest categories/, 'README should use manifest category count');
38
+ assert.match(docs.readme, /36 MCP skills organized into 8 manifest categories/, 'README should use manifest category count');
39
39
  assert.match(docs.readme, /Nineteen[\s\S]*\/rdc:\*` command shorthands/i, 'README should distinguish slash-command shorthands from full MCP skills');
40
40
  assert.match(docs.readme, /Use `rdc_skill_list` for the authoritative live catalog/, 'README should point callers to live MCP catalog');
41
41
  assert.doesNotMatch(docs.readme, /All user-invocable skills become available as slash commands/, 'README must not imply all MCP skills are slash commands');
@@ -24,7 +24,7 @@ const plugin = JSON.parse(readFileSync(join(REPO_ROOT, '.claude-plugin', 'plugin
24
24
  const skillCount = Array.isArray(plugin.skills_meta)
25
25
  ? plugin.skills_meta.length
26
26
  : Object.keys(plugin.skills_meta || {}).length;
27
- assert.equal(skillCount, 34, 'test fixture should expose all 34 MCP skills from plugin skills_meta');
27
+ assert.equal(skillCount, 36, 'test fixture should expose all 36 MCP skills from plugin skills_meta');
28
28
  assert.match(
29
29
  source,
30
30
  /Available MCP skills.*\/rdc:\* command shorthands/,
package/git-sha.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "sha": "e634f9ffc42be06bccedfa3d6ab4e85bf79b5c70"
3
- }