@izkac/forgekit 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 (143) hide show
  1. package/bin/forge.mjs +100 -0
  2. package/bin/forgekit.mjs +84 -0
  3. package/bin/review.mjs +82 -0
  4. package/package.json +46 -0
  5. package/scripts/prepack.mjs +78 -0
  6. package/scripts/run-tests.mjs +43 -0
  7. package/src/adr.mjs +236 -0
  8. package/src/adr.test.mjs +170 -0
  9. package/src/change.mjs +234 -0
  10. package/src/change.test.mjs +83 -0
  11. package/src/cleanup-sessions.mjs +70 -0
  12. package/src/config.mjs +103 -0
  13. package/src/defer.mjs +75 -0
  14. package/src/doctor.mjs +341 -0
  15. package/src/doctor.test.mjs +114 -0
  16. package/src/init.mjs +575 -0
  17. package/src/install.mjs +777 -0
  18. package/src/install.test.mjs +104 -0
  19. package/src/integrity-check.mjs +58 -0
  20. package/src/integrity.mjs +317 -0
  21. package/src/integrity.test.mjs +296 -0
  22. package/src/lib/workspaces.mjs +55 -0
  23. package/src/lib.mjs +138 -0
  24. package/src/models.defaults.json +41 -0
  25. package/src/new-session.mjs +82 -0
  26. package/src/openspec-overlays/README.md +19 -0
  27. package/src/openspec-overlays/openspec-apply-change-footer.md +14 -0
  28. package/src/openspec-overlays/opsx-apply-completion-step.md +1 -0
  29. package/src/openspec-overlays/opsx-apply-implement-step.md +11 -0
  30. package/src/paths.mjs +92 -0
  31. package/src/plan-engine.mjs +260 -0
  32. package/src/plan-engine.test.mjs +245 -0
  33. package/src/preferences.defaults.json +78 -0
  34. package/src/preferences.mjs +438 -0
  35. package/src/preferences.test.mjs +174 -0
  36. package/src/record-evidence.mjs +204 -0
  37. package/src/record-evidence.test.mjs +260 -0
  38. package/src/resolve-model.mjs +312 -0
  39. package/src/resolve-model.test.mjs +194 -0
  40. package/src/review/carryforward.mjs +413 -0
  41. package/src/review/carryforward.test.mjs +587 -0
  42. package/src/review/cli.test.mjs +117 -0
  43. package/src/review/export.mjs +172 -0
  44. package/src/review/export.test.mjs +197 -0
  45. package/src/review/fixtures/valid-review.json +42 -0
  46. package/src/review/lib.mjs +894 -0
  47. package/src/review/lib.test.mjs +266 -0
  48. package/src/review/merge-tentative.mjs +292 -0
  49. package/src/review/merge-tentative.test.mjs +363 -0
  50. package/src/review/new-review.mjs +200 -0
  51. package/src/review/render.mjs +108 -0
  52. package/src/review/schema-consistency.test.mjs +83 -0
  53. package/src/review/schema.json +196 -0
  54. package/src/review/signals.mjs +144 -0
  55. package/src/review/signals.test.mjs +62 -0
  56. package/src/score-cli.mjs +68 -0
  57. package/src/score.mjs +489 -0
  58. package/src/score.test.mjs +253 -0
  59. package/src/session-reminder.mjs +168 -0
  60. package/src/session-status.mjs +70 -0
  61. package/src/set-models.mjs +186 -0
  62. package/src/set-phase.mjs +177 -0
  63. package/src/set-phase.test.mjs +317 -0
  64. package/src/set-prefs.mjs +294 -0
  65. package/src/spine.mjs +91 -0
  66. package/src/triage-prompt.mjs +175 -0
  67. package/src/triage-prompt.test.mjs +50 -0
  68. package/src/vendor-openspec-overlays.mjs +176 -0
  69. package/src/vendor-openspec-overlays.test.mjs +62 -0
  70. package/vendor/skills/archive-to-adr/SKILL.md +149 -0
  71. package/vendor/skills/forge/SKILL.md +136 -0
  72. package/vendor/skills/forge/phases/brainstorm.md +23 -0
  73. package/vendor/skills/forge/phases/finish.md +87 -0
  74. package/vendor/skills/forge/phases/implement.md +76 -0
  75. package/vendor/skills/forge/phases/plan-openspec.md +40 -0
  76. package/vendor/skills/forge/phases/plan-specs.md +97 -0
  77. package/vendor/skills/forge/phases/review.md +25 -0
  78. package/vendor/skills/forge/phases/verify.md +120 -0
  79. package/vendor/skills/forge/references/forge-layout.md +85 -0
  80. package/vendor/skills/forge/references/pace.md +115 -0
  81. package/vendor/skills/forge/references/plan-routing.md +51 -0
  82. package/vendor/skills/forge/references/runtime-integrity.md +157 -0
  83. package/vendor/skills/forge/references/substantial-work.md +37 -0
  84. package/vendor/skills/forge/references/tdd-core.md +29 -0
  85. package/vendor/skills/forge/references/test-evidence.md +30 -0
  86. package/vendor/skills/forge/references/test-strategy.md +68 -0
  87. package/vendor/skills/forge/skills/NOTICE.md +17 -0
  88. package/vendor/skills/forge/skills/brainstorming/SKILL.md +120 -0
  89. package/vendor/skills/forge/skills/requesting-code-review/SKILL.md +67 -0
  90. package/vendor/skills/forge/skills/requesting-code-review/code-reviewer.md +146 -0
  91. package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -0
  92. package/vendor/skills/forge/skills/systematic-debugging/SKILL.md +234 -0
  93. package/vendor/skills/forge/skills/systematic-debugging/condition-based-waiting.md +115 -0
  94. package/vendor/skills/forge/skills/systematic-debugging/defense-in-depth.md +122 -0
  95. package/vendor/skills/forge/skills/systematic-debugging/find-polluter.sh +63 -0
  96. package/vendor/skills/forge/skills/systematic-debugging/root-cause-tracing.md +169 -0
  97. package/vendor/skills/forge/skills/test-driven-development/SKILL.md +290 -0
  98. package/vendor/skills/forge/skills/test-driven-development/testing-anti-patterns.md +299 -0
  99. package/vendor/skills/forge/skills/verification-before-completion/SKILL.md +59 -0
  100. package/vendor/skills/forge/subagents/final-reviewer-prompt.md +53 -0
  101. package/vendor/skills/forge/subagents/implementer-prompt.md +38 -0
  102. package/vendor/skills/forge/subagents/task-reviewer-prompt.md +61 -0
  103. package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -0
  104. package/vendor/skills/thorough-code-review/SKILL.md +290 -0
  105. package/vendor/skills/thorough-code-review/examples/accepted-risks-janus.md +32 -0
  106. package/vendor/skills/thorough-code-review/examples.md +133 -0
  107. package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -0
  108. package/vendor/skills/thorough-code-review/reference/lenses.md +96 -0
  109. package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -0
  110. package/vendor/skills/thorough-code-review/reference/phase1c-coverage.md +44 -0
  111. package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -0
  112. package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -0
  113. package/vendor/skills/thorough-code-review/reference/report-template.md +115 -0
  114. package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -0
  115. package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -0
  116. package/vendor/templates/adr/README.md +7 -0
  117. package/vendor/templates/adr/decisions.md +141 -0
  118. package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -0
  119. package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -0
  120. package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -0
  121. package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -0
  122. package/vendor/templates/project/claude/commands/forge-apply.md +75 -0
  123. package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -0
  124. package/vendor/templates/project/claude/commands/forge-build.md +17 -0
  125. package/vendor/templates/project/claude/commands/forge-plan.md +12 -0
  126. package/vendor/templates/project/claude/commands/forge-skip.md +14 -0
  127. package/vendor/templates/project/claude/commands/forge-status.md +16 -0
  128. package/vendor/templates/project/claude/commands/forge.md +16 -0
  129. package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -0
  130. package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -0
  131. package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -0
  132. package/vendor/templates/project/claude/rules/forge.md +16 -0
  133. package/vendor/templates/project/codex/rules/forge.md +10 -0
  134. package/vendor/templates/project/cursor/commands/forge-apply.md +75 -0
  135. package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -0
  136. package/vendor/templates/project/cursor/commands/forge-build.md +17 -0
  137. package/vendor/templates/project/cursor/commands/forge-plan.md +15 -0
  138. package/vendor/templates/project/cursor/commands/forge-skip.md +14 -0
  139. package/vendor/templates/project/cursor/commands/forge-status.md +16 -0
  140. package/vendor/templates/project/cursor/commands/forge.md +16 -0
  141. package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -0
  142. package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -0
  143. package/vendor/templates/project/cursor/rules/forge.mdc +21 -0
@@ -0,0 +1,44 @@
1
+ # Phase 1.5 — Coverage pass (recall)
2
+
3
+ You are the **coverage critic**. The scout and skeptic together make confirmed findings trustworthy (precision); they do nothing about what the scout *missed* (recall). Your job is to close that gap.
4
+
5
+ **This pass normally runs orchestrator-inline** — the orchestrator already holds the scope and the merged tentative list. Dispatch it as a subagent only when the scope was partitioned and the file list is too large to re-check in context.
6
+
7
+ **You receive the scope, the active lenses, and the merged tentative-finding list.**
8
+
9
+ ## Inputs
10
+
11
+ - **Scope:** {SCOPE_TYPE} — {SCOPE_DETAIL}
12
+ - **Lenses:** {LENS_LIST}
13
+ - **Tentative findings:** {FINDING_SUMMARY} (ids + locations + lenses)
14
+ - **Signals:** {SIGNALS_SUMMARY} (which grounding tools ran and their status)
15
+
16
+ ## Checks
17
+
18
+ 1. **File coverage.** List every file in scope. For each that received **zero** tentative findings, decide: genuinely clean (state why — trivial, well-tested, unchanged logic) or **not actually reviewed**. Re-read the latter.
19
+ 2. **Lens coverage.** For each active lens that produced **zero** findings, decide: the code truly has no such issue, or the lens was not exercised on this scope. Re-inspect the latter against [lenses.md](lenses.md).
20
+ 3. **Blind spots.** Check the kinds of issue a single forward pass tends to miss:
21
+ - error/edge paths and early returns not on the happy path
22
+ - cross-file and cross-service interactions (callers of changed exports)
23
+ - what a change *removed* (deleted guard, dropped test, narrowed type)
24
+ - config, migrations, and generated artifacts in scope but easy to skim past
25
+ 4. **Signal gaps.** Any grounding tool `skipped` that should have run for this scope? Flag it.
26
+
27
+ ## Output
28
+
29
+ ```yaml
30
+ coverage:
31
+ files_reviewed: [list]
32
+ files_skipped: [list] # in scope but deliberately not deep-read (say why in notes)
33
+ lenses_without_findings:
34
+ - lens: performance
35
+ reason: no loops, queries, or allocations introduced
36
+ new_findings: [] # follow-up tentative findings (F-### / dup-###),
37
+ # full scout format; they go through Phase 2 like the rest
38
+ ```
39
+
40
+ ## Rules
41
+
42
+ - A zero-finding lens or file is a claim that needs a one-line justification — not a silent gap.
43
+ - New findings you raise are **tentative**; the skeptic still verifies them. Do not confirm anything here.
44
+ - **Hard cap: 10 follow-up findings**, prioritized by severity. If you found more, keep the top 10 and note the overflow count in the coverage ledger notes.
@@ -0,0 +1,105 @@
1
+ # Phase 2 — Skeptic pass
2
+
3
+ You are an **adversarial skeptic**. Your job is to **disprove** the scout's claim unless evidence confirms it.
4
+
5
+ **You receive only this packet — no chat history.** It may contain **one finding** (critical, or an important finding alone in its file) or a **batch of findings sharing a file or module** (important: ≤4, minor: ≤6) — steelman and verdict each finding independently; never let one verdict color another.
6
+
7
+ ## Finding(s) under review
8
+
9
+ One block per finding:
10
+
11
+ ```
12
+ id: {FINDING_ID}
13
+ lens: {LENS}
14
+ location: {LOCATION}
15
+ claim: {CLAIM}
16
+ evidence: {EVIDENCE}
17
+ context: {CONTEXT_EXCERPT} # ±30 lines around the cited location, from the scout
18
+ related: {RELATED} # callers, test files, ADR paths
19
+ tentative_severity: {SEVERITY}
20
+ confidence: {CONFIDENCE}
21
+ ```
22
+
23
+ Start from `context` and `related` — most verdicts need only 1–2 additional reads. Read more files only when the disproof checklist genuinely requires it.
24
+
25
+ ## Scope context
26
+
27
+ - **Scope:** {SCOPE_DESCRIPTION}
28
+ - **Mode:** {MODE} <!-- `initial` or `reverify` -->
29
+ - **Accepted risks:** {ACCEPTED_RISKS_DIGEST} <!-- contents of reference/accepted-risks.md -->
30
+
31
+ Check the digest **before** reading `docs/adr/` — if it covers the claim and no re-open trigger fired, the verdict is `false_positive` (cite the ADR id). Read full ADRs only when the digest is silent.
32
+
33
+ ## Steelman rule
34
+
35
+ First, restate the **strongest** version of the claim — the worst reasonable interpretation an attacker or failure mode could exploit.
36
+
37
+ ## Disproof checklist
38
+
39
+ Attempt each before concluding:
40
+
41
+ 1. **Call chain** — trace callers and callees; does the dangerous path actually execute?
42
+ 2. **Data flow** — is input attacker-controlled at the sink?
43
+ 3. **Tests** — read (or run if feasible) tests covering this path
44
+ 4. **Framework mitigations** — middleware, ORM parameterization, framework defaults
45
+ 5. **Deployment boundary** — internal-only API, LAN trust model, ADR-accepted risk
46
+ 6. **Project docs** — `docs/adr/`, `AGENTS.md`, prior security reviews
47
+ 7. **Intent** — comment, type guard, or early return that negates the claim
48
+
49
+ ## Verdict (initial review)
50
+
51
+ | Verdict | When |
52
+ | ------- | ---- |
53
+ | `confirmed` | Issue is real at stated or higher severity |
54
+ | `false_positive` | Claim does not hold after investigation |
55
+ | `downgraded` | Real issue but lower severity — set `severity` and `original_severity` |
56
+ | `needs_decision` | Architectural/policy choice; not a clear defect |
57
+
58
+ **Requirements:**
59
+
60
+ - `verdict_reason` must cite specific evidence (file:line, test name, ADR id).
61
+ - "Looks fine" without evidence is invalid.
62
+ - Upgrade severity only with **new** evidence not in the scout packet.
63
+
64
+ ## Risk-weighted second opinion
65
+
66
+ A single skeptic returning `false_positive` is itself a single point of failure — it can quietly bury a real bug. The orchestrator dispatches a **second independent skeptic** (no history, blind to the first verdict) when the finding is in the **dangerous quadrant**:
67
+
68
+ - `severity` is `critical`/`important` **and** the first verdict is `false_positive`, or
69
+ - `phase1_confidence: high` **and** the first verdict is `false_positive` (scout/skeptic disagreement), or
70
+ - `phase1_confidence: low` **and** `severity: critical` (high-stakes, low-certainty).
71
+
72
+ If you are the second skeptic, verify independently and return your verdict in the `second_opinion` block. When the two skeptics disagree, the orchestrator keeps the higher-severity outcome or routes to `needs_decision` — a disagreement is never silently resolved in favour of dismissal.
73
+
74
+ ## Verdict (reverify mode)
75
+
76
+ When `MODE` is `reverify`, the finding was previously `confirmed` or `downgraded`. Read **current** code at `location`.
77
+
78
+ | Verdict | When |
79
+ | ------- | ---- |
80
+ | `resolved` | Fix fully addresses the issue |
81
+ | `still_open` | Issue persists unchanged |
82
+ | `partially_fixed` | Improved but incomplete |
83
+ | `regressed` | Fix introduced new problem or made it worse |
84
+
85
+ Include `verdict_reason` with before/after comparison.
86
+
87
+ ## Output
88
+
89
+ Return one structured block **per finding** for synthesis:
90
+
91
+ ```yaml
92
+ id: F-001
93
+ lens: security
94
+ location: path:line
95
+ claim: ...
96
+ severity: critical | important | minor
97
+ original_severity: ... # required if downgraded
98
+ verdict: confirmed | false_positive | downgraded | needs_decision | resolved | still_open | partially_fixed | regressed
99
+ verdict_reason: ...
100
+ evidence: ...
101
+ second_opinion: # only for dangerous-quadrant findings
102
+ verdict: ...
103
+ verdict_reason: ...
104
+ agrees: true | false
105
+ ```
@@ -0,0 +1,222 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://forgekit.local/schemas/code-review-report.json",
4
+ "title": "ThoroughCodeReviewReport",
5
+ "type": "object",
6
+ "required": ["review_id", "kind", "created_at", "scope", "lenses", "summary", "findings"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "review_id": { "type": "string", "minLength": 1 },
10
+ "kind": { "type": "string", "enum": ["review", "reverify"] },
11
+ "created_at": { "type": "string", "format": "date-time" },
12
+ "scope": {
13
+ "type": "object",
14
+ "required": ["type", "description"],
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "type": {
18
+ "type": "string",
19
+ "enum": ["uncommitted", "branch", "paths", "commit_range", "file"]
20
+ },
21
+ "description": { "type": "string", "minLength": 1 },
22
+ "base_sha": { "type": "string" },
23
+ "head_sha": { "type": "string" },
24
+ "paths": { "type": "array", "items": { "type": "string" } }
25
+ }
26
+ },
27
+ "lenses": {
28
+ "type": "array",
29
+ "minItems": 1,
30
+ "items": {
31
+ "type": "string",
32
+ "enum": [
33
+ "security",
34
+ "correctness",
35
+ "smells",
36
+ "architecture",
37
+ "performance",
38
+ "tests",
39
+ "contracts",
40
+ "errors",
41
+ "maintainability"
42
+ ]
43
+ }
44
+ },
45
+ "parent_report": { "type": "string" },
46
+ "summary": {
47
+ "type": "object",
48
+ "required": ["tentative_count"],
49
+ "additionalProperties": true,
50
+ "properties": {
51
+ "tentative_count": { "type": "integer", "minimum": 0 },
52
+ "headline": { "type": "string" },
53
+ "top_actions": { "type": "array", "items": { "type": "string" } },
54
+ "confirmed": { "type": "integer", "minimum": 0 },
55
+ "downgraded": { "type": "integer", "minimum": 0 },
56
+ "false_positive": { "type": "integer", "minimum": 0 },
57
+ "needs_decision": { "type": "integer", "minimum": 0 },
58
+ "resolved": { "type": "integer", "minimum": 0 },
59
+ "still_open": { "type": "integer", "minimum": 0 },
60
+ "partially_fixed": { "type": "integer", "minimum": 0 },
61
+ "regressed": { "type": "integer", "minimum": 0 }
62
+ }
63
+ },
64
+ "findings": {
65
+ "type": "array",
66
+ "items": { "$ref": "#/$defs/finding" }
67
+ },
68
+ "dedupe_preflight": {
69
+ "type": "object",
70
+ "additionalProperties": false,
71
+ "properties": {
72
+ "count": { "type": "integer", "minimum": 0 },
73
+ "items": {
74
+ "type": "array",
75
+ "items": {
76
+ "type": "object",
77
+ "required": ["id", "location", "claim"],
78
+ "properties": {
79
+ "id": { "type": "string" },
80
+ "location": { "type": "string" },
81
+ "claim": { "type": "string" }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ },
87
+ "coverage": {
88
+ "type": "object",
89
+ "description": "Recall / completeness pass ledger.",
90
+ "additionalProperties": true,
91
+ "properties": {
92
+ "files_reviewed": { "type": "array", "items": { "type": "string" } },
93
+ "files_skipped": { "type": "array", "items": { "type": "string" } },
94
+ "lenses_without_findings": {
95
+ "type": "array",
96
+ "items": {
97
+ "type": "object",
98
+ "required": ["lens", "reason"],
99
+ "properties": {
100
+ "lens": {
101
+ "type": "string",
102
+ "enum": [
103
+ "security",
104
+ "correctness",
105
+ "smells",
106
+ "architecture",
107
+ "performance",
108
+ "tests",
109
+ "contracts",
110
+ "errors",
111
+ "maintainability"
112
+ ]
113
+ },
114
+ "reason": { "type": "string", "minLength": 1 }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ },
120
+ "signals": {
121
+ "type": "object",
122
+ "description": "Signals pre-flight: deterministic tools run before the scout.",
123
+ "additionalProperties": true,
124
+ "properties": {
125
+ "tools": {
126
+ "type": "array",
127
+ "items": {
128
+ "type": "object",
129
+ "required": ["name"],
130
+ "properties": {
131
+ "name": { "type": "string", "minLength": 1 },
132
+ "status": { "type": "string", "enum": ["pass", "fail", "skipped"] },
133
+ "summary": { "type": "string" }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ },
139
+ "stats": {
140
+ "type": "object",
141
+ "description": "Pipeline stats: subagent counts and shortcut tallies for the run.",
142
+ "additionalProperties": false,
143
+ "properties": {
144
+ "scouts": { "type": "integer", "minimum": 0 },
145
+ "skeptics_dedicated": { "type": "integer", "minimum": 0 },
146
+ "skeptics_batched": { "type": "integer", "minimum": 0 },
147
+ "inline_verdicts": { "type": "integer", "minimum": 0 },
148
+ "grounded_skips": { "type": "integer", "minimum": 0 },
149
+ "carried_forward": { "type": "integer", "minimum": 0 },
150
+ "second_opinions": { "type": "integer", "minimum": 0 }
151
+ }
152
+ }
153
+ },
154
+ "$defs": {
155
+ "finding": {
156
+ "type": "object",
157
+ "required": ["id", "lens", "location", "claim", "severity", "verdict", "verdict_reason"],
158
+ "additionalProperties": false,
159
+ "properties": {
160
+ "id": { "type": "string", "pattern": "^(F|dup)-[0-9]{3}$" },
161
+ "title": { "type": "string", "minLength": 1 },
162
+ "lens": {
163
+ "type": "string",
164
+ "enum": [
165
+ "security",
166
+ "correctness",
167
+ "smells",
168
+ "architecture",
169
+ "performance",
170
+ "tests",
171
+ "contracts",
172
+ "errors",
173
+ "maintainability"
174
+ ]
175
+ },
176
+ "location": { "type": "string", "minLength": 1 },
177
+ "claim": { "type": "string", "minLength": 1 },
178
+ "evidence": { "type": "string" },
179
+ "severity": { "type": "string", "enum": ["critical", "important", "minor"] },
180
+ "phase1_confidence": { "type": "string", "enum": ["low", "medium", "high"] },
181
+ "original_severity": { "type": "string", "enum": ["critical", "important", "minor"] },
182
+ "verdict": {
183
+ "type": "string",
184
+ "enum": [
185
+ "confirmed",
186
+ "false_positive",
187
+ "downgraded",
188
+ "needs_decision",
189
+ "resolved",
190
+ "still_open",
191
+ "partially_fixed",
192
+ "regressed"
193
+ ]
194
+ },
195
+ "verdict_reason": { "type": "string", "minLength": 1 },
196
+ "second_opinion": {
197
+ "type": "object",
198
+ "description": "Independent second skeptic for dangerous-quadrant findings.",
199
+ "required": ["verdict", "verdict_reason"],
200
+ "additionalProperties": false,
201
+ "properties": {
202
+ "verdict": {
203
+ "type": "string",
204
+ "enum": [
205
+ "confirmed",
206
+ "false_positive",
207
+ "downgraded",
208
+ "needs_decision",
209
+ "resolved",
210
+ "still_open",
211
+ "partially_fixed",
212
+ "regressed"
213
+ ]
214
+ },
215
+ "verdict_reason": { "type": "string", "minLength": 1 },
216
+ "agrees": { "type": "boolean" }
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }
@@ -0,0 +1,115 @@
1
+ # Code review report template
2
+
3
+ **Generated, not hand-authored.** The JSON sidecar is the single source of truth; the paired markdown is produced from it by `review render --file <json>`. This file documents the structure the renderer emits — edit the JSON (and the renderer in the review CLI `lib.mjs`), never the `.md` directly.
4
+
5
+ Path: `.reviews/<timestamp>-<scope-slug>-review.md` (or `-reverify.md` for fix verification), per [report-schema.json](report-schema.json).
6
+
7
+ ---
8
+
9
+ ```markdown
10
+ # Code review — {SCOPE_DESCRIPTION}
11
+
12
+ **Review ID:** {REVIEW_ID}
13
+ **Kind:** review | reverify
14
+ **Created:** {ISO_TIMESTAMP}
15
+ **Scope:** {SCOPE_TYPE} — {SCOPE_DETAIL}
16
+ **Lenses:** {LENS_LIST}
17
+ **Parent report:** {PARENT_REVIEW_ID or —}
18
+
19
+ ## Executive summary
20
+
21
+ {TWO_TO_FOUR_SENTENCES: what was reviewed, verdict counts, overall risk posture.}
22
+
23
+ ### Verdict counts
24
+
25
+ | Verdict | Count |
26
+ | ------- | ----- |
27
+ | Confirmed | |
28
+ | Downgraded | |
29
+ | False positive | |
30
+ | Needs decision | |
31
+ | Resolved | |
32
+ | Still open | |
33
+ | Partially fixed | |
34
+ | Regressed | |
35
+
36
+ ### Top actions
37
+
38
+ 1. {Highest priority confirmed/critical item}
39
+ 2. {Second}
40
+ 3. {Third}
41
+
42
+ ---
43
+
44
+ ## Critical
45
+
46
+ ### {F-001}: {Short title}
47
+
48
+ - **Lens:** security
49
+ - **Location:** `path:line`
50
+ - **Severity:** critical {or `minor (was important)` when downgraded}
51
+ - **Verdict:** confirmed
52
+ - **Claim:** ...
53
+ - **Reason:** ...
54
+ - **Second skeptic:** {only for dangerous-quadrant findings} verdict — reason
55
+
56
+ {Repeat per finding}
57
+
58
+ ---
59
+
60
+ ## Important
61
+
62
+ {Same structure}
63
+
64
+ ---
65
+
66
+ ## Minor
67
+
68
+ {Same structure}
69
+
70
+ ---
71
+
72
+ ## Needs decision
73
+
74
+ {Architectural items with `needs_decision` verdict — link ADRs if applicable}
75
+
76
+ ---
77
+
78
+ ## Coverage ledger
79
+
80
+ {From the recall pass — files reviewed/skipped and active lenses that produced
81
+ no findings, each with a one-line reason. Omitted when no `coverage` object.}
82
+
83
+ ---
84
+
85
+ ## Appendix A — Rejected findings (false positives)
86
+
87
+ ### {F-00X}: {Short title}
88
+
89
+ - **Claim:** ...
90
+ - **Why rejected:** ...
91
+
92
+ ---
93
+
94
+ ## Appendix B — Dedupe pre-flight
95
+
96
+ {If smells lens ran; else omit section}
97
+
98
+ | ID | Location | Claim |
99
+ | -- | -------- | ----- |
100
+ | dup-001 | ... | ... |
101
+
102
+ ---
103
+
104
+ ## Appendix C — Method
105
+
106
+ - Phase 1: Scout pass ({N} tentative findings)
107
+ - Phase 2: Adversarial skeptic verification (severity-routed, budgeted)
108
+ - {If reverify: Re-verification against parent report {PARENT_ID}}
109
+ ```
110
+
111
+ ## JSON sidecar
112
+
113
+ Author the `.json` (the source of truth), then `review render` to (re)generate this markdown and `review export` to validate before handing off in CI contexts.
114
+
115
+ Main report body includes only `confirmed` and `downgraded` findings (initial review) or `still_open`, `partially_fixed`, `regressed` (reverify). Render places `false_positive` in Appendix A automatically.
@@ -0,0 +1,49 @@
1
+ # Severity rubric
2
+
3
+ Calibrate severity before Phase 2. Skeptics may **downgrade** with evidence; upgrade only with new evidence.
4
+
5
+ ## Critical
6
+
7
+ Must fix before merge or production. Examples:
8
+
9
+ - Exploitable auth bypass or IDOR on production path
10
+ - SQL/command injection with attacker-controlled input reaching sink
11
+ - Secret or credential committed or logged
12
+ - Data loss, corruption, or double-charge on money paths
13
+ - Broken idempotency causing duplicate financial side effects
14
+
15
+ ## Important
16
+
17
+ Should fix soon; real defect or serious debt with plausible trigger. Examples:
18
+
19
+ - Logic bug on common edge case (empty input, race under concurrency)
20
+ - Missing authorization on sensitive internal endpoint (if not ADR-accepted)
21
+ - Error responses cached by idempotency middleware
22
+ - Test gap on behaviour-critical path
23
+ - Significant duplication that must stay in sync (rule of three)
24
+
25
+ ## Minor
26
+
27
+ Nice to have; low likelihood or defense-in-depth. Examples:
28
+
29
+ - Naming inconsistency
30
+ - Missing progress indicator
31
+ - Unlikely edge case with graceful degradation
32
+ - Style nits not affecting behaviour
33
+ - Pre-existing file size (only flag growth **this change** introduced)
34
+
35
+ ## Needs decision (not a severity)
36
+
37
+ Architectural or policy trade-off — route to `NEEDS_DECISION` verdict, not Critical by default.
38
+
39
+ Examples: accepted inter-service trust model per ADR, intentional public surface, documented technical debt.
40
+
41
+ ## Project-specific downgrades
42
+
43
+ Before marking Critical/Important on themes covered by the project's accepted-risk digest, read that digest (and ADRs):
44
+
45
+ - Formally accepted trust boundaries (e.g. LAN-only HMAC)
46
+ - Documented intentional broad access patterns
47
+ - Actor/header trust models bound by an upstream session
48
+
49
+ Re-flag only if a listed re-open trigger has fired. See [accepted-risks.md](accepted-risks.md) and [examples/accepted-risks-janus.md](../examples/accepted-risks-janus.md).
@@ -0,0 +1,55 @@
1
+ # Signals pre-flight
2
+
3
+ Ground the scout in real tool output **before** reading code by hand. Tool-confirmed problems are facts, not guesses — they raise recall on the smells / contracts / tests / errors lenses and cut hallucinated findings.
4
+
5
+ ## Steps
6
+
7
+ 1. **Plan the commands.** Run the planner for the review scope:
8
+
9
+ ```bash
10
+ review signals --type branch # detect changed files vs main
11
+ review signals --type uncommitted # working tree + untracked
12
+ review signals --paths services/persona,services/mercury
13
+ review signals --json # machine-readable
14
+ ```
15
+
16
+ It maps the scope to the **workspaces that own it** and prints the exact per-workspace grounding commands (this monorepo has no root typecheck — each package owns its scripts).
17
+
18
+ 2. **Run the grounding commands** it lists, e.g.:
19
+
20
+ ```bash
21
+ npm run typecheck --workspace=your-workspace
22
+ npm run test --workspace=your-workspace
23
+ npm run lint --workspace=your-workspace
24
+ ```
25
+
26
+ Add, when available and relevant to the scope:
27
+
28
+ - `npx knip` (or the repo's dead-code script) — unused exports / dead code → **smells**
29
+ - the service's OpenAPI **route-parity** test — mounted routes vs registry → **contracts**
30
+
31
+ 3. **Convert real failures to grounded tentative findings.** A type error, failing test, lint error, or dead export becomes an `F-###` (or `dup-###`) tentative finding with `confidence: high` and the tool output as `evidence`. Do **not** invent findings the tools did not support.
32
+
33
+ 4. **Record what ran** in the report JSON `signals` object so the grounding is auditable:
34
+
35
+ ```json
36
+ "signals": {
37
+ "tools": [
38
+ { "name": "typecheck your-workspace", "status": "pass" },
39
+ { "name": "test your-workspace", "status": "fail", "summary": "1 failing: consent.test.ts" },
40
+ { "name": "knip", "status": "skipped", "summary": "not in scope" }
41
+ ]
42
+ }
43
+ ```
44
+
45
+ ## Rules
46
+
47
+ - Read-only. The pre-flight never edits code.
48
+ - Scope-bound. Run tools for the **workspaces in scope**, not the whole repo, unless the scope is repo-wide.
49
+ - A passing tool is signal too — it lets the coverage pass mark a lens genuinely exercised.
50
+ - If a tool can't run (missing script, environment), record it `skipped` with a reason rather than omitting it.
51
+
52
+ ## Notes
53
+
54
+ - The **dedupe pre-flight** (smells lens) is the same pattern with the `dedupe` skill as the tool; keep emitting `dup-###` findings and the `dedupe_preflight` summary.
55
+ - Grounded findings at `critical`/`important` still go through Phase 2 — a failing test might be an intentional WIP. Below `important`, skip the skeptic: the tool output is the proof; the orchestrator just checks for intentional-WIP signals (commit message, TODO, user context) and records the verdict directly.
@@ -0,0 +1,7 @@
1
+ # Architecture Decision Records
2
+
3
+ Canonical index of ADRs for this project. See [decisions.md]({{DECISIONS_REL}}) for the full convention (when to write, template, cross-links with OpenSpec).
4
+
5
+ | # | Title | Status | Date |
6
+ | ----- | ----- | ------ | ---- |
7
+ | <!-- add rows as ADRs are written: | NNNN | Title | Status | YYYY-MM-DD | --> |