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,214 @@
1
+ ---
2
+ command: np:thread
3
+ description: Create or resume a cross-session thread at .nubos-pilot/threads/<slug>.md. Lifecycle status OPEN → IN_PROGRESS (auto on resume) → RESOLVED (user edits manually, no close command per D-19 Claude's Discretion). No agent spawn. Project-scope only.
4
+ ---
5
+
6
+ # np:thread
7
+
8
+ Implements UTIL-06. Threads are lightweight cross-session context
9
+ stores for work spanning multiple sessions but not belonging to a
10
+ specific phase. They live under `.nubos-pilot/threads/<slug>.md` with
11
+ lifecycle `OPEN → IN_PROGRESS → RESOLVED` in their frontmatter.
12
+
13
+ Two modes, selected by presence of the target file:
14
+
15
+ - **create** — writes a fresh file with `status: OPEN`; one atomic
16
+ docs commit (ADR-0004).
17
+ - **resume** — reads the file, bumps `status: OPEN → IN_PROGRESS`
18
+ (never downgraded), updates `last_resumed`, displays content.
19
+ Resume does **not** commit — `last_resumed` churn is too noisy.
20
+
21
+ No close command (D-19). User manually sets `status: RESOLVED`.
22
+ Pure-CRUD — no agent spawn, no metrics record (Pitfall 9 exempt).
23
+
24
+ ## Initialize
25
+
26
+ ```bash
27
+ SLUG_ARG="$*"
28
+ if [[ -z "$SLUG_ARG" ]]; then
29
+ echo "Usage: /np:thread <slug-or-title>" >&2
30
+ exit 2
31
+ fi
32
+ SLUG=$(node np-tools.cjs generate-slug "$SLUG_ARG" --raw)
33
+ if [[ -z "$SLUG" ]]; then
34
+ echo "Error: argument produced no slug-safe characters." >&2
35
+ exit 1
36
+ fi
37
+ STATE_DIR=$(node -e "console.log(require('./lib/core.cjs').projectStateDir(process.cwd()))")
38
+ THREADS_DIR="${STATE_DIR}/threads"
39
+ THREAD_PATH="${THREADS_DIR}/${SLUG}.md"
40
+ TODAY=$(date +%Y-%m-%d)
41
+ mkdir -p "$THREADS_DIR"
42
+ ```
43
+
44
+ Slug via `generate-slug` (wraps `lib/phase.cjs.phaseSlug`) — only
45
+ `[a-z0-9-]` enters the filename; closes T-10-06-01 (path traversal).
46
+
47
+ ## Create vs Resume Branch
48
+
49
+ ```bash
50
+ if [[ -f "$THREAD_PATH" ]]; then
51
+ MODE="resume"
52
+ else
53
+ MODE="create"
54
+ fi
55
+ ```
56
+
57
+ ## Create Branch (MODE = create)
58
+
59
+ Use the `Write` tool to create `$THREAD_PATH` with the frontmatter +
60
+ body template below (not a bash heredoc). `${SLUG}` / `${SLUG_ARG}` /
61
+ `${TODAY}` are substituted from the variables above.
62
+
63
+ ```markdown
64
+ ---
65
+ slug: <SLUG>
66
+ status: OPEN
67
+ created: <TODAY>
68
+ last_resumed: <TODAY>
69
+ ---
70
+
71
+ # Thread: <SLUG_ARG>
72
+
73
+ ## Status: OPEN
74
+
75
+ ## Goal
76
+
77
+ <TBD — user fills in>
78
+
79
+ ## Context
80
+
81
+ *Created from conversation on <TODAY>.*
82
+
83
+ ## References
84
+
85
+ - *(add links, file paths, or issue numbers)*
86
+
87
+ ## Next Steps
88
+
89
+ - *(what the next session should do first)*
90
+ ```
91
+
92
+ Route the commit through `node np-tools.cjs commit` so
93
+ `lib/git.cjs.assertCommittablePaths()` validates the path before
94
+ `git add` (path-traversal guard from Plan 10-01-T04).
95
+
96
+ ```bash
97
+ if [[ "$MODE" == "create" ]]; then
98
+ node np-tools.cjs commit "docs(10): create thread — ${SLUG}" --files "$THREAD_PATH"
99
+ echo "Thread created: $THREAD_PATH"
100
+ echo ""
101
+ echo "Resume anytime with: /np:thread ${SLUG}"
102
+ fi
103
+ ```
104
+
105
+ ## Resume Branch (MODE = resume)
106
+
107
+ Two in-place updates via `lib/core.cjs.atomicWriteFileSync`
108
+ (ADR-0004 crash-safety):
109
+
110
+ 1. If current `status === "OPEN"`, bump to `IN_PROGRESS`. Status is
111
+ **never downgraded**: `IN_PROGRESS` / `RESOLVED` remain as-is.
112
+ 2. `last_resumed: <TODAY>` — always refreshed.
113
+
114
+ Frontmatter parsed via `lib/frontmatter.cjs.extractFrontmatter` (read)
115
+ and re-serialised via a hand-rolled minimal FM writer (the lib ships
116
+ a reader only) that emits one `key: value` per field in insertion
117
+ order.
118
+
119
+ ```bash
120
+ if [[ "$MODE" == "resume" ]]; then
121
+ node -e "
122
+ const fs = require('node:fs');
123
+ const { extractFrontmatter } = require('./lib/frontmatter.cjs');
124
+ const { atomicWriteFileSync } = require('./lib/core.cjs');
125
+ const p = process.argv[1];
126
+ const today = process.argv[2];
127
+ const raw = fs.readFileSync(p, 'utf-8');
128
+ const { frontmatter, body } = extractFrontmatter(raw);
129
+ const next = Object.assign({}, frontmatter);
130
+ const cur = String(next.status || 'OPEN');
131
+ if (cur === 'OPEN') next.status = 'IN_PROGRESS';
132
+ next.last_resumed = today;
133
+ const order = ['slug', 'status', 'created', 'last_resumed'];
134
+ const seen = new Set();
135
+ const lines = ['---'];
136
+ for (const k of order) {
137
+ if (k in next) { lines.push(k + ': ' + next[k]); seen.add(k); }
138
+ }
139
+ for (const k of Object.keys(next)) {
140
+ if (!seen.has(k)) lines.push(k + ': ' + next[k]);
141
+ }
142
+ lines.push('---');
143
+ const out = lines.join('\n') + '\n' + body;
144
+ atomicWriteFileSync(p, out);
145
+ " "$THREAD_PATH" "$TODAY"
146
+ echo "Thread resumed: $THREAD_PATH"
147
+ echo ""
148
+ echo "--- thread content ---"
149
+ node -e "process.stdout.write(require('node:fs').readFileSync(process.argv[1], 'utf-8'))" "$THREAD_PATH"
150
+ fi
151
+ ```
152
+
153
+ Resume never commits. `last_resumed` churn would flood the log.
154
+
155
+ ## Report
156
+
157
+ Echo `Thread <MODE>d: <THREAD_PATH>` with slug/mode/today to stdout.
158
+
159
+ ## Scope Guardrail
160
+
161
+ <scope_guardrail>
162
+ **Do:**
163
+ - Use `phaseSlug`-generated slug (T-10-06-01 mitigation).
164
+ - Preserve status monotonicity on resume: `OPEN → IN_PROGRESS` only.
165
+ - Let the user manually flip `status: RESOLVED` (D-19 — no close
166
+ command in this adapted port).
167
+ - Use `lib/core.cjs.atomicWriteFileSync` for any in-place rewrite
168
+ (ADR-0004 crash-safety).
169
+ - Route the create-branch commit through `node np-tools.cjs commit`.
170
+
171
+ **Don't:**
172
+ - Commit `last_resumed`-only updates. Resume is commit-free.
173
+ - Invoke host-specific prompt tools directly (the BARE_ASKUSER lint
174
+ in `bin/check-workflows.cjs` blocks them) — route through
175
+ `node np-tools.cjs askuser --json '…'`.
176
+ - Bypass `atomicWriteFileSync` — rename pair is the invariant.
177
+ - Add a `metrics record` block. No Task/Spawn site here; Pitfall 9 /
178
+ `workflow-missing-metrics` is exempt.
179
+ </scope_guardrail>
180
+
181
+ ## Output
182
+
183
+ - `.nubos-pilot/threads/<slug>.md` — thread file. Create mode writes
184
+ a new file with four-field frontmatter (`slug / status:OPEN /
185
+ created / last_resumed`) and four-section body. Resume mode
186
+ updates in-place: `status: IN_PROGRESS` (if OPEN) + refreshed
187
+ `last_resumed`.
188
+ - **Create mode only:** one atomic commit
189
+ `docs(10): create thread — <slug>` (ADR-0004).
190
+ - **Resume mode:** no commit.
191
+
192
+ ## Success Criteria
193
+
194
+ - [ ] Slug via `generate-slug` (T-10-06-01 mitigation).
195
+ - [ ] Threads dir via `lib/core.cjs.projectStateDir`.
196
+ - [ ] Mode selected by `[[ -f $THREAD_PATH ]]`.
197
+ - [ ] Create: `Write` tool + `np-tools.cjs commit` atomic unit.
198
+ - [ ] Resume: `extractFrontmatter` round-trip;
199
+ `OPEN → IN_PROGRESS` only; `last_resumed` refreshed.
200
+ - [ ] Resume writes via `atomicWriteFileSync`; no commit.
201
+ - [ ] Lint clean under `bin/check-workflows.cjs` — no BARE_ASKUSER
202
+ violations, no DIRECT_READ matches.
203
+
204
+ ## Related Workflows
205
+
206
+ - **`/np:add-todo <title>`** — smaller-scope pending todo capture.
207
+ - **`/np:note [--global] <text>`** — zero-friction free-form capture.
208
+ - **`/np:add-backlog <title>`** — promote a thread to a backlog entry.
209
+
210
+ ## Design Notes
211
+
212
+ No list-all mode (no-arg invocation errors). Threads live under
213
+ `.nubos-pilot/threads/` per D-14. Lifecycle frontmatter is the
214
+ machine-readable source-of-truth (no free-text heading parsing).
@@ -0,0 +1,9 @@
1
+ # np:triage
2
+
3
+ Interactive reviewer that walks the unified queue (see `np:queue`) item-by-item.
4
+ For each item, prompts `promote-to-todo | promote-to-phase | keep | drop`.
5
+ Non-TTY runs default to `keep` — safe in CI.
6
+
7
+ ```bash
8
+ node np-tools.cjs triage "$@"
9
+ ```
@@ -0,0 +1,246 @@
1
+ ---
2
+ command: np:ui-phase
3
+ description: Generate UI-SPEC.md for frontend phases via 2-agent revision loop (np-ui-researcher → np-ui-checker) with max 2 iterations and a PASS/FLAG/BLOCK verdict gate.
4
+ ---
5
+
6
+ # np:ui-phase
7
+
8
+ Produces `{phase_dir}/{padded}-UI-SPEC.md` via a researcher → checker
9
+ revision loop (max 2 iterations). Inserts between `/np:discuss-phase` and
10
+ `/np:plan-phase` for UI-heavy phases. Locks the six visual pillars
11
+ (spacing, typography, color, copywriting, design-system, components)
12
+ BEFORE the planner creates tasks so execution stays on-brand.
13
+
14
+ Every Task-spawn site is wrapped in the Plan 09-05 metrics + resolve-model
15
+ pattern (D-06, D-01). `RUNTIME` is detected once at the top of the bash
16
+ block and re-used by every `metrics record` call.
17
+
18
+ ## Initialize
19
+
20
+ ```bash
21
+ PHASE="$1"
22
+ if [[ -z "$PHASE" ]]; then
23
+ echo "Usage: /np:ui-phase <phase-number>" >&2
24
+ exit 2
25
+ fi
26
+
27
+ INIT=$(node np-tools.cjs init ui-phase "$PHASE")
28
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
29
+ RUNTIME=$(node -e "console.log(require('./lib/runtime/index.cjs').detect().runtime)")
30
+ ```
31
+
32
+ Parse JSON for: `phase`, `padded`, `phase_dir`, `ui_spec_path`,
33
+ `has_ui_spec`, `template_path`, `max_iterations`,
34
+ `agents.ui_researcher`, `agents.ui_checker`.
35
+
36
+ ```bash
37
+ PADDED=$(echo "$INIT" | jq -r '.padded')
38
+ PHASE_DIR=$(echo "$INIT" | jq -r '.phase_dir')
39
+ UI_SPEC_PATH=$(echo "$INIT" | jq -r '.ui_spec_path')
40
+ HAS_UI_SPEC=$(echo "$INIT" | jq -r '.has_ui_spec')
41
+ TEMPLATE_PATH=$(echo "$INIT" | jq -r '.template_path')
42
+ MAX_ITER=$(echo "$INIT" | jq -r '.max_iterations')
43
+ PLAN_ID="${PADDED}-ui"
44
+ TASK_ID="${PADDED}-ui"
45
+ ```
46
+
47
+ ## Pre-Flight Gates
48
+
49
+ <pre_flight>
50
+
51
+ ### Gate 1 — UI-SPEC.md already exists
52
+
53
+ If `has_ui_spec == true`:
54
+
55
+ ```bash
56
+ if [[ "$HAS_UI_SPEC" == "true" ]]; then
57
+ CHOICE=$(node np-tools.cjs askuser --json '{
58
+ "type": "select",
59
+ "header": "Existing UI-SPEC",
60
+ "question": "UI-SPEC.md already exists for Phase '"$PHASE"'. What would you like to do?",
61
+ "options": [
62
+ {"label": "Update — re-run researcher with existing as baseline", "description": "Re-runs the researcher→checker loop against the current spec."},
63
+ {"label": "View — display current UI-SPEC and exit", "description": "Reads the file and exits without changes."},
64
+ {"label": "Skip — keep current UI-SPEC and exit", "description": "Leaves the file untouched."}
65
+ ]
66
+ }')
67
+ case "$CHOICE" in
68
+ "View"*) cat "$UI_SPEC_PATH"; exit 0 ;;
69
+ "Skip"*) exit 0 ;;
70
+ esac
71
+ fi
72
+ ```
73
+
74
+ </pre_flight>
75
+
76
+ ## Philosophy
77
+
78
+ <philosophy>
79
+ UI-SPEC.md locks the six pillars most often under-specified in frontend
80
+ work: spacing scale (non-multiple-of-4 breaks grids), typography
81
+ (too many sizes or weights create visual noise), color (accent reserved
82
+ for "all interactive elements" defeats the 60/30/10 split), copywriting
83
+ (generic CTAs like "Submit" / "OK" ship as design debt), design-system
84
+ inventory (pull-once, re-use everywhere), and per-component contracts
85
+ (prop shape + a11y + state machine). Running this loop BEFORE
86
+ `/np:plan-phase` surfaces these decisions as an explicit artifact the
87
+ planner, executor, and ui-auditor can enforce.
88
+ </philosophy>
89
+
90
+ ## Main Flow
91
+
92
+ The researcher and checker alternate for up to `$MAX_ITER` iterations.
93
+ Each iteration wraps both spawns in the Plan-09-05 metrics pattern.
94
+ The checker emits a structured JSON verdict with `overall_status` set
95
+ to `APPROVED` or `BLOCKED`; `BLOCKED` re-invokes the researcher with
96
+ the checker's issue list as feedback.
97
+
98
+ ### Step 0 — Initialize UI-SPEC.md from template
99
+
100
+ ```bash
101
+ if [[ "$HAS_UI_SPEC" != "true" ]]; then
102
+ cp "$TEMPLATE_PATH" "$UI_SPEC_PATH"
103
+ fi
104
+ ITER=0
105
+ VERDICT_PATH="${PHASE_DIR}/${PADDED}-ui-checker-verdict.json"
106
+ ```
107
+
108
+ ### Revision Loop
109
+
110
+ > NOTE: Serial per iteration. The researcher writes UI-SPEC.md; the
111
+ > checker reads it and emits a verdict. On `BLOCKED`, loop with the
112
+ > verdict as feedback. On `APPROVED` or `$ITER >= $MAX_ITER`, exit.
113
+
114
+ ```bash
115
+ while [[ "$ITER" -lt "$MAX_ITER" ]]; do
116
+ ITER=$((ITER + 1))
117
+ ITER_TASK_ID="${TASK_ID}-iter-${ITER}"
118
+ ```
119
+
120
+ #### Step 1 — UI researcher (np-ui-researcher, sonnet)
121
+
122
+ ```bash
123
+ START=$(node np-tools.cjs metrics start-timestamp)
124
+ MODEL=$(node np-tools.cjs resolve-model np-ui-researcher --profile balanced)
125
+ > NOTE: Spawn agent=np-ui-researcher model=$MODEL
126
+ > NOTE: input: phase_number=$PHASE, ui_spec_path=$UI_SPEC_PATH, iteration=$ITER
127
+ > NOTE: on iter >= 2, also pass prior_verdict=$VERDICT_PATH as revision feedback
128
+ > NOTE: output: fully-populated UI-SPEC.md at $UI_SPEC_PATH
129
+ END=$(node np-tools.cjs metrics end-timestamp)
130
+ node np-tools.cjs metrics record \
131
+ --agent np-ui-researcher --tier sonnet --resolved-model "$MODEL" \
132
+ --phase "$PHASE" --plan "$PLAN_ID" --task "$ITER_TASK_ID" \
133
+ --started "$START" --ended "$END" \
134
+ --tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
135
+ --retry-count 0 --status ok --runtime "$RUNTIME"
136
+ ```
137
+
138
+ #### Step 2 — UI checker (np-ui-checker, haiku)
139
+
140
+ ```bash
141
+ START=$(node np-tools.cjs metrics start-timestamp)
142
+ MODEL=$(node np-tools.cjs resolve-model np-ui-checker --profile balanced)
143
+ > NOTE: Spawn agent=np-ui-checker model=$MODEL
144
+ > NOTE: input: ui_spec_path=$UI_SPEC_PATH
145
+ > NOTE: output: structured JSON verdict written to $VERDICT_PATH
146
+ END=$(node np-tools.cjs metrics end-timestamp)
147
+ node np-tools.cjs metrics record \
148
+ --agent np-ui-checker --tier haiku --resolved-model "$MODEL" \
149
+ --phase "$PHASE" --plan "$PLAN_ID" --task "$ITER_TASK_ID" \
150
+ --started "$START" --ended "$END" \
151
+ --tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
152
+ --retry-count 0 --status ok --runtime "$RUNTIME"
153
+ ```
154
+
155
+ #### Step 3 — Evaluate verdict
156
+
157
+ ```bash
158
+ OVERALL=$(jq -r '.overall_status' "$VERDICT_PATH" 2>/dev/null || echo "BLOCKED")
159
+ VERDICT=$(jq -r '.verdict' "$VERDICT_PATH" 2>/dev/null || echo "BLOCK")
160
+ if [[ "$OVERALL" == "APPROVED" ]]; then
161
+ break
162
+ fi
163
+ done
164
+ ```
165
+
166
+ ## Validation Gate
167
+
168
+ After the loop, inspect the final verdict. If still `BLOCKED` after
169
+ `$MAX_ITER` iterations, ask the user to accept with warnings, revise
170
+ manually, or abort. If `APPROVED`, update UI-SPEC.md frontmatter to
171
+ `status: approved` with a review timestamp.
172
+
173
+ ```bash
174
+ OVERALL=$(jq -r '.overall_status' "$VERDICT_PATH" 2>/dev/null || echo "BLOCKED")
175
+
176
+ if [[ "$OVERALL" == "BLOCKED" ]]; then
177
+ CHOICE=$(node np-tools.cjs askuser --json '{
178
+ "type": "select",
179
+ "header": "UI-SPEC still BLOCKED after max iterations",
180
+ "question": "The checker still returns BLOCKED. What would you like to do?",
181
+ "options": [
182
+ {"label": "Accept with warnings", "description": "Proceed; unresolved issues are noted in the commit message."},
183
+ {"label": "Revise manually", "description": "Exit so you can edit UI-SPEC.md by hand."},
184
+ {"label": "Abort", "description": "Exit without committing."}
185
+ ]
186
+ }')
187
+ case "$CHOICE" in
188
+ "Abort") exit 1 ;;
189
+ "Revise manually") exit 0 ;;
190
+ esac
191
+ else
192
+ REVIEWED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
193
+ node np-tools.cjs frontmatter-set "$UI_SPEC_PATH" status approved
194
+ node np-tools.cjs frontmatter-set "$UI_SPEC_PATH" reviewed_at "$REVIEWED_AT"
195
+ fi
196
+ ```
197
+
198
+ > NOTE: `frontmatter-set` is the standard nubos-pilot frontmatter editor;
199
+ > if unavailable, use an equivalent in-place sed/Write pattern per the
200
+ > adapted-port invariant (no direct host-tool edits).
201
+
202
+ ## Commit
203
+
204
+ ```bash
205
+ git add "$UI_SPEC_PATH"
206
+ git commit -m "docs(${PADDED}): generate UI-SPEC.md via 2-agent revision loop"
207
+ ```
208
+
209
+ ## Scope Guardrail
210
+
211
+ <scope_guardrail>
212
+ **Do:**
213
+ - Run researcher and checker serially per iteration (max 2 iterations).
214
+ - Emit a metrics record AFTER every Task spawn (D-06).
215
+ - Resolve every MODEL via `np-tools.cjs resolve-model` — no hardcoded IDs.
216
+ - Use `np-tools.cjs askuser` for every prompt (Phase-3 INST-03 invariant).
217
+ - Commit the final UI-SPEC.md when the checker returns APPROVED or the
218
+ user accepts with warnings.
219
+
220
+ **Don't:**
221
+ - Invoke the host-specific prompt tool directly — always route through
222
+ `np-tools.cjs askuser`.
223
+ - Parallelize researcher + checker — the checker reads what the
224
+ researcher just wrote.
225
+ - Exceed `$MAX_ITER` iterations — the revision loop is bounded to
226
+ prevent runaway costs on stubborn BLOCKs.
227
+ - Call any tools binary other than `np-tools.cjs` (the sole CLI entry
228
+ per Plan 09-05 D-14).
229
+ - Reference legacy homedir payload paths — those directories do not
230
+ exist in nubos-pilot projects.
231
+ - Modify UI-SPEC.md from the checker agent — the checker is read-only
232
+ and the researcher owns writes.
233
+ - Skip any metrics record block — the Phase-10 np:stats consumer
234
+ expects one record per Task spawn.
235
+ </scope_guardrail>
236
+
237
+ ## Output
238
+
239
+ - `{phase_dir}/{padded}-UI-SPEC.md` — filled-in UI design contract with
240
+ `status: approved` frontmatter when the checker passes.
241
+ - `{phase_dir}/{padded}-ui-checker-verdict.json` — last checker verdict
242
+ (JSON); retained for the planner and ui-auditor to consume.
243
+ - Up to 2 × 2 = 4 metrics records in
244
+ `.nubos-pilot/metrics/phase-${PHASE}.jsonl` (one per Task spawn per
245
+ iteration).
246
+ - One git commit (when APPROVED or user accepts with warnings).
@@ -0,0 +1,222 @@
1
+ ---
2
+ command: np:ui-review
3
+ description: Retroactive 6-pillar visual audit of a completed phase. Spawns np-ui-auditor to score copywriting, visuals, color, typography, spacing, and experience design against UI-SPEC.md (if present) or abstract best-practice standards. Produces UI-REVIEW.md.
4
+ ---
5
+
6
+ # np:ui-review
7
+
8
+ Produces `{phase_dir}/{padded}-UI-REVIEW.md` via a single `np-ui-auditor` spawn
9
+ that audits the phase's implemented frontend code. Runs AFTER
10
+ `/np:execute-phase` has landed code — the audit needs a SUMMARY.md to
11
+ know what was built.
12
+
13
+ Two modes:
14
+
15
+ - **Spec-conformance audit** — when `{padded}-UI-SPEC.md` exists (phase
16
+ went through `/np:ui-phase`). Pillars are scored against the declared
17
+ contract.
18
+ - **Retroactive general audit** — when no UI-SPEC is present. Pillars
19
+ are scored against abstract 6-pillar best-practice standards. The
20
+ output file header labels the mode explicitly (Pitfall 10 — avoids
21
+ silent drift between spec-backed and spec-less reviews).
22
+
23
+ The single Task-spawn site is wrapped in the Plan 09-05 metrics +
24
+ resolve-model pattern (D-06, D-01). `RUNTIME` is detected once at the
25
+ top of the bash block and re-used by the `metrics record` call.
26
+
27
+ ## Initialize
28
+
29
+ ```bash
30
+ PHASE="$1"
31
+ if [[ -z "$PHASE" ]]; then
32
+ echo "Usage: /np:ui-review <phase-number>" >&2
33
+ exit 2
34
+ fi
35
+
36
+ INIT=$(node np-tools.cjs init ui-review "$PHASE")
37
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
38
+ RUNTIME=$(node -e "console.log(require('./lib/runtime/index.cjs').detect().runtime)")
39
+ ```
40
+
41
+ Parse JSON for: `phase`, `padded`, `phase_dir`, `ui_review_path`,
42
+ `summary_present`, `summary_path`, `ui_spec_path`, `has_ui_spec`,
43
+ `agents.ui_auditor`.
44
+
45
+ ```bash
46
+ PADDED=$(echo "$INIT" | jq -r '.padded')
47
+ PHASE_DIR=$(echo "$INIT" | jq -r '.phase_dir')
48
+ UI_REVIEW_PATH=$(echo "$INIT" | jq -r '.ui_review_path')
49
+ SUMMARY_PRESENT=$(echo "$INIT" | jq -r '.summary_present')
50
+ SUMMARY_PATH=$(echo "$INIT" | jq -r '.summary_path')
51
+ UI_SPEC_PATH=$(echo "$INIT" | jq -r '.ui_spec_path')
52
+ HAS_UI_SPEC=$(echo "$INIT" | jq -r '.has_ui_spec')
53
+ PLAN_ID="${PADDED}-ui-review"
54
+ TASK_ID="${PADDED}-ui-review"
55
+ ```
56
+
57
+ ## Pre-Flight Gates
58
+
59
+ <pre_flight>
60
+
61
+ ### Gate 1 — SUMMARY.md must exist
62
+
63
+ A retroactive audit requires a completed phase. If no SUMMARY.md is
64
+ present, the phase hasn't been executed yet and there is nothing to
65
+ audit.
66
+
67
+ ```bash
68
+ if [[ "$SUMMARY_PRESENT" != "true" ]]; then
69
+ echo "Error: Phase $PHASE has no SUMMARY.md at $SUMMARY_PATH." >&2
70
+ echo "The phase must be executed (/np:execute-phase) before it can be audited." >&2
71
+ exit 1
72
+ fi
73
+ ```
74
+
75
+ ### Gate 2 — UI-REVIEW.md already exists
76
+
77
+ If a prior review is present, let the user choose between re-running,
78
+ viewing the current review, or skipping.
79
+
80
+ ```bash
81
+ if [[ -f "$UI_REVIEW_PATH" ]]; then
82
+ CHOICE=$(node np-tools.cjs askuser --json '{
83
+ "type": "select",
84
+ "header": "Existing UI-REVIEW",
85
+ "question": "UI-REVIEW.md already exists for Phase '"$PHASE"'. What would you like to do?",
86
+ "options": [
87
+ {"label": "Re-run — replace the current review", "description": "Re-runs np-ui-auditor and overwrites the existing file."},
88
+ {"label": "View — display current review and exit", "description": "Reads the file and exits without changes."},
89
+ {"label": "Skip — keep current review and exit", "description": "Leaves the file untouched."}
90
+ ]
91
+ }')
92
+ case "$CHOICE" in
93
+ "View"*) cat "$UI_REVIEW_PATH"; exit 0 ;;
94
+ "Skip"*) exit 0 ;;
95
+ esac
96
+ fi
97
+ ```
98
+
99
+ ### Gate 3 — Determine audit mode
100
+
101
+ ```bash
102
+ if [[ "$HAS_UI_SPEC" == "true" ]]; then
103
+ AUDIT_MODE="spec-conformance"
104
+ else
105
+ AUDIT_MODE="retroactive-general"
106
+ fi
107
+ ```
108
+
109
+ </pre_flight>
110
+
111
+ ## Philosophy
112
+
113
+ <philosophy>
114
+ UI drift is invisible until you measure it. Copy regresses to "Submit"
115
+ and "OK", accent colors multiply past the 60/30/10 split, spacing
116
+ scales fragment into pixel-perfect one-offs, and empty/error/loading
117
+ states go missing. A retroactive 6-pillar audit catches all of that in
118
+ one pass and produces a ranked list of fixes. When a UI-SPEC.md exists,
119
+ the audit is a conformance check. When it doesn't, the audit is a
120
+ best-practice sweep — and the mode label on UI-REVIEW.md makes that
121
+ difference explicit so reviewers don't treat a general audit as if it
122
+ had SPEC backing.
123
+ </philosophy>
124
+
125
+ ## Main Flow
126
+
127
+ Single serial spawn — the auditor is self-contained (screenshots,
128
+ pillar scoring, registry safety, report writing all happen inside
129
+ `np-ui-auditor`).
130
+
131
+ ### Step 1 — UI auditor (np-ui-auditor, haiku)
132
+
133
+ ```bash
134
+ START=$(node np-tools.cjs metrics start-timestamp)
135
+ MODEL=$(node np-tools.cjs resolve-model np-ui-auditor --profile balanced)
136
+ > NOTE: Spawn agent=np-ui-auditor model=$MODEL
137
+ > NOTE: input: phase_number=$PHASE, phase_dir=$PHASE_DIR,
138
+ > NOTE: summary_path=$SUMMARY_PATH, ui_spec_path=$UI_SPEC_PATH,
139
+ > NOTE: has_ui_spec=$HAS_UI_SPEC, audit_mode=$AUDIT_MODE,
140
+ > NOTE: ui_review_path=$UI_REVIEW_PATH
141
+ > NOTE: output: $UI_REVIEW_PATH with pillar scores, top-3 fixes,
142
+ > NOTE: and a mode label ("spec-conformance" or
143
+ > NOTE: "retroactive-general") in the header frontmatter.
144
+ END=$(node np-tools.cjs metrics end-timestamp)
145
+ node np-tools.cjs metrics record \
146
+ --agent np-ui-auditor --tier haiku --resolved-model "$MODEL" \
147
+ --phase "$PHASE" --plan "$PLAN_ID" --task "$TASK_ID" \
148
+ --started "$START" --ended "$END" \
149
+ --tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
150
+ --retry-count 0 --status ok --runtime "$RUNTIME"
151
+ ```
152
+
153
+ ## Validation Gate
154
+
155
+ After the auditor finishes, verify UI-REVIEW.md was written and carries
156
+ the expected mode label. If the file is missing, the spawn failed
157
+ silently and the user is prompted to re-run or abort.
158
+
159
+ ```bash
160
+ if [[ ! -f "$UI_REVIEW_PATH" ]]; then
161
+ CHOICE=$(node np-tools.cjs askuser --json '{
162
+ "type": "select",
163
+ "header": "UI-REVIEW.md missing",
164
+ "question": "np-ui-auditor did not write UI-REVIEW.md. What would you like to do?",
165
+ "options": [
166
+ {"label": "Re-run np-ui-auditor", "description": "Spawn the auditor once more."},
167
+ {"label": "Abort", "description": "Exit without committing."}
168
+ ]
169
+ }')
170
+ case "$CHOICE" in
171
+ "Abort") exit 1 ;;
172
+ esac
173
+ fi
174
+ ```
175
+
176
+ ## Commit
177
+
178
+ ```bash
179
+ git add "$UI_REVIEW_PATH"
180
+ git commit -m "docs(${PADDED}): generate UI-REVIEW.md (${AUDIT_MODE})"
181
+ ```
182
+
183
+ ## Scope Guardrail
184
+
185
+ <scope_guardrail>
186
+ **Do:**
187
+ - Run `np-ui-auditor` exactly once per invocation (single-pass audit).
188
+ - Emit a metrics record AFTER the Task spawn (D-06).
189
+ - Resolve MODEL via `np-tools.cjs resolve-model` — no hardcoded IDs.
190
+ - Use `np-tools.cjs askuser` for every prompt (INST-03 invariant).
191
+ - Label the audit mode explicitly in UI-REVIEW.md
192
+ (`spec-conformance` when UI-SPEC.md exists, `retroactive-general`
193
+ otherwise) — Pitfall 10 enforcement.
194
+ - Abort early when SUMMARY.md is missing; retroactive audits are only
195
+ meaningful against executed phases.
196
+
197
+ **Don't:**
198
+ - Run this workflow on a phase that has not been executed — there is
199
+ nothing to audit until SUMMARY.md lands.
200
+ - Invoke host-specific prompt tools directly — always route through
201
+ `np-tools.cjs askuser`.
202
+ - Silently treat a spec-less audit as if it had SPEC backing — the
203
+ mode label in the output header is mandatory.
204
+ - Spawn any additional agent beyond `np-ui-auditor`; if a follow-up
205
+ remediation pass is needed, that is the planner's job, not this
206
+ workflow's.
207
+ - Call any tools binary other than `np-tools.cjs` (the sole CLI entry
208
+ per Plan 09-05 D-14).
209
+ - Reference legacy homedir payload paths — those directories do not
210
+ exist in nubos-pilot projects.
211
+ - Skip the metrics record block — the Phase-10 np:stats consumer
212
+ expects one record per Task spawn.
213
+ </scope_guardrail>
214
+
215
+ ## Output
216
+
217
+ - `{phase_dir}/{padded}-UI-REVIEW.md` — pillar scores, top-3 priority
218
+ fixes, detailed findings, and mode label
219
+ (`spec-conformance` or `retroactive-general`).
220
+ - 1 metrics record in `.nubos-pilot/metrics/phase-${PHASE}.jsonl`
221
+ for the single `np-ui-auditor` Task spawn.
222
+ - One git commit when UI-REVIEW.md is produced successfully.