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,435 @@
|
|
|
1
|
+
---
|
|
2
|
+
command: np:code-review-fix
|
|
3
|
+
description: Auto-fixer that consumes REVIEW.md, applies fixes finding-by-finding as per-finding atomic commits (D-21 exception), writes REVIEW-FIX.md. Supports --auto iteration cap 3, --fix-scope=critical|warning|info|all filter. Spawns np-code-fixer (sonnet). Final commit is the REVIEW-FIX.md docs commit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# np:code-review-fix
|
|
7
|
+
|
|
8
|
+
Consumes `{phase_dir}/{padded}-REVIEW.md` (produced by `/np:code-review`) and
|
|
9
|
+
applies fixes via a `np-code-fixer` (sonnet) spawn that emits per-finding
|
|
10
|
+
`fix(...)` commits INSIDE the agent (D-21 exception to ADR-0004) and
|
|
11
|
+
writes `REVIEW-FIX.md` with `status: all_fixed | partial | none_fixed`.
|
|
12
|
+
|
|
13
|
+
The workflow's own final commit is the REVIEW-FIX.md docs commit — it
|
|
14
|
+
is NOT re-emitted for the per-finding fixes. See the Commit section for
|
|
15
|
+
the exact atomic-commit ownership contract between workflow and agent.
|
|
16
|
+
|
|
17
|
+
The single Task-spawn site is wrapped in the Plan 09-05 metrics +
|
|
18
|
+
resolve-model pattern (D-06, D-01). `RUNTIME` is detected once at the
|
|
19
|
+
top of the bash block. All prompts route through `np-tools.cjs askuser`
|
|
20
|
+
(INST-03 invariant).
|
|
21
|
+
|
|
22
|
+
Gate logic: before spawning the fixer, the workflow reads REVIEW.md's
|
|
23
|
+
frontmatter via `lib/frontmatter.cjs.extractFrontmatter`, validates the
|
|
24
|
+
schema (`files_reviewed_list` + `status` + `depth` + `findings`) and
|
|
25
|
+
short-circuits if `status` is `clean` or `skipped` (T-10-03-06
|
|
26
|
+
mitigation, Pitfall 2 defense-in-depth). A malformed REVIEW.md triggers
|
|
27
|
+
an exit before any fix attempt — producer/consumer FM drift is surfaced
|
|
28
|
+
at this layer, not hidden by the agent.
|
|
29
|
+
|
|
30
|
+
## Initialize
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
PHASE="$1"
|
|
34
|
+
if [[ -z "$PHASE" ]]; then
|
|
35
|
+
echo "Usage: /np:code-review-fix <phase-number> [--fix-scope=critical|warning|info|all] [--auto] [--iteration=N]" >&2
|
|
36
|
+
exit 2
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
INIT=$(node np-tools.cjs init code-review "$PHASE")
|
|
40
|
+
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
41
|
+
RUNTIME=$(node -e "console.log(require('./lib/runtime/index.cjs').detect().runtime)")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Parse JSON for: `phase`, `padded`, `phase_dir`, `review_path`,
|
|
45
|
+
`review_fix_path`, `agents.code_fixer`. Note: the init dispatcher
|
|
46
|
+
`code-review` covers both reviewer and fixer workflows — same payload
|
|
47
|
+
shape, different fields consumed.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
PADDED=$(echo "$INIT" | jq -r '.padded')
|
|
51
|
+
PHASE_DIR=$(echo "$INIT" | jq -r '.phase_dir')
|
|
52
|
+
REVIEW_PATH=$(echo "$INIT" | jq -r '.review_path')
|
|
53
|
+
REVIEW_FIX_PATH=$(echo "$INIT" | jq -r '.review_fix_path')
|
|
54
|
+
PLAN_ID="${PADDED}-code-review-fix"
|
|
55
|
+
TASK_ID="${PADDED}-code-review-fix"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Argument Parsing
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
FIX_SCOPE="all"
|
|
62
|
+
AUTO_MODE="false"
|
|
63
|
+
ITERATION=1
|
|
64
|
+
for arg in "$@"; do
|
|
65
|
+
case "$arg" in
|
|
66
|
+
--fix-scope=*) FIX_SCOPE="${arg#--fix-scope=}" ;;
|
|
67
|
+
--auto) AUTO_MODE="true" ;;
|
|
68
|
+
--iteration=*) ITERATION="${arg#--iteration=}" ;;
|
|
69
|
+
esac
|
|
70
|
+
done
|
|
71
|
+
|
|
72
|
+
case "$FIX_SCOPE" in
|
|
73
|
+
critical|warning|info|all) ;;
|
|
74
|
+
*) echo "Warning: invalid --fix-scope='$FIX_SCOPE' (expected critical|warning|info|all). Using 'all'." >&2
|
|
75
|
+
FIX_SCOPE="all" ;;
|
|
76
|
+
esac
|
|
77
|
+
|
|
78
|
+
if ! [[ "$ITERATION" =~ ^[0-9]+$ ]]; then
|
|
79
|
+
echo "Warning: invalid --iteration='$ITERATION' (expected non-negative integer). Using 1." >&2
|
|
80
|
+
ITERATION=1
|
|
81
|
+
fi
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Pre-Flight Gates
|
|
85
|
+
|
|
86
|
+
<pre_flight>
|
|
87
|
+
|
|
88
|
+
### Gate 1 — REVIEW.md presence
|
|
89
|
+
|
|
90
|
+
REVIEW.md MUST exist before fixing. Do NOT auto-run code-review — the
|
|
91
|
+
user's explicit review intent is the contract.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
if [[ ! -f "$REVIEW_PATH" ]]; then
|
|
95
|
+
echo "Error: $REVIEW_PATH not found. Run /np:code-review $PHASE first." >&2
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Gate 2 — REVIEW.md frontmatter schema + status gate
|
|
101
|
+
|
|
102
|
+
Load the REVIEW.md frontmatter once via `lib/frontmatter.cjs` and
|
|
103
|
+
validate the fields downstream consumers depend on. If any required
|
|
104
|
+
field is missing, exit with a clear error — producer/consumer FM drift
|
|
105
|
+
is T-10-03-06 and MUST NOT be silently fixed here.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
FM_JSON=$(REVIEW_PATH="$REVIEW_PATH" node -e "
|
|
109
|
+
const fs = require('node:fs');
|
|
110
|
+
const { extractFrontmatter } = require('./lib/frontmatter.cjs');
|
|
111
|
+
const raw = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
|
|
112
|
+
const { frontmatter } = extractFrontmatter(raw);
|
|
113
|
+
process.stdout.write(JSON.stringify(frontmatter || {}));
|
|
114
|
+
" 2>/dev/null || echo '{}')
|
|
115
|
+
|
|
116
|
+
STATUS=$(echo "$FM_JSON" | jq -r '.status // empty')
|
|
117
|
+
DEPTH=$(echo "$FM_JSON" | jq -r '.depth // empty')
|
|
118
|
+
HAS_FILES_LIST=$(echo "$FM_JSON" | jq -r 'has("files_reviewed_list") // false')
|
|
119
|
+
HAS_FINDINGS=$(echo "$FM_JSON" | jq -r 'has("findings") // false')
|
|
120
|
+
|
|
121
|
+
MISSING=""
|
|
122
|
+
[[ -z "$STATUS" ]] && MISSING="$MISSING status"
|
|
123
|
+
[[ -z "$DEPTH" ]] && MISSING="$MISSING depth"
|
|
124
|
+
[[ "$HAS_FILES_LIST" != "true" ]] && MISSING="$MISSING files_reviewed_list"
|
|
125
|
+
[[ "$HAS_FINDINGS" != "true" ]] && MISSING="$MISSING findings"
|
|
126
|
+
|
|
127
|
+
if [[ -n "$MISSING" ]]; then
|
|
128
|
+
echo "Error: REVIEW.md frontmatter missing required fields:$MISSING" >&2
|
|
129
|
+
echo " Expected schema (owned by np-code-reviewer):" >&2
|
|
130
|
+
echo " status: clean | issues_found | skipped" >&2
|
|
131
|
+
echo " depth: quick | standard | deep" >&2
|
|
132
|
+
echo " files_reviewed_list: [path, ...]" >&2
|
|
133
|
+
echo " findings: { critical: N, warning: N, info: N, total: N }" >&2
|
|
134
|
+
echo " Re-run /np:code-review $PHASE to regenerate." >&2
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Short-circuit on non-actionable statuses:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
case "$STATUS" in
|
|
143
|
+
clean|skipped)
|
|
144
|
+
echo "Nothing to fix — REVIEW.md status=$STATUS."
|
|
145
|
+
exit 0
|
|
146
|
+
;;
|
|
147
|
+
issues_found)
|
|
148
|
+
: # proceed
|
|
149
|
+
;;
|
|
150
|
+
*)
|
|
151
|
+
echo "Warning: unknown REVIEW.md status='$STATUS' (expected clean|skipped|issues_found). Proceeding with fix attempt." >&2
|
|
152
|
+
;;
|
|
153
|
+
esac
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Gate 3 — Existing REVIEW-FIX.md
|
|
157
|
+
|
|
158
|
+
If a prior fix report is present, let the user choose between re-running,
|
|
159
|
+
viewing the current report, or skipping (Pattern S-3).
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
if [[ -f "$REVIEW_FIX_PATH" ]]; then
|
|
163
|
+
CHOICE=$(node np-tools.cjs askuser --json '{
|
|
164
|
+
"type": "select",
|
|
165
|
+
"header": "Existing REVIEW-FIX",
|
|
166
|
+
"question": "REVIEW-FIX.md already exists for Phase '"$PHASE"'. What would you like to do?",
|
|
167
|
+
"options": [
|
|
168
|
+
{"label": "Re-run — replace the current fix report", "description": "Re-runs np-code-fixer and overwrites the existing file + emits additional per-finding fix commits if new fixes apply."},
|
|
169
|
+
{"label": "View — display current fix report and exit", "description": "Reads the file and exits without changes."},
|
|
170
|
+
{"label": "Skip — keep current fix report and exit", "description": "Leaves the file untouched."}
|
|
171
|
+
]
|
|
172
|
+
}')
|
|
173
|
+
case "$CHOICE" in
|
|
174
|
+
"View"*) cat "$REVIEW_FIX_PATH"; exit 0 ;;
|
|
175
|
+
"Skip"*) exit 0 ;;
|
|
176
|
+
esac
|
|
177
|
+
fi
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
</pre_flight>
|
|
181
|
+
|
|
182
|
+
## Philosophy
|
|
183
|
+
|
|
184
|
+
<philosophy>
|
|
185
|
+
A fix workflow that re-emits bulk commits loses the one thing atomic
|
|
186
|
+
commits buy: the ability to `git revert` a single bad fix without
|
|
187
|
+
clobbering the others. The D-21 exception to ADR-0004 exists for
|
|
188
|
+
exactly this reason — the agent owns per-finding `fix(...)` commits
|
|
189
|
+
because the agent is the one that knows which file changes map to
|
|
190
|
+
which REVIEW.md finding ID. The workflow's job is the envelope: gate
|
|
191
|
+
the inputs, resolve the model, wrap the spawn in metrics, and commit
|
|
192
|
+
the final REVIEW-FIX.md artifact ONCE.
|
|
193
|
+
|
|
194
|
+
Fix-scope filtering (`--fix-scope=critical|warning|info|all`) is
|
|
195
|
+
deliberately a coarse filter, not a per-finding whitelist. A
|
|
196
|
+
per-finding whitelist would require the user to read REVIEW.md ahead of
|
|
197
|
+
time, which defeats the auto-fix value proposition. Severity-level
|
|
198
|
+
filtering is the right granularity: "only fix critical issues; I'll
|
|
199
|
+
triage warnings manually."
|
|
200
|
+
|
|
201
|
+
The `--auto` iteration loop (cap 3) drives in-session
|
|
202
|
+
auto-fix attempts. Each iteration re-reviews the SAME
|
|
203
|
+
`files_reviewed_list` captured in REVIEW.md's frontmatter — scope
|
|
204
|
+
does NOT drift across iterations. When `status === clean` is reached,
|
|
205
|
+
the loop exits early. When iteration 3 still returns `partial`,
|
|
206
|
+
remaining issues stay documented in REVIEW-FIX.md for manual triage.
|
|
207
|
+
|
|
208
|
+
Why no workflow-level fix-commit bundling? Because `git log --grep` is
|
|
209
|
+
how users navigate fix history, and a bundled `fix(): apply N fixes`
|
|
210
|
+
commit destroys the grep signal. Per-finding commits with the finding
|
|
211
|
+
ID (e.g., `fix(10-03-T02): CR-042 rename shadowed variable`) are
|
|
212
|
+
searchable, revertable, and reviewable — the atomic-commit tax is
|
|
213
|
+
worth the observability dividend.
|
|
214
|
+
</philosophy>
|
|
215
|
+
|
|
216
|
+
## REVIEW.md → np-code-fixer Contract
|
|
217
|
+
|
|
218
|
+
The fixer agent (`np-code-fixer`) owns BOTH the per-finding fix
|
|
219
|
+
commits AND the final `docs(...)` REVIEW-FIX.md commit. This workflow
|
|
220
|
+
does NOT re-commit after the agent returns. The contract:
|
|
221
|
+
|
|
222
|
+
1. Agent reads `$REVIEW_PATH` frontmatter (same schema validated in
|
|
223
|
+
Gate 2).
|
|
224
|
+
2. Agent filters findings by `--fix-scope` (critical|warning|info|all).
|
|
225
|
+
3. For each finding in scope: agent applies the fix, runs
|
|
226
|
+
`node np-tools.cjs commit "fix(${PADDED}): ${FINDING_ID} <one-line>" --files <path>`
|
|
227
|
+
exactly once per finding (T-10-02-02 mitigation — never raw
|
|
228
|
+
`git commit` shell strings).
|
|
229
|
+
4. Agent writes `$REVIEW_FIX_PATH` with frontmatter:
|
|
230
|
+
`status: all_fixed | partial | none_fixed`, `findings_in_scope: N`,
|
|
231
|
+
`fixed: N`, `skipped: N`, `iteration: $ITERATION`.
|
|
232
|
+
5. Agent emits the final `docs(${PADDED}): add code review fix report`
|
|
233
|
+
commit for REVIEW-FIX.md itself.
|
|
234
|
+
|
|
235
|
+
If the agent produces REVIEW-FIX.md but skips the final docs commit
|
|
236
|
+
(malfunction), the workflow's post-validation below will re-emit it
|
|
237
|
+
from outside the agent — but that is a fallback, not the primary path.
|
|
238
|
+
|
|
239
|
+
## Main Flow
|
|
240
|
+
|
|
241
|
+
### Step 1 — Code fixer (np-code-fixer, sonnet)
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
START=$(node np-tools.cjs metrics start-timestamp)
|
|
245
|
+
MODEL=$(node np-tools.cjs resolve-model np-code-fixer --profile balanced)
|
|
246
|
+
# Spawn agent=np-code-fixer model=$MODEL
|
|
247
|
+
# input: review_path=$REVIEW_PATH, review_fix_path=$REVIEW_FIX_PATH,
|
|
248
|
+
# phase=$PHASE, padded=$PADDED, phase_dir=$PHASE_DIR,
|
|
249
|
+
# fix_scope=$FIX_SCOPE, auto=$AUTO_MODE, iteration=$ITERATION
|
|
250
|
+
# output: $REVIEW_FIX_PATH + 0..N per-finding fix(...) commits
|
|
251
|
+
# (D-21 exception — commits happen INSIDE the agent, not
|
|
252
|
+
# after the Task returns) + final docs(...) REVIEW-FIX.md
|
|
253
|
+
# commit emitted by the agent itself
|
|
254
|
+
Task(
|
|
255
|
+
subagent_type="np-code-fixer",
|
|
256
|
+
model="$MODEL",
|
|
257
|
+
prompt="<files_to_read>$REVIEW_PATH</files_to_read><config>review_path=$REVIEW_PATH,review_fix_path=$REVIEW_FIX_PATH,phase=$PHASE,padded=$PADDED,phase_dir=$PHASE_DIR,fix_scope=$FIX_SCOPE,auto=$AUTO_MODE,iteration=$ITERATION</config>"
|
|
258
|
+
)
|
|
259
|
+
END=$(node np-tools.cjs metrics end-timestamp)
|
|
260
|
+
node np-tools.cjs metrics record \
|
|
261
|
+
--agent np-code-fixer --tier sonnet --resolved-model "$MODEL" \
|
|
262
|
+
--phase "$PHASE" --plan "$PLAN_ID" --task "$TASK_ID" \
|
|
263
|
+
--started "$START" --ended "$END" \
|
|
264
|
+
--tokens-in "${TOKENS_IN:-0}" --tokens-out "${TOKENS_OUT:-0}" \
|
|
265
|
+
--retry-count 0 --status ok --runtime "$RUNTIME"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Validation Gate
|
|
269
|
+
|
|
270
|
+
After the fixer returns, verify REVIEW-FIX.md exists and has a
|
|
271
|
+
`status:` field. If missing, the agent likely failed mid-run; per-
|
|
272
|
+
finding commits that already landed stay in git log for review.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
if [[ ! -f "$REVIEW_FIX_PATH" ]]; then
|
|
276
|
+
echo "Warning: REVIEW-FIX.md not written at $REVIEW_FIX_PATH." >&2
|
|
277
|
+
echo "Agent may have failed mid-run; any fix(...) commits already emitted are in git log." >&2
|
|
278
|
+
echo "Check: git log --oneline --grep=\"fix($PADDED)\"" >&2
|
|
279
|
+
exit 1
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
FIX_STATUS=$(REVIEW_FIX_PATH="$REVIEW_FIX_PATH" node -e "
|
|
283
|
+
const fs = require('node:fs');
|
|
284
|
+
const { extractFrontmatter } = require('./lib/frontmatter.cjs');
|
|
285
|
+
const raw = fs.readFileSync(process.env.REVIEW_FIX_PATH, 'utf-8');
|
|
286
|
+
const { frontmatter } = extractFrontmatter(raw);
|
|
287
|
+
process.stdout.write((frontmatter && frontmatter.status) || '');
|
|
288
|
+
" 2>/dev/null)
|
|
289
|
+
|
|
290
|
+
if [[ -z "$FIX_STATUS" ]]; then
|
|
291
|
+
echo "Warning: REVIEW-FIX.md missing status field in frontmatter." >&2
|
|
292
|
+
fi
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Commit
|
|
296
|
+
|
|
297
|
+
**D-21 EXCEPTION TO ADR-0004:** per-finding `fix(...)` commits were
|
|
298
|
+
already emitted by `np-code-fixer` during its execution. The agent
|
|
299
|
+
also owns the final `docs(...)` commit for REVIEW-FIX.md. This
|
|
300
|
+
workflow does NOT re-commit the fix report on the agent's behalf —
|
|
301
|
+
routing through `git log --oneline` after the spawn will show the
|
|
302
|
+
complete commit chain:
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
docs(10-XX): add code review fix report <- agent-owned final commit
|
|
306
|
+
fix(10-XX): CR-042 rename shadowed var <- per-finding commit
|
|
307
|
+
fix(10-XX): CR-041 add null check <- per-finding commit
|
|
308
|
+
...
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Fallback path — if the agent wrote REVIEW-FIX.md but did NOT commit it
|
|
312
|
+
(e.g., agent crashed between Write and commit), emit the missing docs
|
|
313
|
+
commit from the workflow:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
if ! git diff --cached --quiet "$REVIEW_FIX_PATH" 2>/dev/null || \
|
|
317
|
+
git status --porcelain "$REVIEW_FIX_PATH" 2>/dev/null | grep -q .; then
|
|
318
|
+
echo "Note: REVIEW-FIX.md is uncommitted — agent did not emit final docs commit."
|
|
319
|
+
echo "Emitting fallback docs commit from workflow (D-21 fallback path)."
|
|
320
|
+
node np-tools.cjs commit "docs(${PADDED}): add code review fix report" --files "$REVIEW_FIX_PATH"
|
|
321
|
+
fi
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## --auto Iteration Hint
|
|
325
|
+
|
|
326
|
+
If `--auto` AND FIX_STATUS is `partial`, display a prose directive to
|
|
327
|
+
re-run the review + fix cycle. Do NOT shell-out automatically
|
|
328
|
+
(ADR-0001 no-daemon, in-session loop only). The downstream user
|
|
329
|
+
invokes `/np:code-review $PHASE --auto` → `/np:code-review-fix $PHASE
|
|
330
|
+
--auto --iteration=2` etc., capped at 3 per the agent's contract.
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
if [[ "$AUTO_MODE" == "true" ]] && [[ "$FIX_STATUS" == "partial" ]]; then
|
|
334
|
+
NEXT=$((ITERATION + 1))
|
|
335
|
+
if [[ $NEXT -le 3 ]]; then
|
|
336
|
+
echo ""
|
|
337
|
+
echo "--auto: fix status=partial. Next iteration ($NEXT/3):"
|
|
338
|
+
echo " /np:code-review $PHASE --auto"
|
|
339
|
+
echo " /np:code-review-fix $PHASE --auto --iteration=$NEXT"
|
|
340
|
+
else
|
|
341
|
+
echo ""
|
|
342
|
+
echo "--auto: iteration cap 3 reached with status=partial."
|
|
343
|
+
echo "Remaining issues documented in $REVIEW_FIX_PATH — triage manually."
|
|
344
|
+
fi
|
|
345
|
+
fi
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Scope Guardrail
|
|
349
|
+
|
|
350
|
+
<scope_guardrail>
|
|
351
|
+
**Do:**
|
|
352
|
+
- Spawn `np-code-fixer` exactly once per invocation (single-pass fix).
|
|
353
|
+
- Validate REVIEW.md frontmatter schema in Gate 2 BEFORE spawning the
|
|
354
|
+
fixer (T-10-03-06 producer/consumer drift mitigation).
|
|
355
|
+
- Let the agent own per-finding `fix(...)` commits (D-21 exception).
|
|
356
|
+
- Let the agent own the final `docs(...)` REVIEW-FIX.md commit; this
|
|
357
|
+
workflow's fallback path only fires when the agent skipped it.
|
|
358
|
+
- Emit a metrics record AFTER the Task spawn (D-06).
|
|
359
|
+
- Resolve MODEL via `np-tools.cjs resolve-model` — no hardcoded IDs.
|
|
360
|
+
- Use `np-tools.cjs askuser` for every prompt (INST-03 invariant).
|
|
361
|
+
- Short-circuit on REVIEW.md `status: clean | skipped` — no agent
|
|
362
|
+
spawn, no commit, exit 0.
|
|
363
|
+
- Route every commit (agent-side or fallback) through
|
|
364
|
+
`np-tools.cjs commit` so the gitignore-guard runs.
|
|
365
|
+
|
|
366
|
+
**Don't:**
|
|
367
|
+
- Auto-run `/np:code-review` from this workflow if REVIEW.md is
|
|
368
|
+
missing — require explicit user intent before producing a review.
|
|
369
|
+
- Bundle per-finding fixes into a single commit — atomicity buys
|
|
370
|
+
revertability per finding (D-21).
|
|
371
|
+
- Re-emit the docs commit unconditionally — the agent owns it; this
|
|
372
|
+
workflow's fallback only fires on uncommitted REVIEW-FIX.md.
|
|
373
|
+
- Shell out to `/np:code-review` or `/np:code-review-fix` recursively
|
|
374
|
+
on `--auto`; the iteration hint is prose, user-driven (ADR-0001).
|
|
375
|
+
- Invoke host-specific prompt tools directly — always route through
|
|
376
|
+
`np-tools.cjs askuser`.
|
|
377
|
+
- Skip the metrics record block — the Phase-10 np:stats consumer
|
|
378
|
+
expects one record per Task spawn.
|
|
379
|
+
</scope_guardrail>
|
|
380
|
+
|
|
381
|
+
## Output
|
|
382
|
+
|
|
383
|
+
- `{phase_dir}/{padded}-REVIEW-FIX.md` — agent-owned frontmatter
|
|
384
|
+
(status, findings_in_scope, fixed, skipped, iteration) plus a
|
|
385
|
+
per-finding applied/skipped table with commit hashes.
|
|
386
|
+
- 0..N `fix(${PADDED}): <FINDING_ID> <one-line>` commits (one per
|
|
387
|
+
applied finding; D-21 exception to ADR-0004).
|
|
388
|
+
- 1 `docs(${PADDED}): add code review fix report` commit for
|
|
389
|
+
REVIEW-FIX.md itself (agent-owned; workflow has a fallback).
|
|
390
|
+
- 1 metrics record in `.nubos-pilot/metrics/phase-${PHASE}.jsonl` for
|
|
391
|
+
the single `np-code-fixer` Task spawn.
|
|
392
|
+
|
|
393
|
+
## Success Criteria
|
|
394
|
+
|
|
395
|
+
- [ ] REVIEW.md presence verified (explicit error if missing — no
|
|
396
|
+
auto-run of /np:code-review)
|
|
397
|
+
- [ ] REVIEW.md frontmatter schema validated
|
|
398
|
+
(files_reviewed_list + status + depth + findings present;
|
|
399
|
+
T-10-03-06 mitigation / Pitfall 2)
|
|
400
|
+
- [ ] Short-circuit on REVIEW.md `status: clean | skipped` (exit 0,
|
|
401
|
+
no spawn, no commit)
|
|
402
|
+
- [ ] `--fix-scope` validated to critical|warning|info|all (invalid
|
|
403
|
+
warns and falls back to `all`)
|
|
404
|
+
- [ ] Existing REVIEW-FIX.md handled via 3-way askuser prompt
|
|
405
|
+
- [ ] Agent spawn wrapped in Pattern S-2 metrics block with
|
|
406
|
+
`metrics record` within 30 lines of Task()
|
|
407
|
+
- [ ] Per-finding fix commits happen INSIDE np-code-fixer (D-21),
|
|
408
|
+
NEVER re-emitted by this workflow
|
|
409
|
+
- [ ] Final REVIEW-FIX.md docs commit happens INSIDE np-code-fixer;
|
|
410
|
+
workflow fallback only fires when agent skipped it
|
|
411
|
+
- [ ] `--auto` prints iteration hint (cap 3); does NOT shell-out
|
|
412
|
+
recursively (ADR-0001)
|
|
413
|
+
|
|
414
|
+
## Related Workflows
|
|
415
|
+
|
|
416
|
+
- **`/np:code-review <phase>`** — produces the REVIEW.md that this
|
|
417
|
+
workflow consumes. Run it first. Without REVIEW.md this workflow
|
|
418
|
+
exits with an error.
|
|
419
|
+
- **`/np:review <phase>`** — cross-AI peer review; orthogonal to the
|
|
420
|
+
code-review/fix pair. Runs a fan-out across external CLIs and does
|
|
421
|
+
not interact with REVIEW.md.
|
|
422
|
+
|
|
423
|
+
## Platform Notes
|
|
424
|
+
|
|
425
|
+
<platform_notes>
|
|
426
|
+
**Windows:** This workflow uses bash features (arrays, variable
|
|
427
|
+
expansion, `jq`, process substitution). On Windows, it requires Git
|
|
428
|
+
Bash or WSL. Native PowerShell is not supported.
|
|
429
|
+
|
|
430
|
+
**`jq` dependency:** Gate 2 pipes the frontmatter JSON through `jq`
|
|
431
|
+
for field extraction. `jq` is present on nearly all dev machines
|
|
432
|
+
where nubos-pilot runs (it is the same dependency surface the
|
|
433
|
+
`/np:execute-phase` workflow relies on). If `jq` is missing, install
|
|
434
|
+
via `brew install jq` (macOS) or the distro's package manager.
|
|
435
|
+
</platform_notes>
|