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,327 @@
1
+ ---
2
+ command: np:research-phase
3
+ description: Phase-level technical research — spawn the researcher subagent, produce RESEARCH.md, fall back to local-only sources when WebFetch + Context7 are both unavailable.
4
+ ---
5
+
6
+ # np:research-phase
7
+
8
+ Phase-level technical research. Spawns the `researcher` subagent
9
+ (`agents/np-researcher.md`, tier=sonnet per Phase-5 D-13) with phase context and
10
+ produces `{phase_dir}/{padded}-RESEARCH.md`.
11
+
12
+ Standalone research command. For most workflows, use `/np:plan-phase` which
13
+ integrates research automatically. This command is the audit-friendly entry
14
+ point: it runs research **in isolation** and commits its artifact before
15
+ planning starts.
16
+
17
+ ## Philosophy
18
+
19
+ <philosophy>
20
+ Research is investigation, not confirmation. The researcher's job is to
21
+ surface what the ecosystem actually uses — not to rationalise a library
22
+ choice the planner already made. Every claim in RESEARCH.md carries a
23
+ confidence tag (`[VERIFIED]`, `[CITED: url]`, `[ASSUMED]`); the planner and
24
+ plan-checker weight downstream decisions accordingly. An incomplete
25
+ RESEARCH.md with honest scope-markers beats a complete one with unverified
26
+ claims (see Phase-5 D-22 — the `## Research Coverage` section is the
27
+ mechanism that lets the planner discount library-version claims made
28
+ without WebFetch / Context7).
29
+ </philosophy>
30
+
31
+ ## Scope Guardrail
32
+
33
+ <scope_guardrail>
34
+ This workflow ONLY writes `{phase_dir}/{padded}-RESEARCH.md`. It NEVER:
35
+
36
+ - edits `roadmap.yaml` or `.nubos-pilot/ROADMAP.md`
37
+ - touches STATE.md
38
+ - mutates another phase's directory
39
+ - re-runs discuss-phase or plan-phase on the user's behalf
40
+
41
+ When the researcher returns a `## CHECKPOINT REACHED` block, the workflow
42
+ surfaces it and exits — it does NOT attempt to resume mid-research
43
+ automatically. Resumption is a Phase 6 executor concern.
44
+ </scope_guardrail>
45
+
46
+ ## Downstream Awareness
47
+
48
+ <downstream_awareness>
49
+ `{phase_dir}/{padded}-RESEARCH.md` is consumed by the planner
50
+ (`agents/np-planner.md`) and then by plan-checker. The planner turns
51
+ "Standard Stack" entries into literal task actions ("Install `jose@6.0.10`")
52
+ and "Common Pitfalls" into verification steps. If the offline path was
53
+ taken, plan-checker grep-matches `## Research Coverage` and emits a
54
+ `missing-coverage-annotation` finding when the section is absent — that is
55
+ why Step 4 below validates the section presence after spawn.
56
+ </downstream_awareness>
57
+
58
+ ## Answer Validation
59
+
60
+ <answer_validation>
61
+ Before exiting, confirm:
62
+
63
+ 1. `{phase_dir}/{padded}-RESEARCH.md` exists and is non-empty.
64
+ 2. If `MODE == offline`, the file contains a literal `## Research Coverage`
65
+ heading (D-22).
66
+ 3. If the user declined the offline-confirm prompt, RESEARCH.md was NOT
67
+ written (D-23) and the abort message surfaced verbatim.
68
+
69
+ All confirmations route through `node np-tools.cjs askuser --json '{...}'`.
70
+ Never a bare prompt-tool invocation — Phase-3 D-03 rename rule
71
+ enforced by `bin/check-workflows.cjs` (the guard rejects any line that
72
+ mentions the forbidden Claude-Code prompt-tool identifier outside a
73
+ `np-tools.cjs` wrapper).
74
+ </answer_validation>
75
+
76
+ ## Step 0: Parse Phase Argument
77
+
78
+ The phase number is the positional argument to `/np:research-phase <N>`.
79
+
80
+ ```bash
81
+ PHASE="$1"
82
+ if [[ -z "$PHASE" ]]; then
83
+ echo "Usage: /np:research-phase <phase-number>" >&2
84
+ exit 2
85
+ fi
86
+ ```
87
+
88
+ ## Step 1: Single-Call Init
89
+
90
+ All phase context is gathered in one call to
91
+ `node np-tools.cjs init research-phase <N>`. The subcommand returns a JSON
92
+ payload; larger payloads are written to a tmp file and referenced via
93
+ `@file:<path>`.
94
+
95
+ ```bash
96
+ INIT=$(node np-tools.cjs init research-phase "$PHASE")
97
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
98
+ RUNTIME=$(node -e "console.log(require('./lib/runtime/index.cjs').detect().runtime)")
99
+ ```
100
+
101
+ `RUNTIME` is resolved once here and reused by the metrics-record call at the
102
+ researcher spawn site (Step 4) per D-06 workflow-writer pattern.
103
+
104
+ The payload shape:
105
+
106
+ ```json
107
+ {
108
+ "_workflow": "research-phase",
109
+ "phase": 5,
110
+ "padded": "05",
111
+ "phase_dir": "/abs/.nubos-pilot/phases/05-planning",
112
+ "goal": "…",
113
+ "requirements": ["PLAN-03", "…"],
114
+ "has_research": false,
115
+ "tools_available": {
116
+ "WebFetch": true,
117
+ "Context7": false
118
+ },
119
+ "agent_skills": { "np-researcher": ["…"] }
120
+ }
121
+ ```
122
+
123
+ Extract fields:
124
+
125
+ ```bash
126
+ PADDED=$(echo "$INIT" | jq -r '.padded')
127
+ PHASE_DIR=$(echo "$INIT" | jq -r '.phase_dir')
128
+ HAS_RESEARCH=$(echo "$INIT" | jq -r '.has_research')
129
+ WEBFETCH_AVAILABLE=$(echo "$INIT" | jq -r '.tools_available.WebFetch')
130
+ CONTEXT7_AVAILABLE=$(echo "$INIT" | jq -r '.tools_available.Context7')
131
+ CONTEXT_PATH="$PHASE_DIR/$PADDED-CONTEXT.md"
132
+ RESEARCH_PATH="$PHASE_DIR/$PADDED-RESEARCH.md"
133
+ PLAN_ID="${PADDED}-research"
134
+ TASK_ID="${PADDED}-researcher"
135
+ ```
136
+
137
+ `PLAN_ID` / `TASK_ID` default to stable tokens for the metrics record at the
138
+ researcher spawn site (D-08 schema requires both fields; phase-level research
139
+ has no per-plan/per-task identity so the defaults act as phase-scoped labels).
140
+
141
+ ## Step 2: Guard against Overwrite
142
+
143
+ When `has_research` is already `true`, ask the user how to proceed rather
144
+ than silently clobbering the existing file.
145
+
146
+ ```bash
147
+ if [[ "$HAS_RESEARCH" == "true" ]]; then
148
+ node np-tools.cjs askuser --json '{
149
+ "type": "select",
150
+ "prompt": "RESEARCH.md already exists for this phase. How do you want to proceed?",
151
+ "options": ["Overwrite", "Append-update", "Abort"]
152
+ }'
153
+ fi
154
+ ```
155
+
156
+ On `Abort` the workflow exits 0 without touching anything. On
157
+ `Append-update` the researcher is spawned with `mode=append`; on
158
+ `Overwrite` with `mode=overwrite`.
159
+
160
+ ## Step 3: Offline Fallback (D-21)
161
+
162
+ When both `WebFetch` and `Context7` report unavailable (both `false` in the
163
+ init payload), the researcher cannot verify library versions or fetch
164
+ external docs. Route the verbatim D-21 German confirm prompt through
165
+ `askUser`:
166
+
167
+ ```bash
168
+ MODE=online
169
+ if [[ "$WEBFETCH_AVAILABLE" == "false" && "$CONTEXT7_AVAILABLE" == "false" ]]; then
170
+ CONFIRM=$(node np-tools.cjs askuser --json '{"type":"confirm","question":"Kein Web-/Context7-Zugriff verfügbar — mit lokalen Quellen (Repo + Prior-Phase-CONTEXT.md) fortfahren?"}')
171
+ if [[ "$CONFIRM" != "yes" && "$CONFIRM" != "true" ]]; then
172
+ echo "Research aborted. Run \`np:plan-phase $PHASE --skip-research\` to proceed without research."
173
+ exit 0
174
+ fi
175
+ MODE=offline
176
+ fi
177
+ ```
178
+
179
+ The German prompt text is **verbatim** from `agents/np-researcher.md` (Plan
180
+ 05-03, D-21). The abort message on decline is **verbatim** from D-23. Do
181
+ not rephrase either string — downstream greps and plan-checker rules match
182
+ on exact content.
183
+
184
+ ## Step 4: Spawn the Researcher Subagent
185
+
186
+ The spawn call is intentionally abstract — no runtime-specific syntax. The
187
+ Phase 8 runtime adapters (`claude-code`, `codex`, `gemini`, `opencode`)
188
+ bind the string `Spawn agent=np-researcher …` to whichever mechanism that
189
+ runtime supports (`Task(…)` for Claude Code, shell subprocess for Codex,
190
+ etc.). Keeping this abstract here means the workflow stays runtime-neutral.
191
+
192
+ Before spawning, resolve the researcher model via `np-tools.cjs resolve-model`
193
+ and capture the start timestamp for the metrics record (D-06 workflow-writer
194
+ pattern). An empty `$RESEARCHER_MODEL` string signals the runtime adapter to
195
+ omit the `model:` parameter at spawn (Phase 8 D-22 inherit-pattern).
196
+
197
+ ```bash
198
+ RESEARCHER_START=$(node np-tools.cjs metrics start-timestamp)
199
+ RESEARCHER_MODEL=$(node np-tools.cjs resolve-model researcher --profile balanced)
200
+ ```
201
+
202
+ ```text
203
+ Spawn agent=np-researcher tier=sonnet model=$RESEARCHER_MODEL mode=$MODE phase=$PHASE context=$CONTEXT_PATH output=$RESEARCH_PATH
204
+ ```
205
+
206
+ After the spawn returns, close the metrics record with the 15-field D-08
207
+ schema. Token counts default to `0` when the host runtime does not surface
208
+ `Task()` usage to the workflow (non-Claude runtimes, or Claude without
209
+ usage-capture — Phase 10 will enrich this via runtime-adapter support per
210
+ RESEARCH §A5).
211
+
212
+ ```bash
213
+ RESEARCHER_END=$(node np-tools.cjs metrics end-timestamp)
214
+ node np-tools.cjs metrics record \
215
+ --agent np-researcher --tier sonnet --resolved-model "$RESEARCHER_MODEL" \
216
+ --phase "$PHASE" --plan "$PLAN_ID" --task "$TASK_ID" \
217
+ --started "$RESEARCHER_START" --ended "$RESEARCHER_END" \
218
+ --tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
219
+ --retry-count "${RETRY_COUNT:-0}" --status "${STATUS:-ok}" --runtime "$RUNTIME"
220
+ ```
221
+
222
+ The researcher reads:
223
+
224
+ - `$CONTEXT_PATH` (user decisions from `/np:discuss-phase`) when present
225
+ - the requirements + goal embedded in `$INIT`
226
+ - prior-phase `*-CONTEXT.md` files (for offline dependency signals)
227
+
228
+ The researcher writes exactly one file: `$RESEARCH_PATH`. It may invoke
229
+ `WebFetch` / `mcp__context7__*` when `$MODE == online`, or fall back to
230
+ `Read` / `Grep` / `Glob` only when `$MODE == offline`.
231
+
232
+ ## Step 5: Validate the Research Coverage Section (D-22)
233
+
234
+ When `MODE == offline`, RESEARCH.md MUST contain a literal
235
+ `## Research Coverage` heading (D-22 in CONTEXT.md). Missing the section
236
+ while running offline is a correctness bug — plan-checker will otherwise
237
+ over-weight library-version claims the researcher could not verify.
238
+
239
+ ```bash
240
+ if [[ "$MODE" == "offline" ]]; then
241
+ if ! grep -q '^## Research Coverage$' "$RESEARCH_PATH"; then
242
+ echo "research-missing-coverage: $RESEARCH_PATH is missing the '## Research Coverage' section required for offline research (D-22)" >&2
243
+ exit 1
244
+ fi
245
+ fi
246
+ ```
247
+
248
+ When `MODE == online` the section must NOT appear (D-22 inverse) — the
249
+ check-workflows guard in Phase 10 (plan-checker review command) will flag
250
+ unnecessary coverage annotations so the planner treats them as signal, not
251
+ noise.
252
+
253
+ ## Step 6: Handle Researcher Return Block
254
+
255
+ Classify the researcher's structured-return block:
256
+
257
+ - `## RESEARCH COMPLETE` — display the one-paragraph summary, suggest
258
+ `/np:plan-phase $PHASE` as the next step.
259
+ - `## CHECKPOINT REACHED` — surface the checkpoint block to the user and
260
+ exit (scope_guardrail: no auto-resume).
261
+ - `## RESEARCH INCONCLUSIVE` — display the attempts log, ask the user
262
+ whether to retry with different context or mark the phase as
263
+ research-skipped (`--skip-research` path in `/np:plan-phase`).
264
+
265
+ ```bash
266
+ node np-tools.cjs askuser --json '{
267
+ "type": "select",
268
+ "prompt": "Research artifact written. What next?",
269
+ "options": ["Plan phase", "Review RESEARCH.md", "Done"]
270
+ }'
271
+ ```
272
+
273
+ ## Step 7: Commit RESEARCH.md
274
+
275
+ Respects `.nubos-pilot/config.json`'s `commit_docs` flag (default `true`).
276
+ Skipped entirely when research was aborted via D-23.
277
+
278
+ ```bash
279
+ COMMIT_DOCS=$(node -e 'try{
280
+ const c=require("./.nubos-pilot/config.json");
281
+ process.stdout.write(String(c.commit_docs !== false));
282
+ }catch(e){process.stdout.write("true");}')
283
+
284
+ if [[ "$COMMIT_DOCS" == "true" ]]; then
285
+ git add "$RESEARCH_PATH"
286
+ if ! git diff --cached --quiet; then
287
+ git commit --no-verify -m "docs($PADDED): research phase $PHASE ($MODE mode)"
288
+ fi
289
+ else
290
+ echo "commit_docs=false — RESEARCH.md remains staged-dirty" >&2
291
+ fi
292
+ ```
293
+
294
+ ## Naming Conventions (D-03)
295
+
296
+ Canonical tokens this workflow uses:
297
+
298
+ | Token | Value |
299
+ | ----------------------------- | ---------------------------- |
300
+ | Tools-binary CJS entry | `np-tools.cjs` |
301
+ | Slash-command for research | `/np:research-phase` |
302
+ | Researcher subagent name | `researcher` |
303
+ | Phase directory root | `.nubos-pilot/phases/…` |
304
+ | Claude-Code `Task(…)` spawn | abstract `Spawn agent=…` |
305
+
306
+ Auto-advance state lives on `workflow.auto_advance` (boolean). Set
307
+ from `/np:autonomous`; cleared when the loop exits or the user aborts.
308
+
309
+ ## Exit Codes
310
+
311
+ - `0` — research produced, or user aborted cleanly (D-23 decline,
312
+ overwrite-abort).
313
+ - `1` — validation failure (e.g. `research-missing-coverage` on the
314
+ offline path).
315
+ - `2` — usage error (missing phase argument).
316
+
317
+ ## See Also
318
+
319
+ - `agents/np-researcher.md` — the spawned subagent's contract (tier, tools,
320
+ D-21..D-23 protocol).
321
+ - `bin/np-tools/research-phase.cjs` — init subcommand (payload shape, env
322
+ var contract for tools_available).
323
+ - `tests/fixtures/research/offline-sample.md` — golden RESEARCH.md sample
324
+ with the `## Research Coverage` section; consumed by plan-checker
325
+ contract tests.
326
+ - `/np:plan-phase` — integrates research automatically; invoke this
327
+ standalone workflow only when you want an audit-friendly research commit.
@@ -0,0 +1,39 @@
1
+ ---
2
+ command: np:reset-slice
3
+ description: Restore working-tree files of the in-flight task and clear current_task. Cheap, working-tree-only — no commit history change.
4
+ ---
5
+
6
+ # /np:reset-slice
7
+
8
+ <objective>
9
+ Discard the unsaved work of the currently in-flight task: `git restore`
10
+ each file in the checkpoint's `files_touched`, delete the checkpoint,
11
+ clear `STATE.current_task`, flip task status back to `pending`. No commit
12
+ is made and no history is rewritten — this is the cheapest possible undo
13
+ of a task that is mid-execution.
14
+ </objective>
15
+
16
+ ## Execution
17
+
18
+ ```bash
19
+ CHOICE=$(node np-tools.cjs askuser --json '{
20
+ "type": "select",
21
+ "header": "Reset slice bestätigen",
22
+ "question": "Working-Tree-Änderungen des aktuellen Tasks (gemäß checkpoint.files_touched) werden via git restore zurückgesetzt. Fortfahren?",
23
+ "options": [
24
+ {"label": "Confirm", "description": "Working-Tree zurücksetzen, checkpoint löschen, Task-Status pending."},
25
+ {"label": "Cancel", "description": "Nichts ändern."}
26
+ ]
27
+ }')
28
+ case "$CHOICE" in
29
+ Confirm*) node np-tools.cjs reset-slice ;;
30
+ *) echo "Aborted." ; exit 0 ;;
31
+ esac
32
+ ```
33
+
34
+ ## Scope Guardrail
35
+
36
+ **Do:** `git restore` files_touched; delete checkpoint; clear
37
+ `STATE.current_task`; flip task status → pending.
38
+ **Don't:** revert commits (use `/np:undo-task`); touch files outside
39
+ files_touched (T-06-19 accepted).
@@ -0,0 +1,79 @@
1
+ ---
2
+ command: np:resume-work
3
+ description: Classify session state (resume | orphan | clean) from STATE + checkpoints; re-spawn executor or prompt user for orphan handling.
4
+ ---
5
+
6
+ # /np:resume-work
7
+
8
+ <objective>
9
+ Re-enter a paused session. Returns one of three states; the workflow acts
10
+ on each accordingly.
11
+ </objective>
12
+
13
+ ## Initialize
14
+
15
+ ```bash
16
+ INIT=$(node np-tools.cjs init resume-work)
17
+ STATUS=$(echo "$INIT" | node -e "process.stdin.on('data', d => console.log(JSON.parse(d).status))")
18
+ ```
19
+
20
+ ## Execution
21
+
22
+ ### status: resume
23
+
24
+ STATE.current_task matches an in-progress checkpoint. Spawn
25
+ `agents/np-executor.md` with the checkpoint payload so it continues from
26
+ `resume_hint`:
27
+
28
+ ```bash
29
+ if [ "$STATUS" = "resume" ]; then
30
+ TASK_ID=$(echo "$INIT" | node -e "process.stdin.on('data', d => console.log(JSON.parse(d).task_id))")
31
+ # Hand the task payload + checkpoint to agents/np-executor.md; on completion
32
+ # the agent invokes `node np-tools.cjs commit-task "$TASK_ID"` as usual.
33
+ echo "Resuming task $TASK_ID via agents/np-executor.md …"
34
+ fi
35
+ ```
36
+
37
+ ### status: orphan
38
+
39
+ Checkpoints exist but none match `STATE.current_task`:
40
+
41
+ ```bash
42
+ if [ "$STATUS" = "orphan" ]; then
43
+ CHOICE=$(node np-tools.cjs askuser --json '{
44
+ "type": "select",
45
+ "header": "Verwaiste Checkpoints",
46
+ "question": "Es existieren Checkpoint-Dateien, aber STATE.current_task passt nicht. Wie vorgehen?",
47
+ "options": [
48
+ {"label": "Clean working tree (reset-slice)", "description": "Verwirft in-flight Änderungen und löscht den Checkpoint."},
49
+ {"label": "Adopt orphan as current_task", "description": "STATE wird auf den gefundenen Checkpoint gesetzt; Executor übernimmt."},
50
+ {"label": "Abort", "description": "Exit, User entscheidet manuell."}
51
+ ]
52
+ }')
53
+ case "$CHOICE" in
54
+ "Abort") exit 0 ;;
55
+ esac
56
+ fi
57
+ ```
58
+
59
+ ### status: clean
60
+
61
+ No active work. Print the next-step hint:
62
+
63
+ ```bash
64
+ if [ "$STATUS" = "clean" ]; then
65
+ node np-tools.cjs next
66
+ fi
67
+ ```
68
+
69
+ ## Scope Guardrail
70
+
71
+ **Do:** trust `init resume-work`'s classification verbatim; route each
72
+ status to its corresponding handler.
73
+ **Don't:** invent a fourth status; skip the askUser gate on orphan;
74
+ silently overwrite STATE.
75
+
76
+ ## Output
77
+
78
+ - One of: executor re-spawn, user-driven orphan resolution, or next-step
79
+ hint. STATE.md changes only via the chosen handler.