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.
- package/agents/np-ai-researcher.md +140 -0
- package/agents/np-code-fixer.md +363 -0
- package/agents/np-code-reviewer.md +351 -0
- package/agents/np-domain-researcher.md +136 -0
- package/agents/np-eval-auditor.md +167 -0
- package/agents/np-eval-planner.md +153 -0
- package/agents/np-executor.md +72 -0
- package/agents/np-framework-selector.md +171 -0
- package/agents/np-nyquist-auditor.md +185 -0
- package/agents/np-plan-checker.md +165 -0
- package/agents/np-planner.md +199 -0
- package/agents/np-researcher.md +150 -0
- package/agents/np-security-auditor.md +206 -0
- package/agents/np-ui-auditor.md +369 -0
- package/agents/np-ui-checker.md +192 -0
- package/agents/np-ui-researcher.md +324 -0
- package/agents/np-verifier.md +79 -0
- package/bin/check-coverage.cjs +40 -0
- package/bin/check-workflows.cjs +171 -0
- package/bin/check-workflows.test.cjs +208 -0
- package/bin/install.js +500 -0
- package/bin/np-tools/_commands.cjs +70 -0
- package/bin/np-tools/add-tests.cjs +171 -0
- package/bin/np-tools/add-tests.test.cjs +122 -0
- package/bin/np-tools/add-todo.cjs +108 -0
- package/bin/np-tools/add-todo.test.cjs +112 -0
- package/bin/np-tools/agent-skills.cjs +14 -0
- package/bin/np-tools/agent-skills.test.cjs +42 -0
- package/bin/np-tools/ai-integration-phase.cjs +109 -0
- package/bin/np-tools/ai-integration-phase.test.cjs +123 -0
- package/bin/np-tools/askuser.cjs +53 -0
- package/bin/np-tools/askuser.test.cjs +49 -0
- package/bin/np-tools/autonomous.cjs +69 -0
- package/bin/np-tools/autonomous.test.cjs +74 -0
- package/bin/np-tools/checkpoint.cjs +101 -0
- package/bin/np-tools/checkpoint.test.cjs +119 -0
- package/bin/np-tools/code-review.cjs +133 -0
- package/bin/np-tools/code-review.test.cjs +96 -0
- package/bin/np-tools/commit-task.cjs +120 -0
- package/bin/np-tools/commit-task.test.cjs +160 -0
- package/bin/np-tools/commit.cjs +103 -0
- package/bin/np-tools/commit.test.cjs +93 -0
- package/bin/np-tools/config.cjs +101 -0
- package/bin/np-tools/config.test.cjs +71 -0
- package/bin/np-tools/discuss-phase-power.cjs +265 -0
- package/bin/np-tools/discuss-phase-power.test.cjs +242 -0
- package/bin/np-tools/discuss-phase.cjs +132 -0
- package/bin/np-tools/discuss-phase.test.cjs +148 -0
- package/bin/np-tools/dispatch.cjs +116 -0
- package/bin/np-tools/doctor.cjs +242 -0
- package/bin/np-tools/eval-review.cjs +116 -0
- package/bin/np-tools/eval-review.test.cjs +123 -0
- package/bin/np-tools/execute-phase.cjs +182 -0
- package/bin/np-tools/execute-phase.test.cjs +116 -0
- package/bin/np-tools/execute-plan.cjs +124 -0
- package/bin/np-tools/execute-plan.test.cjs +82 -0
- package/bin/np-tools/help.cjs +28 -0
- package/bin/np-tools/help.test.cjs +29 -0
- package/bin/np-tools/init-dispatch.test.cjs +91 -0
- package/bin/np-tools/metrics.cjs +97 -0
- package/bin/np-tools/metrics.test.cjs +188 -0
- package/bin/np-tools/new-milestone.cjs +288 -0
- package/bin/np-tools/new-milestone.test.cjs +166 -0
- package/bin/np-tools/new-project.cjs +284 -0
- package/bin/np-tools/new-project.test.cjs +165 -0
- package/bin/np-tools/next.cjs +7 -0
- package/bin/np-tools/next.test.cjs +30 -0
- package/bin/np-tools/park.cjs +48 -0
- package/bin/np-tools/park.test.cjs +50 -0
- package/bin/np-tools/pause-work.cjs +24 -0
- package/bin/np-tools/pause-work.test.cjs +74 -0
- package/bin/np-tools/phase.cjs +71 -0
- package/bin/np-tools/phase.test.cjs +81 -0
- package/bin/np-tools/plan-diff.cjs +57 -0
- package/bin/np-tools/plan-diff.test.cjs +134 -0
- package/bin/np-tools/plan-milestone-gaps.cjs +115 -0
- package/bin/np-tools/plan-milestone-gaps.test.cjs +122 -0
- package/bin/np-tools/plan-phase.cjs +350 -0
- package/bin/np-tools/plan-phase.test.cjs +263 -0
- package/bin/np-tools/progress.cjs +7 -0
- package/bin/np-tools/progress.test.cjs +44 -0
- package/bin/np-tools/queue.cjs +213 -0
- package/bin/np-tools/research-phase.cjs +144 -0
- package/bin/np-tools/research-phase.test.cjs +154 -0
- package/bin/np-tools/reset-slice.cjs +17 -0
- package/bin/np-tools/reset-slice.test.cjs +96 -0
- package/bin/np-tools/resolve-model.cjs +110 -0
- package/bin/np-tools/resolve-model.test.cjs +200 -0
- package/bin/np-tools/resume-work.cjs +76 -0
- package/bin/np-tools/resume-work.test.cjs +91 -0
- package/bin/np-tools/skip.cjs +48 -0
- package/bin/np-tools/skip.test.cjs +66 -0
- package/bin/np-tools/slug.cjs +34 -0
- package/bin/np-tools/slug.test.cjs +46 -0
- package/bin/np-tools/state.cjs +16 -0
- package/bin/np-tools/state.test.cjs +40 -0
- package/bin/np-tools/stats.cjs +151 -0
- package/bin/np-tools/stats.test.cjs +118 -0
- package/bin/np-tools/triage.cjs +128 -0
- package/bin/np-tools/ui-phase.cjs +108 -0
- package/bin/np-tools/ui-phase.test.cjs +121 -0
- package/bin/np-tools/ui-review.cjs +108 -0
- package/bin/np-tools/ui-review.test.cjs +120 -0
- package/bin/np-tools/undo-task.cjs +31 -0
- package/bin/np-tools/undo-task.test.cjs +117 -0
- package/bin/np-tools/undo.cjs +43 -0
- package/bin/np-tools/undo.test.cjs +120 -0
- package/bin/np-tools/unpark.cjs +48 -0
- package/bin/np-tools/unpark.test.cjs +50 -0
- package/bin/np-tools/verify-work.cjs +186 -0
- package/bin/np-tools/verify-work.test.cjs +97 -0
- package/docs/adr/0001-no-daemon-invariant.md +82 -0
- package/docs/adr/0002-zero-runtime-dependencies.md +90 -0
- package/docs/adr/0003-max-six-unit-types.md +85 -0
- package/docs/adr/0004-atomic-commit-per-unit.md +102 -0
- package/docs/adr/0005-three-orthogonal-file-trees.md +98 -0
- package/docs/adr/0006-yaml-dependency-amendment.md +60 -0
- package/docs/adr/README.md +27 -0
- package/docs/agent-frontmatter-schema.md +84 -0
- package/docs/phase-artifact-schemas.md +292 -0
- package/docs/phase-directory-layout.md +82 -0
- package/lib/__tests__/README.md +1 -0
- package/lib/agents.cjs +98 -0
- package/lib/agents.test.cjs +286 -0
- package/lib/askuser.cjs +36 -0
- package/lib/askuser.test.cjs +310 -0
- package/lib/checkpoint.cjs +135 -0
- package/lib/checkpoint.test.cjs +184 -0
- package/lib/core.cjs +165 -0
- package/lib/core.test.cjs +405 -0
- package/lib/fixtures/README.md +1 -0
- package/lib/fixtures/phase-tree/README.md +1 -0
- package/lib/fixtures/plans/cycle/PLAN.md +16 -0
- package/lib/fixtures/plans/cycle/tasks/T-01.md +20 -0
- package/lib/fixtures/plans/cycle/tasks/T-02.md +20 -0
- package/lib/fixtures/plans/cycle/tasks/T-03.md +20 -0
- package/lib/fixtures/plans/linear/PLAN.md +16 -0
- package/lib/fixtures/plans/linear/tasks/T-01.md +20 -0
- package/lib/fixtures/plans/linear/tasks/T-02.md +20 -0
- package/lib/fixtures/plans/linear/tasks/T-03.md +20 -0
- package/lib/fixtures/plans/parallel/PLAN.md +16 -0
- package/lib/fixtures/plans/parallel/tasks/T-01.md +20 -0
- package/lib/fixtures/plans/parallel/tasks/T-02.md +20 -0
- package/lib/fixtures/plans/parallel/tasks/T-03.md +20 -0
- package/lib/fixtures/plans/wave-conflict/PLAN.md +16 -0
- package/lib/fixtures/plans/wave-conflict/tasks/T-01.md +20 -0
- package/lib/fixtures/plans/wave-conflict/tasks/T-02.md +20 -0
- package/lib/fixtures/roadmap/ROADMAP-malformed.md +3 -0
- package/lib/fixtures/roadmap/ROADMAP-minimal.md +51 -0
- package/lib/fixtures/roadmap/roadmap-malformed.yaml +7 -0
- package/lib/fixtures/roadmap/roadmap-minimal.yaml +40 -0
- package/lib/fixtures/roadmap/roadmap-ten-phases.yaml +101 -0
- package/lib/fixtures/templates/phase-context.md +6 -0
- package/lib/fixtures/templates/plan-skeleton.md +6 -0
- package/lib/frontmatter.cjs +251 -0
- package/lib/frontmatter.test.cjs +177 -0
- package/lib/gaps.cjs +197 -0
- package/lib/gaps.test.cjs +200 -0
- package/lib/git.cjs +207 -0
- package/lib/git.test.cjs +305 -0
- package/lib/install/agents-md.cjs +77 -0
- package/lib/install/backup.cjs +70 -0
- package/lib/install/codex-toml.cjs +440 -0
- package/lib/install/managed-block.cjs +30 -0
- package/lib/install/manifest.cjs +148 -0
- package/lib/install/mcp-writer.cjs +127 -0
- package/lib/install/runtime-detect.cjs +44 -0
- package/lib/install/staging.cjs +149 -0
- package/lib/metrics-aggregate.cjs +229 -0
- package/lib/metrics-aggregate.test.cjs +192 -0
- package/lib/metrics.cjs +120 -0
- package/lib/metrics.test.cjs +182 -0
- package/lib/model-aliases.regression.test.cjs +16 -0
- package/lib/model-profiles.cjs +42 -0
- package/lib/model-profiles.test.cjs +61 -0
- package/lib/next.cjs +236 -0
- package/lib/next.test.cjs +194 -0
- package/lib/phase.cjs +95 -0
- package/lib/phase.test.cjs +189 -0
- package/lib/plan-checker-contract.test.cjs +72 -0
- package/lib/plan-diff.cjs +173 -0
- package/lib/plan-diff.test.cjs +217 -0
- package/lib/plan.cjs +85 -0
- package/lib/plan.test.cjs +263 -0
- package/lib/progress.cjs +95 -0
- package/lib/progress.test.cjs +116 -0
- package/lib/researcher-contract.test.cjs +61 -0
- package/lib/roadmap-render.cjs +206 -0
- package/lib/roadmap-render.test.cjs +121 -0
- package/lib/roadmap.cjs +416 -0
- package/lib/roadmap.test.cjs +371 -0
- package/lib/runtime/_contract.test.cjs +61 -0
- package/lib/runtime/_readline.cjs +119 -0
- package/lib/runtime/_readline.test.cjs +126 -0
- package/lib/runtime/claude.cjs +48 -0
- package/lib/runtime/claude.test.cjs +101 -0
- package/lib/runtime/codex.cjs +35 -0
- package/lib/runtime/codex.test.cjs +114 -0
- package/lib/runtime/gemini.cjs +35 -0
- package/lib/runtime/gemini.test.cjs +109 -0
- package/lib/runtime/index.cjs +49 -0
- package/lib/runtime/index.test.cjs +181 -0
- package/lib/runtime/opencode.cjs +35 -0
- package/lib/runtime/opencode.test.cjs +124 -0
- package/lib/state.cjs +205 -0
- package/lib/state.test.cjs +264 -0
- package/lib/surface-audit.test.cjs +46 -0
- package/lib/tasks.cjs +327 -0
- package/lib/tasks.test.cjs +389 -0
- package/lib/template.cjs +66 -0
- package/lib/template.test.cjs +159 -0
- package/lib/undo.cjs +179 -0
- package/lib/undo.test.cjs +261 -0
- package/lib/verify.cjs +116 -0
- package/lib/verify.test.cjs +187 -0
- package/np-tools.cjs +303 -0
- package/package.json +39 -0
- package/templates/AI-SPEC.md +90 -0
- package/templates/CONTEXT.md +32 -0
- package/templates/PLAN.md +69 -0
- package/templates/PROJECT.md +60 -0
- package/templates/REQUIREMENTS.md +38 -0
- package/templates/SECURITY.md +61 -0
- package/templates/UI-SPEC.md +64 -0
- package/templates/VALIDATION.md +76 -0
- package/templates/claude/payload/README.md +11 -0
- package/templates/opencode/opencode.json +6 -0
- package/templates/opencode/payload/AGENTS.md +9 -0
- package/workflows/add-backlog.md +212 -0
- package/workflows/add-tests.md +69 -0
- package/workflows/add-todo.md +222 -0
- package/workflows/ai-integration-phase.md +230 -0
- package/workflows/autonomous.md +94 -0
- package/workflows/cleanup.md +325 -0
- package/workflows/code-review-fix.md +435 -0
- package/workflows/code-review.md +447 -0
- package/workflows/discuss-phase-assumptions.md +269 -0
- package/workflows/discuss-phase-power.md +139 -0
- package/workflows/discuss-phase.md +386 -0
- package/workflows/dispatch.md +9 -0
- package/workflows/doctor.md +10 -0
- package/workflows/eval-review.md +243 -0
- package/workflows/execute-phase.md +142 -0
- package/workflows/execute-plan.md +82 -0
- package/workflows/help.md +8 -0
- package/workflows/new-milestone.md +166 -0
- package/workflows/new-project.md +213 -0
- package/workflows/next.md +8 -0
- package/workflows/note.md +244 -0
- package/workflows/park.md +29 -0
- package/workflows/pause-work.md +34 -0
- package/workflows/plan-milestone-gaps.md +233 -0
- package/workflows/plan-phase.md +351 -0
- package/workflows/progress.md +8 -0
- package/workflows/queue.md +9 -0
- package/workflows/research-phase.md +327 -0
- package/workflows/reset-slice.md +39 -0
- package/workflows/resume-work.md +79 -0
- package/workflows/review.md +489 -0
- package/workflows/secure-phase.md +209 -0
- package/workflows/session-report.md +243 -0
- package/workflows/skip.md +29 -0
- package/workflows/state.md +7 -0
- package/workflows/stats.md +170 -0
- package/workflows/thread.md +214 -0
- package/workflows/triage.md +9 -0
- package/workflows/ui-phase.md +246 -0
- package/workflows/ui-review.md +222 -0
- package/workflows/undo-task.md +42 -0
- package/workflows/undo.md +55 -0
- package/workflows/unpark.md +29 -0
- package/workflows/validate-phase.md +231 -0
- 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.
|