nubos-pilot 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/agents/np-ai-researcher.md +140 -0
  2. package/agents/np-code-fixer.md +363 -0
  3. package/agents/np-code-reviewer.md +351 -0
  4. package/agents/np-domain-researcher.md +136 -0
  5. package/agents/np-eval-auditor.md +167 -0
  6. package/agents/np-eval-planner.md +153 -0
  7. package/agents/np-executor.md +72 -0
  8. package/agents/np-framework-selector.md +171 -0
  9. package/agents/np-nyquist-auditor.md +185 -0
  10. package/agents/np-plan-checker.md +165 -0
  11. package/agents/np-planner.md +199 -0
  12. package/agents/np-researcher.md +150 -0
  13. package/agents/np-security-auditor.md +206 -0
  14. package/agents/np-ui-auditor.md +369 -0
  15. package/agents/np-ui-checker.md +192 -0
  16. package/agents/np-ui-researcher.md +324 -0
  17. package/agents/np-verifier.md +79 -0
  18. package/bin/check-coverage.cjs +40 -0
  19. package/bin/check-workflows.cjs +171 -0
  20. package/bin/check-workflows.test.cjs +208 -0
  21. package/bin/install.js +500 -0
  22. package/bin/np-tools/_commands.cjs +70 -0
  23. package/bin/np-tools/add-tests.cjs +171 -0
  24. package/bin/np-tools/add-tests.test.cjs +122 -0
  25. package/bin/np-tools/add-todo.cjs +108 -0
  26. package/bin/np-tools/add-todo.test.cjs +112 -0
  27. package/bin/np-tools/agent-skills.cjs +14 -0
  28. package/bin/np-tools/agent-skills.test.cjs +42 -0
  29. package/bin/np-tools/ai-integration-phase.cjs +109 -0
  30. package/bin/np-tools/ai-integration-phase.test.cjs +123 -0
  31. package/bin/np-tools/askuser.cjs +53 -0
  32. package/bin/np-tools/askuser.test.cjs +49 -0
  33. package/bin/np-tools/autonomous.cjs +69 -0
  34. package/bin/np-tools/autonomous.test.cjs +74 -0
  35. package/bin/np-tools/checkpoint.cjs +101 -0
  36. package/bin/np-tools/checkpoint.test.cjs +119 -0
  37. package/bin/np-tools/code-review.cjs +133 -0
  38. package/bin/np-tools/code-review.test.cjs +96 -0
  39. package/bin/np-tools/commit-task.cjs +120 -0
  40. package/bin/np-tools/commit-task.test.cjs +160 -0
  41. package/bin/np-tools/commit.cjs +103 -0
  42. package/bin/np-tools/commit.test.cjs +93 -0
  43. package/bin/np-tools/config.cjs +101 -0
  44. package/bin/np-tools/config.test.cjs +71 -0
  45. package/bin/np-tools/discuss-phase-power.cjs +265 -0
  46. package/bin/np-tools/discuss-phase-power.test.cjs +242 -0
  47. package/bin/np-tools/discuss-phase.cjs +132 -0
  48. package/bin/np-tools/discuss-phase.test.cjs +148 -0
  49. package/bin/np-tools/dispatch.cjs +116 -0
  50. package/bin/np-tools/doctor.cjs +242 -0
  51. package/bin/np-tools/eval-review.cjs +116 -0
  52. package/bin/np-tools/eval-review.test.cjs +123 -0
  53. package/bin/np-tools/execute-phase.cjs +182 -0
  54. package/bin/np-tools/execute-phase.test.cjs +116 -0
  55. package/bin/np-tools/execute-plan.cjs +124 -0
  56. package/bin/np-tools/execute-plan.test.cjs +82 -0
  57. package/bin/np-tools/help.cjs +28 -0
  58. package/bin/np-tools/help.test.cjs +29 -0
  59. package/bin/np-tools/init-dispatch.test.cjs +91 -0
  60. package/bin/np-tools/metrics.cjs +97 -0
  61. package/bin/np-tools/metrics.test.cjs +188 -0
  62. package/bin/np-tools/new-milestone.cjs +288 -0
  63. package/bin/np-tools/new-milestone.test.cjs +166 -0
  64. package/bin/np-tools/new-project.cjs +284 -0
  65. package/bin/np-tools/new-project.test.cjs +165 -0
  66. package/bin/np-tools/next.cjs +7 -0
  67. package/bin/np-tools/next.test.cjs +30 -0
  68. package/bin/np-tools/park.cjs +48 -0
  69. package/bin/np-tools/park.test.cjs +50 -0
  70. package/bin/np-tools/pause-work.cjs +24 -0
  71. package/bin/np-tools/pause-work.test.cjs +74 -0
  72. package/bin/np-tools/phase.cjs +71 -0
  73. package/bin/np-tools/phase.test.cjs +81 -0
  74. package/bin/np-tools/plan-diff.cjs +57 -0
  75. package/bin/np-tools/plan-diff.test.cjs +134 -0
  76. package/bin/np-tools/plan-milestone-gaps.cjs +115 -0
  77. package/bin/np-tools/plan-milestone-gaps.test.cjs +122 -0
  78. package/bin/np-tools/plan-phase.cjs +350 -0
  79. package/bin/np-tools/plan-phase.test.cjs +263 -0
  80. package/bin/np-tools/progress.cjs +7 -0
  81. package/bin/np-tools/progress.test.cjs +44 -0
  82. package/bin/np-tools/queue.cjs +213 -0
  83. package/bin/np-tools/research-phase.cjs +144 -0
  84. package/bin/np-tools/research-phase.test.cjs +154 -0
  85. package/bin/np-tools/reset-slice.cjs +17 -0
  86. package/bin/np-tools/reset-slice.test.cjs +96 -0
  87. package/bin/np-tools/resolve-model.cjs +110 -0
  88. package/bin/np-tools/resolve-model.test.cjs +200 -0
  89. package/bin/np-tools/resume-work.cjs +76 -0
  90. package/bin/np-tools/resume-work.test.cjs +91 -0
  91. package/bin/np-tools/skip.cjs +48 -0
  92. package/bin/np-tools/skip.test.cjs +66 -0
  93. package/bin/np-tools/slug.cjs +34 -0
  94. package/bin/np-tools/slug.test.cjs +46 -0
  95. package/bin/np-tools/state.cjs +16 -0
  96. package/bin/np-tools/state.test.cjs +40 -0
  97. package/bin/np-tools/stats.cjs +151 -0
  98. package/bin/np-tools/stats.test.cjs +118 -0
  99. package/bin/np-tools/triage.cjs +128 -0
  100. package/bin/np-tools/ui-phase.cjs +108 -0
  101. package/bin/np-tools/ui-phase.test.cjs +121 -0
  102. package/bin/np-tools/ui-review.cjs +108 -0
  103. package/bin/np-tools/ui-review.test.cjs +120 -0
  104. package/bin/np-tools/undo-task.cjs +31 -0
  105. package/bin/np-tools/undo-task.test.cjs +117 -0
  106. package/bin/np-tools/undo.cjs +43 -0
  107. package/bin/np-tools/undo.test.cjs +120 -0
  108. package/bin/np-tools/unpark.cjs +48 -0
  109. package/bin/np-tools/unpark.test.cjs +50 -0
  110. package/bin/np-tools/verify-work.cjs +186 -0
  111. package/bin/np-tools/verify-work.test.cjs +97 -0
  112. package/docs/adr/0001-no-daemon-invariant.md +82 -0
  113. package/docs/adr/0002-zero-runtime-dependencies.md +90 -0
  114. package/docs/adr/0003-max-six-unit-types.md +85 -0
  115. package/docs/adr/0004-atomic-commit-per-unit.md +102 -0
  116. package/docs/adr/0005-three-orthogonal-file-trees.md +98 -0
  117. package/docs/adr/0006-yaml-dependency-amendment.md +60 -0
  118. package/docs/adr/README.md +27 -0
  119. package/docs/agent-frontmatter-schema.md +84 -0
  120. package/docs/phase-artifact-schemas.md +292 -0
  121. package/docs/phase-directory-layout.md +82 -0
  122. package/lib/__tests__/README.md +1 -0
  123. package/lib/agents.cjs +98 -0
  124. package/lib/agents.test.cjs +286 -0
  125. package/lib/askuser.cjs +36 -0
  126. package/lib/askuser.test.cjs +310 -0
  127. package/lib/checkpoint.cjs +135 -0
  128. package/lib/checkpoint.test.cjs +184 -0
  129. package/lib/core.cjs +165 -0
  130. package/lib/core.test.cjs +405 -0
  131. package/lib/fixtures/README.md +1 -0
  132. package/lib/fixtures/phase-tree/README.md +1 -0
  133. package/lib/fixtures/plans/cycle/PLAN.md +16 -0
  134. package/lib/fixtures/plans/cycle/tasks/T-01.md +20 -0
  135. package/lib/fixtures/plans/cycle/tasks/T-02.md +20 -0
  136. package/lib/fixtures/plans/cycle/tasks/T-03.md +20 -0
  137. package/lib/fixtures/plans/linear/PLAN.md +16 -0
  138. package/lib/fixtures/plans/linear/tasks/T-01.md +20 -0
  139. package/lib/fixtures/plans/linear/tasks/T-02.md +20 -0
  140. package/lib/fixtures/plans/linear/tasks/T-03.md +20 -0
  141. package/lib/fixtures/plans/parallel/PLAN.md +16 -0
  142. package/lib/fixtures/plans/parallel/tasks/T-01.md +20 -0
  143. package/lib/fixtures/plans/parallel/tasks/T-02.md +20 -0
  144. package/lib/fixtures/plans/parallel/tasks/T-03.md +20 -0
  145. package/lib/fixtures/plans/wave-conflict/PLAN.md +16 -0
  146. package/lib/fixtures/plans/wave-conflict/tasks/T-01.md +20 -0
  147. package/lib/fixtures/plans/wave-conflict/tasks/T-02.md +20 -0
  148. package/lib/fixtures/roadmap/ROADMAP-malformed.md +3 -0
  149. package/lib/fixtures/roadmap/ROADMAP-minimal.md +51 -0
  150. package/lib/fixtures/roadmap/roadmap-malformed.yaml +7 -0
  151. package/lib/fixtures/roadmap/roadmap-minimal.yaml +40 -0
  152. package/lib/fixtures/roadmap/roadmap-ten-phases.yaml +101 -0
  153. package/lib/fixtures/templates/phase-context.md +6 -0
  154. package/lib/fixtures/templates/plan-skeleton.md +6 -0
  155. package/lib/frontmatter.cjs +251 -0
  156. package/lib/frontmatter.test.cjs +177 -0
  157. package/lib/gaps.cjs +197 -0
  158. package/lib/gaps.test.cjs +200 -0
  159. package/lib/git.cjs +207 -0
  160. package/lib/git.test.cjs +305 -0
  161. package/lib/install/agents-md.cjs +77 -0
  162. package/lib/install/backup.cjs +70 -0
  163. package/lib/install/codex-toml.cjs +440 -0
  164. package/lib/install/managed-block.cjs +30 -0
  165. package/lib/install/manifest.cjs +148 -0
  166. package/lib/install/mcp-writer.cjs +127 -0
  167. package/lib/install/runtime-detect.cjs +44 -0
  168. package/lib/install/staging.cjs +149 -0
  169. package/lib/metrics-aggregate.cjs +229 -0
  170. package/lib/metrics-aggregate.test.cjs +192 -0
  171. package/lib/metrics.cjs +120 -0
  172. package/lib/metrics.test.cjs +182 -0
  173. package/lib/model-aliases.regression.test.cjs +16 -0
  174. package/lib/model-profiles.cjs +42 -0
  175. package/lib/model-profiles.test.cjs +61 -0
  176. package/lib/next.cjs +236 -0
  177. package/lib/next.test.cjs +194 -0
  178. package/lib/phase.cjs +95 -0
  179. package/lib/phase.test.cjs +189 -0
  180. package/lib/plan-checker-contract.test.cjs +72 -0
  181. package/lib/plan-diff.cjs +173 -0
  182. package/lib/plan-diff.test.cjs +217 -0
  183. package/lib/plan.cjs +85 -0
  184. package/lib/plan.test.cjs +263 -0
  185. package/lib/progress.cjs +95 -0
  186. package/lib/progress.test.cjs +116 -0
  187. package/lib/researcher-contract.test.cjs +61 -0
  188. package/lib/roadmap-render.cjs +206 -0
  189. package/lib/roadmap-render.test.cjs +121 -0
  190. package/lib/roadmap.cjs +416 -0
  191. package/lib/roadmap.test.cjs +371 -0
  192. package/lib/runtime/_contract.test.cjs +61 -0
  193. package/lib/runtime/_readline.cjs +119 -0
  194. package/lib/runtime/_readline.test.cjs +126 -0
  195. package/lib/runtime/claude.cjs +48 -0
  196. package/lib/runtime/claude.test.cjs +101 -0
  197. package/lib/runtime/codex.cjs +35 -0
  198. package/lib/runtime/codex.test.cjs +114 -0
  199. package/lib/runtime/gemini.cjs +35 -0
  200. package/lib/runtime/gemini.test.cjs +109 -0
  201. package/lib/runtime/index.cjs +49 -0
  202. package/lib/runtime/index.test.cjs +181 -0
  203. package/lib/runtime/opencode.cjs +35 -0
  204. package/lib/runtime/opencode.test.cjs +124 -0
  205. package/lib/state.cjs +205 -0
  206. package/lib/state.test.cjs +264 -0
  207. package/lib/surface-audit.test.cjs +46 -0
  208. package/lib/tasks.cjs +327 -0
  209. package/lib/tasks.test.cjs +389 -0
  210. package/lib/template.cjs +66 -0
  211. package/lib/template.test.cjs +159 -0
  212. package/lib/undo.cjs +179 -0
  213. package/lib/undo.test.cjs +261 -0
  214. package/lib/verify.cjs +116 -0
  215. package/lib/verify.test.cjs +187 -0
  216. package/np-tools.cjs +303 -0
  217. package/package.json +39 -0
  218. package/templates/AI-SPEC.md +90 -0
  219. package/templates/CONTEXT.md +32 -0
  220. package/templates/PLAN.md +69 -0
  221. package/templates/PROJECT.md +60 -0
  222. package/templates/REQUIREMENTS.md +38 -0
  223. package/templates/SECURITY.md +61 -0
  224. package/templates/UI-SPEC.md +64 -0
  225. package/templates/VALIDATION.md +76 -0
  226. package/templates/claude/payload/README.md +11 -0
  227. package/templates/opencode/opencode.json +6 -0
  228. package/templates/opencode/payload/AGENTS.md +9 -0
  229. package/workflows/add-backlog.md +212 -0
  230. package/workflows/add-tests.md +69 -0
  231. package/workflows/add-todo.md +222 -0
  232. package/workflows/ai-integration-phase.md +230 -0
  233. package/workflows/autonomous.md +94 -0
  234. package/workflows/cleanup.md +325 -0
  235. package/workflows/code-review-fix.md +435 -0
  236. package/workflows/code-review.md +447 -0
  237. package/workflows/discuss-phase-assumptions.md +269 -0
  238. package/workflows/discuss-phase-power.md +139 -0
  239. package/workflows/discuss-phase.md +386 -0
  240. package/workflows/dispatch.md +9 -0
  241. package/workflows/doctor.md +10 -0
  242. package/workflows/eval-review.md +243 -0
  243. package/workflows/execute-phase.md +142 -0
  244. package/workflows/execute-plan.md +82 -0
  245. package/workflows/help.md +8 -0
  246. package/workflows/new-milestone.md +166 -0
  247. package/workflows/new-project.md +213 -0
  248. package/workflows/next.md +8 -0
  249. package/workflows/note.md +244 -0
  250. package/workflows/park.md +29 -0
  251. package/workflows/pause-work.md +34 -0
  252. package/workflows/plan-milestone-gaps.md +233 -0
  253. package/workflows/plan-phase.md +351 -0
  254. package/workflows/progress.md +8 -0
  255. package/workflows/queue.md +9 -0
  256. package/workflows/research-phase.md +327 -0
  257. package/workflows/reset-slice.md +39 -0
  258. package/workflows/resume-work.md +79 -0
  259. package/workflows/review.md +489 -0
  260. package/workflows/secure-phase.md +209 -0
  261. package/workflows/session-report.md +243 -0
  262. package/workflows/skip.md +29 -0
  263. package/workflows/state.md +7 -0
  264. package/workflows/stats.md +170 -0
  265. package/workflows/thread.md +214 -0
  266. package/workflows/triage.md +9 -0
  267. package/workflows/ui-phase.md +246 -0
  268. package/workflows/ui-review.md +222 -0
  269. package/workflows/undo-task.md +42 -0
  270. package/workflows/undo.md +55 -0
  271. package/workflows/unpark.md +29 -0
  272. package/workflows/validate-phase.md +231 -0
  273. package/workflows/verify-work.md +83 -0
@@ -0,0 +1,447 @@
1
+ ---
2
+ command: np:code-review
3
+ description: Source-file review on a completed phase. Reads files_to_read from --files flag or phase SUMMARY.md key_files. Spawns np-code-reviewer (opus) to produce REVIEW.md with critical/warning/info findings at depth quick|standard|deep. One atomic docs commit. Supports --auto flag (chains to /np:code-review-fix after review).
4
+ ---
5
+
6
+ # np:code-review
7
+
8
+ Produces `{phase_dir}/{padded}-REVIEW.md` via a single `np-code-reviewer` (opus)
9
+ spawn that reviews phase source files at depth `quick|standard|deep`.
10
+ Runs AFTER `/np:execute-phase` has landed code — the audit needs either
11
+ a phase `SUMMARY.md` with `key_files:` or an explicit `--files=...`
12
+ override to know what to review.
13
+
14
+ The single Task-spawn site is wrapped in the Plan 09-05 metrics +
15
+ resolve-model pattern (D-06, D-01). `RUNTIME` is detected once at the
16
+ top of the bash block and re-used by the `metrics record` call. All
17
+ interactive prompts route through `np-tools.cjs askuser` per INST-03.
18
+
19
+ File paths passed via `--files=...` are validated through a
20
+ realpath + repo-root-prefix guard (Pitfall 7 / T-10-03-01 mitigation)
21
+ to reject path-traversal attempts before they reach the agent.
22
+
23
+ ## Initialize
24
+
25
+ ```bash
26
+ PHASE="$1"
27
+ if [[ -z "$PHASE" ]]; then
28
+ echo "Usage: /np:code-review <phase-number> [--files=f1,f2] [--depth=quick|standard|deep] [--auto]" >&2
29
+ exit 2
30
+ fi
31
+
32
+ INIT=$(node np-tools.cjs init code-review "$PHASE")
33
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
34
+ RUNTIME=$(node -e "console.log(require('./lib/runtime/index.cjs').detect().runtime)")
35
+ ```
36
+
37
+ Parse JSON for: `phase`, `padded`, `phase_dir`, `review_path`,
38
+ `review_fix_path`, `summary_present`, `summary_path`, `has_review`,
39
+ `depth`, `agents.code_reviewer`.
40
+
41
+ ```bash
42
+ PADDED=$(echo "$INIT" | jq -r '.padded')
43
+ PHASE_DIR=$(echo "$INIT" | jq -r '.phase_dir')
44
+ REVIEW_PATH=$(echo "$INIT" | jq -r '.review_path')
45
+ SUMMARY_PRESENT=$(echo "$INIT" | jq -r '.summary_present')
46
+ SUMMARY_PATH=$(echo "$INIT" | jq -r '.summary_path')
47
+ HAS_REVIEW=$(echo "$INIT" | jq -r '.has_review')
48
+ DEPTH=$(echo "$INIT" | jq -r '.depth')
49
+ PLAN_ID="${PADDED}-code-review"
50
+ TASK_ID="${PADDED}-code-review"
51
+ ```
52
+
53
+ ## Argument Parsing
54
+
55
+ ```bash
56
+ FILES_ARG=""
57
+ DEPTH_OVERRIDE=""
58
+ AUTO_MODE="false"
59
+ for arg in "$@"; do
60
+ case "$arg" in
61
+ --files=*) FILES_ARG="${arg#--files=}" ;;
62
+ --depth=*) DEPTH_OVERRIDE="${arg#--depth=}" ;;
63
+ --auto) AUTO_MODE="true" ;;
64
+ esac
65
+ done
66
+
67
+ if [[ -n "$DEPTH_OVERRIDE" ]]; then
68
+ case "$DEPTH_OVERRIDE" in
69
+ quick|standard|deep) DEPTH="$DEPTH_OVERRIDE" ;;
70
+ *) echo "Warning: invalid --depth='$DEPTH_OVERRIDE' (expected quick|standard|deep). Keeping DEPTH=$DEPTH." >&2 ;;
71
+ esac
72
+ fi
73
+ ```
74
+
75
+ ## Path-Traversal Guard
76
+
77
+ Every path from `--files=...` is validated against the repository root
78
+ before reaching the agent (T-10-03-01 mitigation). `realpath -m` is
79
+ preferred for correctness; on macOS without `coreutils` a string-match
80
+ fallback is used.
81
+
82
+ ```bash
83
+ SAFE_FILES=()
84
+ if [[ -n "$FILES_ARG" ]]; then
85
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
86
+ if [[ -z "$REPO_ROOT" ]]; then
87
+ echo "Error: unable to resolve repository root via 'git rev-parse --show-toplevel'." >&2
88
+ exit 1
89
+ fi
90
+ IFS=',' read -ra FILES_ARR <<< "$FILES_ARG"
91
+ if command -v realpath >/dev/null 2>&1; then
92
+ for F in "${FILES_ARR[@]}"; do
93
+ [[ -z "$F" ]] && continue
94
+ RP=$(realpath -m "$F" 2>/dev/null || true)
95
+ case "$RP" in
96
+ "$REPO_ROOT"/*) SAFE_FILES+=("$F") ;;
97
+ *) echo "Skipping path outside repo: $F" >&2 ;;
98
+ esac
99
+ done
100
+ else
101
+ echo "WARN: realpath not available (macOS users: brew install coreutils). Falling back to string-match guard." >&2
102
+ for F in "${FILES_ARR[@]}"; do
103
+ [[ -z "$F" ]] && continue
104
+ case "$F" in
105
+ */../*|../*|/*) echo "Skipping unsafe path: $F" >&2 ;;
106
+ *) SAFE_FILES+=("$F") ;;
107
+ esac
108
+ done
109
+ fi
110
+ fi
111
+ ```
112
+
113
+ ## Pre-Flight Gates
114
+
115
+ <pre_flight>
116
+
117
+ ### Gate 1 — SUMMARY.md must exist
118
+
119
+ A retroactive code review requires a completed phase. If no SUMMARY.md
120
+ is present, the phase has not been executed yet and there is nothing to
121
+ review.
122
+
123
+ ```bash
124
+ if [[ "$SUMMARY_PRESENT" != "true" ]]; then
125
+ echo "Error: Phase $PHASE has no SUMMARY.md at $SUMMARY_PATH." >&2
126
+ echo "The phase must be executed (/np:execute-phase) before it can be reviewed." >&2
127
+ exit 1
128
+ fi
129
+ ```
130
+
131
+ ### Gate 2 — REVIEW.md already exists
132
+
133
+ If a prior review is present, let the user choose between re-running,
134
+ viewing the current review, or skipping.
135
+
136
+ ```bash
137
+ if [[ "$HAS_REVIEW" == "true" ]]; then
138
+ CHOICE=$(node np-tools.cjs askuser --json '{
139
+ "type": "select",
140
+ "header": "Existing REVIEW",
141
+ "question": "REVIEW.md already exists for Phase '"$PHASE"'. What would you like to do?",
142
+ "options": [
143
+ {"label": "Re-run — replace the current review", "description": "Re-runs np-code-reviewer and overwrites the existing file."},
144
+ {"label": "View — display current review and exit", "description": "Reads the file and exits without changes."},
145
+ {"label": "Skip — keep current review and exit", "description": "Leaves the file untouched."}
146
+ ]
147
+ }')
148
+ case "$CHOICE" in
149
+ "View"*) cat "$REVIEW_PATH"; exit 0 ;;
150
+ "Skip"*) exit 0 ;;
151
+ esac
152
+ fi
153
+ ```
154
+
155
+ ### Gate 3 — Determine review scope
156
+
157
+ Scope precedence: `--files` override (already path-guarded above) wins;
158
+ otherwise the phase `SUMMARY.md` frontmatter `key_files:` block is the
159
+ source of truth. If neither produces any files, abort with a clear
160
+ error — do NOT fall back to an arbitrary git diff. SUMMARY.md is
161
+ mandatory per Gate 1 and its `key-files:` block is authoritative.
162
+
163
+ ```bash
164
+ if [[ ${#SAFE_FILES[@]} -eq 0 ]]; then
165
+ EXTRACTED=$(SUMMARY_PATH="$SUMMARY_PATH" node -e "
166
+ const fs = require('node:fs');
167
+ const { extractFrontmatter } = require('./lib/frontmatter.cjs');
168
+ const raw = fs.readFileSync(process.env.SUMMARY_PATH, 'utf-8');
169
+ const { frontmatter } = extractFrontmatter(raw);
170
+ const kf = (frontmatter && frontmatter['key-files']) || (frontmatter && frontmatter.key_files) || {};
171
+ const out = [];
172
+ if (Array.isArray(kf.created)) for (const p of kf.created) out.push(String(p));
173
+ if (Array.isArray(kf.modified)) for (const p of kf.modified) out.push(String(p));
174
+ if (out.length) process.stdout.write(out.join('\n'));
175
+ " 2>/dev/null || true)
176
+
177
+ if [[ -n "$EXTRACTED" ]]; then
178
+ while IFS= read -r line; do
179
+ [[ -n "$line" ]] && SAFE_FILES+=("$line")
180
+ done <<< "$EXTRACTED"
181
+ fi
182
+ fi
183
+
184
+ if [[ ${#SAFE_FILES[@]} -eq 0 ]]; then
185
+ echo "Error: no files to review." >&2
186
+ echo " Provide --files=f1,f2,... OR add key-files.created / key-files.modified to $SUMMARY_PATH." >&2
187
+ exit 1
188
+ fi
189
+ ```
190
+
191
+ </pre_flight>
192
+
193
+ ## Philosophy
194
+
195
+ <philosophy>
196
+ A code review is not a bug-finding tool — it is a contract-verification
197
+ pass. The reviewer's job is to answer ONE question: did the
198
+ implementation deliver against its plan (CLAUDE.md, ADRs, PROJECT
199
+ constraints, phase `requirements:`) without introducing critical
200
+ defects along the way? Findings are graded critical / warning / info so
201
+ downstream `/np:code-review-fix` can gate on severity. A review that
202
+ produces a 30-item warning list is usually a planning failure, not an
203
+ execution failure — the planner should tighten the spec next round.
204
+ Scope is the phase, not the whole repo; the `--files` override exists
205
+ for targeted re-reviews after a fix pass, not for repo-wide audits.
206
+
207
+ **Depth semantics** (resolved via init payload or `--depth=` override):
208
+
209
+ | Depth | Scope | Typical use |
210
+ |-------|-------|-------------|
211
+ | `quick` | surface-level: obvious bugs, missing error handling, broken imports | post-fix re-review, large scopes (>50 files) |
212
+ | `standard` | default: correctness + security + plan-contract alignment | normal per-phase review |
213
+ | `deep` | exhaustive: performance, edge cases, threat-model vs implementation | security-sensitive phases, pre-release audits |
214
+
215
+ The reviewer agent branches on `$DEPTH` internally; this workflow only
216
+ selects which value to pass. `--depth` override beats the init-payload
217
+ default (`standard`). Invalid values trigger a warning and keep the
218
+ init default rather than crashing — the review should still run.
219
+
220
+ **Scope precedence** (implemented in the Pre-Flight Gates above):
221
+
222
+ 1. `--files=a,b,c` override (path-guarded) — highest priority
223
+ 2. SUMMARY.md `key-files.created` + `key-files.modified` (agent-owned
224
+ frontmatter produced by `/np:execute-phase`)
225
+ 3. Error — no fall-through to git diff. A git-diff fallback would
226
+ produce noisy reviews of unrelated files; the SUMMARY.md
227
+ `key-files:` contract from Phase 9 plan-phase → Phase 9
228
+ execute-phase is authoritative.
229
+ </philosophy>
230
+
231
+ ## REVIEW.md Frontmatter Contract
232
+
233
+ The reviewer agent (`np-code-reviewer`) owns the REVIEW.md frontmatter.
234
+ The workflow does NOT author or mutate that block. This workflow's
235
+ contract is: (1) ensure the agent has the right input, (2) commit the
236
+ output file atomically. The agent contract is documented in
237
+ `agents/np-code-reviewer.md`; the keys most relevant to the
238
+ downstream `/np:code-review-fix` consumer are:
239
+
240
+ - `status: clean | issues_found | skipped` — drives fix-workflow gate
241
+ - `depth: quick | standard | deep` — echoes the value this workflow passed
242
+ - `files_reviewed: N` and `files_reviewed_list: [f1, f2, …]` — enables
243
+ scope-persistence across `--auto` re-review iterations
244
+ - `findings.critical / findings.warning / findings.info` counts + bodies
245
+
246
+ If the agent produces a file without these keys, the commit still
247
+ proceeds (the workflow is not a schema validator), but
248
+ `/np:code-review-fix` will refuse to consume it — that workflow's FM
249
+ gate is the defense-in-depth layer (T-10-03-06 mitigation).
250
+
251
+ ## Main Flow
252
+
253
+ Single serial spawn — the reviewer is self-contained (file reading,
254
+ finding severity, REVIEW.md writing all happen inside
255
+ `np-code-reviewer`). The agent writes `REVIEW_PATH` with its own
256
+ frontmatter schema (agent-owned, not workflow-owned). See
257
+ `agents/np-code-reviewer.md` for the REVIEW.md FM contract.
258
+
259
+ ### Step 1 — Code reviewer (np-code-reviewer, opus)
260
+
261
+ ```bash
262
+ START=$(node np-tools.cjs metrics start-timestamp)
263
+ MODEL=$(node np-tools.cjs resolve-model np-code-reviewer --profile balanced)
264
+ FILES_JSON=$(printf '%s\n' "${SAFE_FILES[@]}" | node -e '
265
+ const chunks = [];
266
+ process.stdin.on("data", (d) => chunks.push(d));
267
+ process.stdin.on("end", () => {
268
+ const lines = Buffer.concat(chunks).toString("utf-8").split("\n").filter((l) => l.length > 0);
269
+ process.stdout.write(JSON.stringify(lines));
270
+ });
271
+ ')
272
+ # Spawn agent=np-code-reviewer model=$MODEL
273
+ # input: files_to_read=$FILES_JSON (JSON array, whitespace-safe),
274
+ # review_path=$REVIEW_PATH, depth=$DEPTH,
275
+ # phase_dir=$PHASE_DIR, summary_path=$SUMMARY_PATH
276
+ # output: $REVIEW_PATH with agent-owned REVIEW.md frontmatter
277
+ # (status, depth, files_reviewed, files_reviewed_list,
278
+ # findings.{critical,warning,info}, total)
279
+ Task(
280
+ subagent_type="np-code-reviewer",
281
+ model="$MODEL",
282
+ prompt="<files_to_read>$FILES_JSON</files_to_read><config>phase=$PHASE,phase_dir=$PHASE_DIR,review_path=$REVIEW_PATH,depth=$DEPTH,summary_path=$SUMMARY_PATH</config>"
283
+ )
284
+ END=$(node np-tools.cjs metrics end-timestamp)
285
+ node np-tools.cjs metrics record \
286
+ --agent np-code-reviewer --tier opus --resolved-model "$MODEL" \
287
+ --phase "$PHASE" --plan "$PLAN_ID" --task "$TASK_ID" \
288
+ --started "$START" --ended "$END" \
289
+ --tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
290
+ --retry-count 0 --status ok --runtime "$RUNTIME"
291
+ ```
292
+
293
+ ## Validation Gate
294
+
295
+ After the reviewer finishes, verify REVIEW.md was written. If the file
296
+ is missing, the spawn failed silently and the user is prompted to
297
+ re-run or abort.
298
+
299
+ ```bash
300
+ if [[ ! -f "$REVIEW_PATH" ]]; then
301
+ CHOICE=$(node np-tools.cjs askuser --json '{
302
+ "type": "select",
303
+ "header": "REVIEW.md missing",
304
+ "question": "np-code-reviewer did not write REVIEW.md. What would you like to do?",
305
+ "options": [
306
+ {"label": "Re-run np-code-reviewer", "description": "Spawn the reviewer once more."},
307
+ {"label": "Abort", "description": "Exit without committing."}
308
+ ]
309
+ }')
310
+ case "$CHOICE" in
311
+ "Abort") exit 1 ;;
312
+ esac
313
+ fi
314
+ ```
315
+
316
+ ## Commit
317
+
318
+ ```bash
319
+ node np-tools.cjs commit "docs(${PADDED}): add code review report" --files "$REVIEW_PATH"
320
+ ```
321
+
322
+ ## --auto Chain Hint
323
+
324
+ If `--auto` was passed, display a prose directive to the user — the
325
+ follow-up `/np:code-review-fix` invocation stays explicit (in-session
326
+ loop, no daemon per ADR-0001; cross-workflow chaining is the
327
+ `/np:execute-phase` orchestrator's concern, not this workflow's).
328
+
329
+ ```bash
330
+ if [[ "$AUTO_MODE" == "true" ]]; then
331
+ echo ""
332
+ echo "--auto flag set. Next step: /np:code-review-fix $PHASE --auto"
333
+ echo " (re-runs review + fix until clean OR iteration cap 3 reached)"
334
+ fi
335
+ ```
336
+
337
+ ## Scope Guardrail
338
+
339
+ <scope_guardrail>
340
+ **Do:**
341
+ - Run `np-code-reviewer` exactly once per invocation (single-pass review).
342
+ - Emit a metrics record AFTER the Task spawn (D-06).
343
+ - Resolve MODEL via `np-tools.cjs resolve-model` — no hardcoded IDs.
344
+ - Use `np-tools.cjs askuser` for every prompt (INST-03 invariant).
345
+ - Validate `--files` paths through realpath + repo-root-prefix BEFORE
346
+ passing them to the agent (T-10-03-01 path-traversal mitigation).
347
+ - Route the final commit through `np-tools.cjs commit` so
348
+ `lib/git.cjs.assertCommittablePaths()` runs the gitignore-guard.
349
+ - Abort early when SUMMARY.md is missing; retroactive reviews are only
350
+ meaningful against executed phases.
351
+
352
+ **Don't:**
353
+ - Spawn any additional agent beyond `np-code-reviewer`; the fix pass
354
+ is a separate workflow (`/np:code-review-fix`) per atomic-commit
355
+ discipline (ADR-0004, D-21 exception lives inside that workflow).
356
+ - Invoke host-specific prompt tools directly — always route through
357
+ `np-tools.cjs askuser`.
358
+ - Shell out to `/np:code-review-fix` automatically on `--auto`; that
359
+ would nest workflows and violate the atomic-commit model.
360
+ - Skip the metrics record block — the Phase-10 np:stats consumer
361
+ expects one record per Task spawn.
362
+ - Use a git-diff fallback for scope; SUMMARY.md `key-files:` is the
363
+ single source of truth (Gate 3).
364
+ </scope_guardrail>
365
+
366
+ ## Platform Notes
367
+
368
+ <platform_notes>
369
+ **macOS:** `realpath -m` requires GNU coreutils. Install via
370
+ `brew install coreutils` if the path-traversal guard warns about
371
+ "realpath not available". The string-match fallback still rejects
372
+ obvious escapes (`../`, absolute paths) but cannot canonicalize
373
+ symlinks, so valid relative paths with traversal-like components may
374
+ also be rejected — prefer absolute paths under the repo root if the
375
+ fallback rejects a legitimate file.
376
+
377
+ **Windows:** This workflow uses bash features (arrays, process
378
+ substitution). On Windows, it requires Git Bash or WSL. Native
379
+ PowerShell is not supported.
380
+ </platform_notes>
381
+
382
+ ## Output
383
+
384
+ - `{phase_dir}/{padded}-REVIEW.md` — agent-owned frontmatter (status,
385
+ depth, files_reviewed, files_reviewed_list, findings summary) plus
386
+ severity-grouped finding bodies.
387
+ - 1 metrics record in `.nubos-pilot/metrics/phase-${PHASE}.jsonl` for
388
+ the single `np-code-reviewer` Task spawn.
389
+ - One git commit when REVIEW.md is produced successfully.
390
+
391
+ ## Success Criteria
392
+
393
+ - [ ] Phase validated via init payload before any agent spawn
394
+ - [ ] `--files` paths validated through realpath + repo-root-prefix
395
+ (T-10-03-01 mitigation) before being passed to the agent
396
+ - [ ] File scope resolved from `--files` override OR SUMMARY.md
397
+ `key-files:` — no git-diff fallback
398
+ - [ ] Existing REVIEW.md handled via 3-way askuser prompt (Re-run /
399
+ View / Skip)
400
+ - [ ] Depth resolved with validation (quick|standard|deep); invalid
401
+ `--depth=...` warns and keeps the init-payload default
402
+ - [ ] Empty scope results in explicit error (no silent agent spawn)
403
+ - [ ] Agent spawn wrapped in Pattern S-2 metrics block (D-06) with
404
+ `metrics record` within 30 lines of the Task() call (Pitfall 9)
405
+ - [ ] `metrics record` includes `--runtime "$RUNTIME"` resolved at the
406
+ top of the bash block via `lib/runtime/index.cjs.detect()`
407
+ - [ ] REVIEW.md missing after spawn triggers askuser Re-run / Abort
408
+ - [ ] Final commit routed through `np-tools.cjs commit` so
409
+ `lib/git.cjs.assertCommittablePaths()` enforces the
410
+ gitignore-guard (T-10-03-05 defense-in-depth)
411
+ - [ ] `--auto` flag prints a prose hint; it does NOT auto-invoke
412
+ `/np:code-review-fix` (no-daemon invariant ADR-0001)
413
+
414
+ ## Related Workflows
415
+
416
+ - **`/np:code-review-fix <phase> [--auto]`** — consumes REVIEW.md,
417
+ spawns `np-code-fixer` (sonnet), emits per-finding fix commits
418
+ inside the agent (D-21 exception to ADR-0004), then the final
419
+ REVIEW-FIX.md docs commit. The `--auto` iteration loop (capped at
420
+ 3) re-reviews the same `files_reviewed_list` across iterations so
421
+ scope is preserved.
422
+ - **`/np:review <phase>`** — cross-AI peer review that fans out a
423
+ phase-scoped prompt to every installed external CLI
424
+ (gemini/claude/codex/coderabbit/opencode/qwen/cursor) and
425
+ concatenates their outputs into REVIEWS.md. Complementary to
426
+ code-review: that workflow asks the agent "did the code deliver
427
+ against the plan"; `/np:review` asks external AIs "would the plan
428
+ itself hold up to adversarial review".
429
+ - **`/np:ui-review <phase>`** — 6-pillar UI audit (copy, visual,
430
+ color, typography, spacing, experience). Spawns `np-ui-auditor`
431
+ (haiku). Orthogonal to code-review; run both on any UI phase.
432
+ - **`/np:secure-phase <phase>`** and **`/np:validate-phase <phase>`**
433
+ (Phase 10 Plan 10-04) — threat-model and test-coverage audits
434
+ respectively. Chain after code-review for security-sensitive
435
+ phases.
436
+
437
+ ## Design Notes
438
+
439
+ No git-diff Tier-3 fallback: Phase 9 execute-phase guarantees a
440
+ populated `key-files:` block in every SUMMARY.md, making a git-diff
441
+ scope superfluous and noisy. No config-gate short-circuit: the
442
+ workflow is invoked explicitly by the user, so a flag to "skip when
443
+ invoked" would be redundant. Frontmatter-schema validation is
444
+ delegated to the downstream `/np:code-review-fix` FM-gate, which
445
+ refuses to consume a malformed REVIEW.md — this workflow's commit
446
+ step is intentionally permissive so agent issues surface as
447
+ reviewable diffs rather than hidden skips.