@gobing-ai/spur 0.3.41 → 0.3.43

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 (185) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/README.md +15 -1
  3. package/config/templates/AGENTS.md +5 -3
  4. package/config/workflows/task-pipeline.yaml +113 -12
  5. package/package.json +15 -12
  6. package/plugins/README.md +655 -0
  7. package/plugins/sp/README.md +621 -0
  8. package/plugins/sp/agents/expert-spur.md +109 -0
  9. package/plugins/sp/agents/super-coder.md +126 -0
  10. package/plugins/sp/agents/super-planner.md +283 -0
  11. package/plugins/sp/agents/super-reviewer.md +154 -0
  12. package/plugins/sp/commands/dev-arch.md +30 -0
  13. package/plugins/sp/commands/dev-brainstorm.md +40 -0
  14. package/plugins/sp/commands/dev-changelog.md +28 -0
  15. package/plugins/sp/commands/dev-daily.md +29 -0
  16. package/plugins/sp/commands/dev-debug.md +29 -0
  17. package/plugins/sp/commands/dev-dogfood.md +33 -0
  18. package/plugins/sp/commands/dev-featurechange.md +130 -0
  19. package/plugins/sp/commands/dev-find-conflict.md +51 -0
  20. package/plugins/sp/commands/dev-find-issue.md +76 -0
  21. package/plugins/sp/commands/dev-find-next.md +60 -0
  22. package/plugins/sp/commands/dev-fixall.md +33 -0
  23. package/plugins/sp/commands/dev-gitmsg.md +28 -0
  24. package/plugins/sp/commands/dev-gtd.md +97 -0
  25. package/plugins/sp/commands/dev-handover.md +26 -0
  26. package/plugins/sp/commands/dev-idea.md +50 -0
  27. package/plugins/sp/commands/dev-next.md +31 -0
  28. package/plugins/sp/commands/dev-parallel.md +30 -0
  29. package/plugins/sp/commands/dev-plan.md +46 -0
  30. package/plugins/sp/commands/dev-refine.md +48 -0
  31. package/plugins/sp/commands/dev-refineall.md +65 -0
  32. package/plugins/sp/commands/dev-refresh.md +32 -0
  33. package/plugins/sp/commands/dev-reverse.md +32 -0
  34. package/plugins/sp/commands/dev-review.md +31 -0
  35. package/plugins/sp/commands/dev-run.md +63 -0
  36. package/plugins/sp/commands/dev-runall.md +83 -0
  37. package/plugins/sp/commands/dev-simplify.md +39 -0
  38. package/plugins/sp/commands/dev-unit.md +29 -0
  39. package/plugins/sp/commands/dev-verify.md +48 -0
  40. package/plugins/sp/commands/dev-verifyall.md +72 -0
  41. package/plugins/sp/commands/dev-wrap.md +48 -0
  42. package/plugins/sp/commands/dev-wrapall.md +51 -0
  43. package/plugins/sp/commands/rule-add.md +18 -0
  44. package/plugins/sp/commands/rule-refine.md +18 -0
  45. package/plugins/sp/commands/rule-scan.md +18 -0
  46. package/plugins/sp/commands/spur-init.md +22 -0
  47. package/plugins/sp/commands/workflow-add.md +18 -0
  48. package/plugins/sp/commands/workflow-refine.md +18 -0
  49. package/plugins/sp/hooks/agent-hint.ts +60 -0
  50. package/plugins/sp/hooks/careful-guard.ts +147 -0
  51. package/plugins/sp/hooks/context-post-tool.ts +325 -0
  52. package/plugins/sp/hooks/context-session-start.ts +182 -0
  53. package/plugins/sp/hooks/context-session-stop.ts +95 -0
  54. package/plugins/sp/hooks/hooks.json +51 -0
  55. package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
  56. package/plugins/sp/hooks/task-write-guard.ts +84 -0
  57. package/plugins/sp/plugin.json +8 -0
  58. package/plugins/sp/scripts/batch-preflight.ts +204 -0
  59. package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
  60. package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
  61. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
  62. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
  63. package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
  64. package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
  65. package/plugins/sp/scripts/task-size-precheck.ts +202 -0
  66. package/plugins/sp/scripts/validate-commands.ts +651 -0
  67. package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
  68. package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
  69. package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
  70. package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
  71. package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
  72. package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
  73. package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
  74. package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
  75. package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
  76. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
  77. package/plugins/sp/skills/code-implementation/SKILL.md +203 -0
  78. package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
  79. package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
  80. package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
  81. package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
  82. package/plugins/sp/skills/code-review/SKILL.md +112 -0
  83. package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
  84. package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
  85. package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
  86. package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
  87. package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
  88. package/plugins/sp/skills/code-testing/SKILL.md +108 -0
  89. package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
  90. package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
  91. package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
  92. package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
  93. package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
  94. package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
  95. package/plugins/sp/skills/code-verification/SKILL.md +535 -0
  96. package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
  97. package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
  98. package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
  99. package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
  100. package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
  101. package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
  102. package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
  103. package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
  104. package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
  105. package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
  106. package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
  107. package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
  108. package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
  109. package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
  110. package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
  111. package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
  112. package/plugins/sp/skills/functional-review/SKILL.md +364 -0
  113. package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
  114. package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
  115. package/plugins/sp/skills/issue-finding/SKILL.md +442 -0
  116. package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
  117. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
  118. package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
  119. package/plugins/sp/skills/issue-finding/references/session-formats.md +151 -0
  120. package/plugins/sp/skills/next-feature/SKILL.md +125 -0
  121. package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
  122. package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
  123. package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
  124. package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
  125. package/plugins/sp/skills/next-router/SKILL.md +181 -0
  126. package/plugins/sp/skills/next-router/references/messages.md +90 -0
  127. package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
  128. package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
  129. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +109 -0
  130. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
  131. package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
  132. package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
  133. package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
  134. package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
  135. package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
  136. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
  137. package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
  138. package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
  139. package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
  140. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
  141. package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
  142. package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
  143. package/plugins/sp/skills/spur-cli/references/features.md +234 -0
  144. package/plugins/sp/skills/spur-cli/references/init.md +119 -0
  145. package/plugins/sp/skills/spur-cli/references/message.md +98 -0
  146. package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
  147. package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
  148. package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
  149. package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
  150. package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
  151. package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
  152. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
  153. package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
  154. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
  155. package/plugins/sp/skills/spur-cli/references/tasks.md +280 -0
  156. package/plugins/sp/skills/spur-cli/references/team.md +133 -0
  157. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
  158. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
  159. package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
  160. package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
  161. package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
  162. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
  163. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +680 -0
  164. package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
  165. package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
  166. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
  167. package/plugins/sp/skills/spur-dev/references/execution-batch.md +790 -0
  168. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -0
  169. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
  170. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
  171. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
  172. package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
  173. package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
  174. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +120 -0
  175. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
  176. package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
  177. package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
  178. package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
  179. package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
  180. package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
  181. package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
  182. package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
  183. package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
  184. package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
  185. package/spur.js +6035 -4963
@@ -0,0 +1,277 @@
1
+ ---
2
+ name: comparison-protocol
3
+ description: "Four-pillar inventory, candidate graph construction, within-pillar and cross-pillar audit protocol, and token/cost controls for sp:conflict-finding."
4
+ see_also:
5
+ - conflict-finding
6
+ - spur-cli
7
+ - spur-dev
8
+ - doc-evolve
9
+ - code-verification
10
+ ---
11
+
12
+ # Comparison protocol — inventories, subject clustering, and token controls
13
+
14
+ This file is the SSOT for **Design §4 steps 4–8** of task 0486 (inventory → candidate graph →
15
+ within-pillar audit → cross-pillar audit → classify-and-challenge) and **Design §6** (token and cost
16
+ controls), satisfying Requirements **R4** (cross-pillar comparison with reproducible anchors and no
17
+ all-pairs explosion) and **R5** (honest, token-aware scan protocol with freshness-verifiable context
18
+ reuse). Authority reasoning itself lives in
19
+ [authority-resolution.md](authority-resolution.md); finding shapes and evidence rules live in
20
+ [finding-contract.md](finding-contract.md); repair routing lives in
21
+ [remediation-routing.md](remediation-routing.md). Skill entry point: [../SKILL.md](../SKILL.md).
22
+
23
+ **Governing principle:** the audit is _subject- and claim-driven_, never _text-driven_ and never
24
+ _file-vs-file_. The hard problem is deciding which artifacts are semantically related to the same
25
+ subject + claim type, then comparing only those — not computing a similarity over every pair in the
26
+ corpus.
27
+
28
+ ## Four-pillar inventory (Design §4 step 4)
29
+
30
+ Discovery materializes an **inventory** of exactly the selected pillars. Every inventory entry is a
31
+ row with six mandatory fields. An entry records **what was found and how fresh it is** — absence of
32
+ an _optional_ file is a reported fact, not an error, but a _selected_ pillar that produced no
33
+ entries is never silently dropped.
34
+
35
+ | Pillar | Identity | Path | Anchor | Provenance / freshness | Scan status |
36
+ | ----------- | ------------------------------------------------------------ | ----------------------------- | ------------------------------------ | --------------------------------------- | --------------------------------- |
37
+ | `source` | module / symbol / command / flag / DTO / schema / config key | repo-relative file | symbol, heading, line, command name | git commit/date, blame, change cone | `scanned` / `sampled` / `skipped` |
38
+ | `tasks` | WBS id, task file id | `docs/tasks3/<wbs>_<slug>.md` | WBS number, Requirement/AC heading | `git log` mtime, spur lifecycle verdict | `scanned` / `sampled` / `skipped` |
39
+ | `features` | feature id (e.g. `H11`) | feature file path | feature id, AC title, status section | git mtime, feature-tree status | `scanned` / `sampled` / `skipped` |
40
+ | `authority` | document id (e.g. `00_ADR`, `99_CONSTITUTION`) | `AGENTS.md`, `docs/0*.md` | heading, ADR entry, decision id | git mtime, last-touched commit | `scanned` / `sampled` / `skipped` |
41
+
42
+ Rules:
43
+
44
+ 1. **Optional absence is reported, not fatal.** An authority set is `AGENTS.md`,
45
+ `docs/00_ADR.md`, `docs/01_PRD.md`, `docs/03_ARCHITECTURE.md`, `docs/04_DESIGN.md`,
46
+ `docs/05_FEATURES.md`, `docs/99_PROJECT_CONSTITUTION.md` _when present_. A missing optional file
47
+ yields an inventory row with scan status `absent` and does not block the audit.
48
+ 2. **A selected pillar is never silently omitted.** If `--pillar tasks` yields no entries, that is
49
+ itself a finding (an empty/absent pillar) with an explicit inventory row — never a gap in the
50
+ report.
51
+ 3. **Anchors must be stable and real.** Unavailable line numbers are replaced by a stable
52
+ structural anchor — heading, symbol, WBS number, feature id, command name, ADR entry. Anchors are
53
+ **never fabricated**: if no anchor is verifiable, the entry records `anchor: unavailable` with an
54
+ explicit note rather than inventing one.
55
+ 4. **Freshness is provenance, not presence.** Every entry carries how the fact was obtained (git
56
+ mtime, blame, `spur … --json`, `rg` hit line) so the reader can judge whether the entry can be
57
+ reused or must be re-read.
58
+
59
+ ## Building the candidate graph (Design §4 step 5)
60
+
61
+ The candidate graph is the set of **semantically related subject pairs** to compare. It is built
62
+ from _explicit_ links and _shared identifiers_ — never from an unbounded all-pairs comparison.
63
+
64
+ Join keys, in priority order:
65
+
66
+ | Key | Source → target | Example |
67
+ | -------------------------- | ------------------------------------------------------------ | ---------------------------------------------------- |
68
+ | Explicit links | markdown links / cross-refs between artifacts | task file links a feature id; doc cites an ADR entry |
69
+ | WBS / feature ids | `0486`, `H11` | task ↔ task deps, feature tree rollup, doc scope |
70
+ | Dependencies | declared deps in task/feature | task depends-on another task |
71
+ | AC titles | acceptance-criteria titles shared between task/feature | feature AC title repeated in task AC |
72
+ | Paths | same file or dir referenced in multiple pillars | `docs/04_DESIGN.md` mentioned in task Solution |
73
+ | Symbols / commands / flags | same symbol, command, flag name | `dev-find-conflict`, `--resolve` |
74
+ | DTO / schema / config keys | same key name across config + source + docs | `--pillar`, a config field |
75
+ | Normalized domain terms | a normalized term (case/plural-insensitive) shared by claims | `authority`, `freshness`, `coverage` |
76
+
77
+ Construction protocol:
78
+
79
+ 1. **Seed from scope.** If `<scope>` is a path/WBS/feature-id/symbol/command/config-key, seed the
80
+ graph with every artifact whose identity or content references that scope.
81
+ 2. **Grow by shared keys.** For each seed, add an edge to any artifact sharing one of the keys
82
+ above for the _same subject_. A key matches only when it refers to the same subject, not merely
83
+ the same string in an unrelated context (see normalize).
84
+ 3. **Normalize before matching.** Domain terms are matched after lowercasing and plural/case
85
+ folding (e.g. `AC`/`ac`, `WBS`/`wbs`); identifiers (`0486`, `H11`) and paths are matched
86
+ verbatim. Do not fuzzy-match identifiers.
87
+ 4. **Bound the graph.** The graph is the union of seed-reachable edges. Artifacts that share no key
88
+ and are not seed-reachable are excluded. **An unbounded all-pairs comparison is explicitly
89
+ forbidden** — if a scope would touch every artifact, that is a _coverage_ concern, not license to
90
+ compare everything.
91
+ 5. **Record edge provenance.** Each edge records which key(s) joined it so the candidate set is
92
+ reproducible (a reviewer can rerun the join and get the same pairs).
93
+
94
+ ## Within-pillar audit (Design §4 step 6)
95
+
96
+ For each pillar, compare only claims that share a subject within the pillar.
97
+
98
+ ### Source code (`--pillar source`)
99
+
100
+ | Claim cluster | Compare | Conflict types |
101
+ | --------------------------- | --------------------------------------------------------------- | -------------------- |
102
+ | contracts / implementations | exported signature vs body; interface vs impl | contradiction, stale |
103
+ | tests | test expectation vs implementation | contradiction, stale |
104
+ | config / registrations | config key vs parser; registered command/flag vs parsed surface | omission, orphan |
105
+ | symbols / commands | command wrapper vs its delegation target | stale, duplicate |
106
+
107
+ ### Task files (`--pillar tasks`)
108
+
109
+ | Claim cluster | Compare |
110
+ | ----------------- | ----------------------------------------------------------------------------- |
111
+ | requirements / AC | Requirement vs AC text; AC title vs body |
112
+ | dependencies | declared dependency vs referenced WBS existing |
113
+ | status / solution | `status` field vs what Solution/Testing describe; lifecycle verdict vs status |
114
+ | orphans | task whose parent feature is gone, or WBS referenced nowhere |
115
+
116
+ ### Feature files (`--pillar features`)
117
+
118
+ | Claim cluster | Compare |
119
+ | ------------- | ------------------------------------------------------------- |
120
+ | hierarchy | child feature id vs parent references |
121
+ | AC / status | AC titles vs status section; index projection vs actual files |
122
+ | orphans | feature referenced by no task and no doc |
123
+
124
+ ### Authority files (`--pillar authority`)
125
+
126
+ | Claim cluster | Compare |
127
+ | ---------------- | -------------------------------------------- |
128
+ | ownership | who owns a subject vs who is referenced |
129
+ | decision / scope | ADR decision vs its scope statement |
130
+ | process | process rule vs referenced workflow/template |
131
+
132
+ Within-pillar finding rules: a claim must have **at least two opposing anchors** for
133
+ contradiction/stale. Low-confidence differences become candidates, never definitive conflicts (see
134
+ [finding-contract.md](finding-contract.md)).
135
+
136
+ ## Cross-pillar audit (Design §4 step 7)
137
+
138
+ Audit every boundary applicable to the selected scope. Default scope (`all`) audits all six:
139
+
140
+ | Boundary | What is compared | Typical conflict |
141
+ | ------------------- | ------------------------------------------- | ----------------------------------------------- |
142
+ | source ↔ task | task AC/requirements vs implemented surface | stale projection (code shipped, task says todo) |
143
+ | source ↔ feature | feature AC vs shipped surface | feature AC unmet or over-shipped |
144
+ | source ↔ authority | authority "should" vs source "is" | architecture/design doc vs module topology |
145
+ | task ↔ feature | task AC/deps vs feature AC/status | AC mismatch, orphan task |
146
+ | task ↔ authority | task obligation vs PRD/ADR scope | task outside documented scope |
147
+ | feature ↔ authority | feature goal vs PRD/ADR bounds | feature contradicts PRD non-goal |
148
+
149
+ Per-boundary protocol:
150
+
151
+ 1. Restrict to candidate-graph edges that cross the two pillars.
152
+ 2. For each edge, resolve the **normative authority** and **observed reality** for the _subject +
153
+ claim type_ (authority matrix: [authority-resolution.md](authority-resolution.md)).
154
+ 3. Compare only **comparable** claims. Incomparable, missing, or ambiguous authority yields an
155
+ unresolved `needs-authority-decision` item — never a forced winner.
156
+ 4. Emit reproducible anchors from **both** sides (at least two opposing anchors for
157
+ contradiction/stale).
158
+
159
+ ## Classify and challenge (Design §4 step 8)
160
+
161
+ Before asserting any candidate as a conflict, run the **four-challenge filter**. A candidate that
162
+ survives all applicable challenges is a real finding; one explained by any challenge is not a
163
+ conflict (or is a _different_ conflict type).
164
+
165
+ | Challenge | Question | If true |
166
+ | ----------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------- |
167
+ | Lifecycle | Is the difference planned work (todo task/feature whose lifecycle says not-yet-done)? | Not a conflict — planned work |
168
+ | Supersession | Is one artifact superseded (accepted ADR beats derived doc; superseded ADR is historical)? | Not a conflict — supersession |
169
+ | Abstraction-level | Is the difference merely a different level of abstraction (design doc generalizes, code specializes)? | Not a conflict |
170
+ | Intentional deprecation | Is one side explicitly marked deprecated / intentionally divergent? | Not a conflict — intentional |
171
+
172
+ Rules:
173
+
174
+ 1. **Mere wording or abstraction-level difference is NOT a conflict.** Only
175
+ `contradiction`, `stale`, `duplicate`, `omission`, `orphan`, or `ambiguous-authority` supported by
176
+ evidence counts.
177
+ 2. **A todo task/feature differing from current code is planned work**, not stale code, unless its
178
+ lifecycle or supersession metadata says otherwise.
179
+ 3. **Challenge before classify, then classify exactly.** Run the challenges first; only survivors
180
+ get a conflict type and severity/confidence.
181
+ 4. **Never promote.** A low-confidence candidate stays a candidate or unresolved item; it is never
182
+ promoted to a definitive conflict (see [finding-contract.md](finding-contract.md)).
183
+ 5. **Every asserted finding names the challenge that failed** in its false-positive check, so the
184
+ reader sees why lifecycle/supersession/abstraction/deprecation did not excuse it.
185
+
186
+ ## Token and cost controls (Design §6)
187
+
188
+ The audit is **token-aware**: it reads the minimum to be honest, and it reports what it did not
189
+ read. It never claims comprehensiveness it cannot defend.
190
+
191
+ ### Read order (cheap first)
192
+
193
+ 1. **Authority rules and indexes first.** Read `AGENTS.md`, `docs/99_PROJECT_CONSTITUTION.md`, and
194
+ any reusable index (`.spur/context/anatomy.md`, task/feature metadata) before any full artifact.
195
+ These establish the claim-specific authority matrix and the candidate seed set without opening
196
+ bodies.
197
+ 2. **Deterministic discovery, batched.** Batch `git`, `rg`, `spur task/feature … --json`, relevant
198
+ `spur … check`, and `sp:doc-evolve` audit surfaces into as few calls as possible. Retain results
199
+ in a compact **in-memory evidence manifest** for the run — never persist it.
200
+
201
+ > **`rg` skips dot-directories and ignored paths by default.** A bare `rg <pattern> .` will not
202
+ > search `.spur/context/`, `.github/`, or anything matched by `.gitignore`, and returns **no
203
+ > hits** rather than an error — a silent false negative that reads exactly like a clean boundary.
204
+ > When the scan must cover indexed context, dotted config, or ignored trees, use `rg -uu`
205
+ > (or `--hidden --no-ignore`) and say which you used. A "no conflicts found" result produced by a
206
+ > default-scoped `rg` over a dotted path is not evidence of absence, and must not be reported as
207
+ > a cleared boundary.
208
+
209
+ 3. **Open full artifacts only for candidate subjects.** A file is read in full only when it is a
210
+ seed or a candidate-graph subject that survived the classify-challenge filter (or when coverage
211
+ demands it). Non-candidates are inventoried by metadata, not read.
212
+
213
+ ### Adaptive vs full mode
214
+
215
+ | Mode | Behavior | Coverage guarantee |
216
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
217
+ | `adaptive` (default) | Always scan the complete authority/task/feature metadata surfaces needed for traceability; narrow source reads to the Git change cone and linked symbols. Reuse `.spur/context/` **only** when freshness + provenance are verifiable against the current tree. | Disclosed change cone + skipped areas; `complete` only when defensible |
218
+ | `full` | Cold comprehensive scan; no reuse of indexed context; read every selected-pillar artifact needed to establish completeness. | Intended `complete: true` unless a tool fails |
219
+
220
+ Adaptive reuse decision:
221
+
222
+ 1. **Verify provenance.** The `.spur/context/` artifact must state its source tree (paths, commit,
223
+ or mtime) and that source must match the current tree.
224
+ 2. **Verify freshness.** Compare the artifact's recorded freshness against current git state. If any
225
+ authority/task/feature metadata it relies on is newer, the reused index is **stale**.
226
+ 3. **Verify the change cone.** In adaptive mode, always scan the full authority/task/feature
227
+ metadata surfaces; only _source_ reads are narrowed to the change cone. If the cone is empty or
228
+ unverifiable, escalate to the full source scan.
229
+ 4. **Degrade honestly.** Absent, stale, or unverifiable context → **cold full scan** **or** an
230
+ **explicit incomplete-coverage result**. Never silent omission. When links are missing, context
231
+ is stale, or coverage cannot be defended, escalate to the full scan.
232
+
233
+ ### Reporting cost and coverage
234
+
235
+ The report (Markdown and `--json`) records:
236
+
237
+ - **Files inspected / skipped** per pillar, with skip reasons.
238
+ - **Claims inspected / skipped** (candidate edges examined vs left unexamined).
239
+ - **Tokens** (estimated) consumed by reads.
240
+ - **Change cone** (in adaptive mode): which paths were narrowed.
241
+ - **Reused context**: which `.spur/context/` artifact, and the provenance/freshness evidence.
242
+ - **`coverage.complete`**: `true` only when every selected pillar was scanned without a tool failure
243
+ that prevented coverage.
244
+
245
+ Rules:
246
+
247
+ 1. **Do not claim "comprehensive" when `coverage.complete` is false.** If a tool failed, coverage is
248
+ degraded and reported in `errors` (tool failure is distinct from semantic uncertainty).
249
+ 2. **Tool failures are coverage evidence, not silence.** A failing `git`/`rg`/`spur` call is
250
+ recorded; the affected pillar's scan status is `skipped` with the reason, and `coverage.complete`
251
+ reflects it.
252
+ 3. **No hidden state.** Adaptive reuse is a read of an existing `.spur/context/` artifact; the audit
253
+ itself creates no persistent cache, database, vector index, embedding pipeline, background
254
+ daemon, or custom parser in v1. The in-memory evidence manifest dies with the run.
255
+
256
+ ## Anti-patterns and boundaries
257
+
258
+ | Anti-pattern | Correct behavior |
259
+ | --------------------------------------------------------- | --------------------------------------------------------------- |
260
+ | Unbounded all-pairs comparison | Compare only candidate-graph edges joined by explicit keys |
261
+ | Asserting conflict from wording alone | Run the four-challenge filter; only evidence-backed types count |
262
+ | Forcing ambiguous authority through a global ranking | Emit unresolved `needs-authority-decision` HITL item |
263
+ | Silently omitting a selected pillar or a tool failure | Record scan status `absent`/`skipped` and degrade coverage |
264
+ | Claiming "comprehensive" with `coverage.complete=false` | Report incomplete coverage explicitly |
265
+ | Reusing any context without freshness/provenance check | Verify provenance+freshness against the current tree or degrade |
266
+ | Reading full artifacts for non-candidates | Open full files only for candidates / coverage demands |
267
+ | Fabricating a line-number anchor | Use a stable structural anchor or `anchor: unavailable` |
268
+ | Creating persistent cache / index / daemon / parser in v1 | Keep the in-memory evidence manifest run-local only |
269
+
270
+ ## Related
271
+
272
+ - Skill entry: [../SKILL.md](../SKILL.md)
273
+ - Authority matrix and ambiguity protocol: [authority-resolution.md](authority-resolution.md)
274
+ - Finding schema, severity, confidence, coverage: [finding-contract.md](finding-contract.md)
275
+ - Confirmed repair routing and freshness recheck: [remediation-routing.md](remediation-routing.md)
276
+ - Deterministic discovery: `spur task … --json`, `spur feature … --json`, `sp:spur-cli`,
277
+ `sp:spur-dev`, `sp:doc-evolve`, `sp:code-verification`
@@ -0,0 +1,346 @@
1
+ ---
2
+ name: finding-contract
3
+ description: "Finding classifications, evidence rules, severity/confidence semantics, and the stable Markdown/JSON result envelope for sp:conflict-finding."
4
+ see_also:
5
+ - conflict-finding
6
+ - authority-resolution
7
+ - comparison-protocol
8
+ - remediation-routing
9
+ ---
10
+
11
+ # Finding and result contracts
12
+
13
+ `sp:conflict-finding` reports every asserted conflict as a **finding** carrying a fixed field
14
+ envelope, and packages the whole audit run into a **result** with a fixed top-level shape. This
15
+ file is the SSOT for both: what a finding may say, what evidence must back it, how severity and
16
+ confidence are graded, and how Markdown and `--json` stay the same information in two renderings.
17
+
18
+ Two rules bind everything below:
19
+
20
+ 1. **A conflict is a claim about claims, not about text.** Only `contradiction`, `stale`,
21
+ `duplicate`, `omission`, `orphan`, or `ambiguous-authority` supported by reproducible evidence
22
+ count. Wording or abstraction-level differences are never asserted as conflicts (R2).
23
+ 2. **The envelope is stable, the reasoning is not.** `--json` stabilizes the evidence envelope so
24
+ results can be inspected or composed; it never implies deterministic semantic reasoning.
25
+
26
+ ## 1. Finding classifications
27
+
28
+ ### `conflict_type`
29
+
30
+ Exactly one of six values. The value states _what kind of disagreement_ the evidence establishes —
31
+ not what the auditor suspects, and never merely what text differs.
32
+
33
+ | `conflict_type` | Meaning | Minimum evidence posture |
34
+ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
35
+ | `contradiction` | Two live claims about the same subject + claim type assert incompatible facts and neither is superseded. | ≥ 2 opposing anchors, both current |
36
+ | `stale` | A projection (derived doc, feature/task status, doc surface) describes a state that its authority or observed reality has moved past. | ≥ 2 opposing anchors (current authority/observation vs. the stale projection) |
37
+ | `duplicate` | The same claim is stated in ≥ 2 places as if independent, risking drift and split edits. | ≥ 2 anchors for the same subject+claim |
38
+ | `omission` | A required claim is absent where the authority or an explicit link implies it must exist. | 1 anchor proving the obligation + 1 anchor showing the gap |
39
+ | `orphan` | A claim references a subject, symbol, WBS, feature ID, or command that no longer exists or is no longer reachable. | 1 anchor for the dangling reference + 1 anchor showing the target is gone |
40
+ | `ambiguous-authority` | Two or more authorities claim the same subject+claim but are incomparable (or authority is missing), so no precedence edge can be drawn. | ≥ 2 candidate authorities, none provably dominant |
41
+
42
+ Rules:
43
+
44
+ - A `contradiction` between a normative source and observed reality is recorded as _both_ sides —
45
+ the precedence reason names which side is normative and which is observed, without deleting the
46
+ observed one (see [./authority-resolution.md](authority-resolution.md)).
47
+ - A `stale` finding never mutates the source of truth; it names which projection lags and which
48
+ artifact is authoritative.
49
+ - When classification is uncertain, default to `ambiguous-authority` (an unresolved HITL item) or
50
+ to a low-confidence candidate — never to a definitive `contradiction` you cannot defend.
51
+
52
+ ### `status`
53
+
54
+ Exactly one of six lifecycle states. It tracks where the finding sits between discovery and
55
+ resolution, and it is what the remediation workflow reads to decide the next action.
56
+
57
+ | `status` | Meaning | Who advances it |
58
+ | -------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------- |
59
+ | `open` | Reported with evidence; no decision or repair yet. | default after audit |
60
+ | `needs-authority-decision` | Authority is incomparable/missing; requires a human decision before any repair is proposed as settled. | audit, when authority ambiguity is unresolved |
61
+ | `confirmed` | Evidence revalidated (freshness recheck) and the finding is accepted as real. | confirmation gate |
62
+ | `repairing` | A repair is in flight through the owner surface. | remediation routing |
63
+ | `resolved` | Repair applied, or the artifacts now match (idempotent), and freshness revalidated. | remediation completion |
64
+ | `failed` | A repair attempt failed or hit ambiguous authority mid-repair and was not silently rolled forward. | remediation failure |
65
+
66
+ Transition rules:
67
+
68
+ - `open` → `needs-authority-decision` happens during audit when no precedence edge can be drawn.
69
+ - `open`/`needs-authority-decision` → `confirmed` only through the explicit confirmation step in
70
+ `--resolve` mode after a freshness recheck.
71
+ - A `failed` finding may be re-audited (back to `open`) but is never silently reported as
72
+ `resolved`.
73
+
74
+ ## 2. Required finding fields
75
+
76
+ Every finding carries all of these fields, in **both** Markdown and JSON. The field set is fixed;
77
+ absent information is represented by an explicit sentinel (`null`, `"unknown"`, or `[]`), never by
78
+ dropping the key.
79
+
80
+ | Field | Type | Content |
81
+ | ---------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
82
+ | `id` | string | Stable identifier for this finding in this run, e.g. `F-0001`. Used to key remediation and stale-evidence checks. |
83
+ | `subject` | string | The shared identity the conflicting claims are about (path, WBS, feature ID, symbol, command, config key, or normalized domain term). |
84
+ | `claim_type` | string | The claim dimension being judged (process, structural-decision, product-scope, feature-ac, task-obligation, architecture-mechanism, command/api/schema-surface, implementation-behavior). |
85
+ | `conflict_type` | string | One of the six values in §1. |
86
+ | `pillars` | string[] | The pillar(s) involved, from `source`, `tasks`, `features`, `authority`. |
87
+ | `artifacts` | string[] | Repo-relative paths of every artifact participating in the conflict. |
88
+ | `normative_authority` | string \| null | The artifact/rule that defines what _should_ be true for this subject+claim, if resolvable. |
89
+ | `observed_reality` | string \| null | What currently _is_ true (runtime behavior, code topology, gate output), if observable. |
90
+ | `precedence_reason` | string | The project rule or documented fallback that justifies the authority edge — or an explicit statement that none exists (for `ambiguous-authority`). |
91
+ | `evidence` | array | Reproducible evidence items per §3. |
92
+ | `freshness` | object | Per-anchor staleness: `{ revalidated: bool, rechecked_at: ISO8601\|null, anchors_stale: string[] }`. |
93
+ | `severity` | string | Impact grade: `critical` \| `high` \| `medium` \| `low` (§4). |
94
+ | `confidence` | string | Evidence-strength grade: `high` \| `medium` \| `low` (§4). |
95
+ | `false_positive_check` | string | The explicit reasoning that rules out lifecycle, supersession, abstraction-level, and intentional-deprecation explanations before asserting conflict (R2). |
96
+ | `proposed_repair` | string \| null | The minimal repair that would reconcile the claims, when one can be proposed without forcing ambiguous authority. |
97
+ | `repair_owner` | string \| null | The artifact owner / route responsible for the repair (`spur task/feature`, `sp:doc-evolve`, source lifecycle, command/skill superskill). |
98
+ | `status` | string | One of the six values in §1. |
99
+
100
+ ### The `false_positive_check` is mandatory
101
+
102
+ Every finding must show its work against the four challenge classes (R2). The check is a short
103
+ statement, not a placeholder:
104
+
105
+ | Challenge | Ask | If it explains the difference |
106
+ | ----------------------- | -------------------------------------------------------------------------------------- | ----------------------------- |
107
+ | Lifecycle | Is one claim planned/future work rather than a present contradiction? | Not a conflict |
108
+ | Supersession | Is the older artifact superseded/historical? | Not a current conflict |
109
+ | Abstraction level | Are the claims at different intended levels (design intent vs. implementation detail)? | Not a conflict |
110
+ | Intentional deprecation | Is the divergence deliberate and documented? | Not a conflict |
111
+
112
+ A finding with an empty or hand-wavy `false_positive_check` must be demoted to low-confidence
113
+ candidate or dropped — it has not met the bar for a definitive conflict.
114
+
115
+ ## 3. Evidence rules
116
+
117
+ Each item in `evidence` is a reproducible, self-contained anchor. The same shape appears in
118
+ Markdown (as a bulleted evidence block) and JSON (as an object in the `evidence` array).
119
+
120
+ ```json
121
+ {
122
+ "path": "docs/04_DESIGN.md",
123
+ "anchor": { "kind": "line", "value": 141 },
124
+ "claim_paraphrase": "DESIGN says the flag default is --mode adaptive",
125
+ "provenance": { "source": "git blame", "freshness": "2026-08-08" },
126
+ "reproduced_by": "rg '--mode' docs/04_DESIGN.md; read docs/04_DESIGN.md:141"
127
+ }
128
+ ```
129
+
130
+ ### Anchor kinds
131
+
132
+ `anchor.kind` is one of a fixed set — never a bare, unverifiable line number.
133
+
134
+ | `kind` | `value` example | When to use |
135
+ | --------- | ------------------------------ | ---------------------------------------------------------------------- |
136
+ | `line` | `141` | A specific line, when a stable line number exists in the current tree. |
137
+ | `heading` | `## Design` | A section that can move line numbers across edits. |
138
+ | `symbol` | `findconflict` | A function/type/command/flag/config-key name. |
139
+ | `wbs` | `0486` | A task WBS identifier. |
140
+ | `feature` | `H11` | A feature ID. |
141
+ | `command` | `/sp:dev-find-conflict --json` | A command or flag invocation / contract. |
142
+
143
+ ### Mandatory rules
144
+
145
+ 1. **Repo-relative path.** `path` is always relative to the repository root; never an absolute
146
+ path, never an invented location.
147
+ 2. **Claim paraphrase.** Every anchor restates the claim it supports in the auditor's own words so
148
+ the reader need not re-open the artifact to know what was asserted.
149
+ 3. **Provenance and freshness.** Record where the value came from (`git`, `rg`, `spur task --json`,
150
+ `sp:doc-evolve` audit, direct read) and when it was observed, so revalidation can detect drift.
151
+ 4. **Reproduction step.** `reproduced_by` names the exact command or reasoning step that produced
152
+ the anchor, so a fresh session can re-run it.
153
+ 5. **Two opposing anchors for `contradiction`/`stale`.** These conflict types are not asserted on a
154
+ single artifact: `evidence` must contain at least two anchors on opposite sides, each with its
155
+ own path/paraphrase/reproduction.
156
+ 6. **Never fabricate line numbers.** If a line number is unavailable or unstable, use a stable
157
+ structural anchor (`heading`, `symbol`, `wbs`, `feature`, `command`). A made-up line number is a
158
+ hard violation; prefer a structural anchor and note `line` as `null`.
159
+ 7. **Opposing anchors must be current.** For `contradiction`, both sides must be live; a superseded
160
+ or historical anchor is not opposition. For `stale`, the current authority/observation is one
161
+ side and the lagging projection the other.
162
+
163
+ ### Unavailable anchors
164
+
165
+ When a claim cannot be pinned to a stable anchor, record the best structural anchor and set
166
+ `confidence` accordingly — never fabricate, never silently drop the evidence item. An evidence item
167
+ with no reproducible anchor cannot support a `contradiction`/`stale` finding.
168
+
169
+ ## 4. Severity and confidence
170
+
171
+ Severity and confidence answer two different questions and must never be conflated:
172
+
173
+ - **`severity`** = impact _if the conflict is real_ (blast radius, wrongness, cost of not fixing).
174
+ - **`confidence`** = strength of the evidence that the conflict _is real_.
175
+
176
+ ### Severity — impact-based
177
+
178
+ | `severity` | Meaning |
179
+ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
180
+ | `critical` | The conflict misdirects or corrupts a load-bearing decision/contract: e.g. an AC that contradicts shipped behavior of a core command, or an ADR superseded while derived docs still assert it as current. |
181
+ | `high` | A materially wrong projection that likely causes incorrect work (stale task status, feature AC drift, surface doc contradicting a schema). |
182
+ | `medium` | A real but bounded divergence; correctable with local, confirmed repair. |
183
+ | `low` | A cosmetic or low-blast-radius inconsistency; tracked but not urgent. |
184
+
185
+ Severity is judged from impact, _not_ from how easy the conflict was to spot. A `critical` finding
186
+ with weak evidence still reports `severity: critical` but `confidence: low` (see below).
187
+
188
+ ### Confidence — evidence strength
189
+
190
+ | `confidence` | Meaning |
191
+ | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
192
+ | `high` | ≥ 2 reproducible, current, opposing anchors; precedence edge is explicit and challenge-free. |
193
+ | `medium` | Reproducible anchor(s) present, but one side is weaker (stale provenance, single indirect anchor, or a non-trivial inference). |
194
+ | `low` | A plausible candidate supported by partial/indirect evidence; could not be fully defended. |
195
+
196
+ ### Low confidence never disappears
197
+
198
+ A low-confidence candidate is **never promoted to a definitive conflict**, and it is **never
199
+ dropped**:
200
+
201
+ - It is reported with `confidence: low` and `status: open` (or `needs-authority-decision`), placed
202
+ after higher-confidence findings in the report.
203
+ - It is NOT given `status: confirmed` and is NOT routed for repair in `--resolve` mode without
204
+ human revalidation.
205
+ - The report lists it under **candidates / unresolved**, distinct from confirmed findings, so
206
+ nothing is silently lost.
207
+
208
+ ## 5. Top-level result envelope
209
+
210
+ The whole run is a single result object. Top-level keys are fixed:
211
+
212
+ ```text
213
+ schema_version, command, scope, mode, pillars, authority_map,
214
+ inventory, findings, unresolved, coverage, cost, remediation, errors
215
+ ```
216
+
217
+ ```json
218
+ {
219
+ "schema_version": 1,
220
+ "command": "dev-find-conflict",
221
+ "scope": "docs/00_ADR.md",
222
+ "mode": "adaptive",
223
+ "pillars": ["authority"],
224
+ "authority_map": {},
225
+ "inventory": [],
226
+ "findings": [],
227
+ "unresolved": [],
228
+ "coverage": { "complete": true },
229
+ "cost": {},
230
+ "remediation": {},
231
+ "errors": []
232
+ }
233
+ ```
234
+
235
+ | Key | Content |
236
+ | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
237
+ | `schema_version` | integer, `1`. The envelope contract version — not a semantic-reasoning version. |
238
+ | `command` | string, `dev-find-conflict`. |
239
+ | `scope` | string. The resolved audit scope (path, WBS, feature ID, symbol, command, or `"<project>"`). |
240
+ | `mode` | string, `adaptive` \| `full`. |
241
+ | `pillars` | string[]. The pillars actually audited (subset of `source`, `tasks`, `features`, `authority`). |
242
+ | `authority_map` | object. Claim-type → authoritative artifact/rule, with each precedence edge citing its project rule or fallback (see [./authority-resolution.md](authority-resolution.md)). |
243
+ | `inventory` | array. Four-pillar inventory entries: `{ pillar, identity, path, anchor, freshness, scan_status }`. |
244
+ | `findings` | array. Confirmed findings with the fixed field set of §2. |
245
+ | `unresolved` | array. Ambiguous-authority and low-confidence candidates awaiting a human decision; never empty-hiding real uncertainty. |
246
+ | `coverage` | object. Intended/discovered/scanned/skipped per pillar, skipped reasons, reused context, change cone, `complete: boolean` (§6). |
247
+ | `cost` | object. Estimated files/claims/tokens inspected vs. skipped; never claims "comprehensive" when `coverage.complete` is false (§6). |
248
+ | `remediation` | object. The confirmed/declined repair set keyed by finding ID + evidence fingerprint, with per-item outcome (see [./remediation-routing.md](remediation-routing.md)). |
249
+ | `errors` | array. Distinctly typed failures — see below. |
250
+
251
+ ### `errors` — tool failure vs. semantic uncertainty
252
+
253
+ `errors` distinguishes two failure classes so a consumer never mistakes a broken tool for a
254
+ genuinely ambiguous claim:
255
+
256
+ | Error type | Meaning | Example |
257
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
258
+ | `tool_failure` | A deterministic step (git, rg, `spur task --json`, check) failed or was unavailable. Recorded as coverage evidence; degrades `coverage.complete`. |
259
+ | `semantic_uncertainty` | The model could not defensibly classify/comparify a subject+claim. Recorded as an unresolved candidate, never forced to a definitive conflict. |
260
+
261
+ Both types carry `{ kind, subject, message }`. A `tool_failure` never becomes a finding; a
262
+ `semantic_uncertainty` never becomes a confirmed conflict.
263
+
264
+ ### `coverage` — honesty contract
265
+
266
+ ```json
267
+ {
268
+ "complete": false,
269
+ "pillars": {
270
+ "source": {
271
+ "intended": 120,
272
+ "discovered": 120,
273
+ "scanned": 80,
274
+ "skipped": 40,
275
+ "skipped_reasons": ["stale_context", "unlinked_symbols"]
276
+ },
277
+ "tasks": {
278
+ "intended": 60,
279
+ "discovered": 60,
280
+ "scanned": 60,
281
+ "skipped": 0,
282
+ "skipped_reasons": []
283
+ }
284
+ },
285
+ "reused_context": [".spur/context/anatomy.md"],
286
+ "change_cone": "git diff main..HEAD -- src/",
287
+ "complete": false
288
+ }
289
+ ```
290
+
291
+ - `complete: true` is claimed **only** when every intended pillar entry was scanned and every
292
+ tool step succeeded.
293
+ - Adaptive mode must disclose `skipped` and `skipped_reasons` (stale context, unverifiable
294
+ provenance, unlinked symbols) and, when reuse is used, the `reused_context` paths plus the
295
+ `change_cone` it relied on.
296
+ - Absent/stale/unverifiable context degrades to a cold full scan **or** an explicit
297
+ `complete: false` result — never a silent reduced-coverage claim.
298
+
299
+ ### Markdown carries the same information
300
+
301
+ The Markdown report is the same envelope rendered as readable sections, with no information loss:
302
+
303
+ - A **Coverage** section mirrors `coverage` (per-pillar scanned/skipped + reasons, reused context,
304
+ change cone, completeness statement).
305
+ - A **Findings** section lists every finding with all fields of §2; ordering by `severity` then
306
+ `confidence`.
307
+ - An **Unresolved / candidates** section mirrors `unresolved`, including low-confidence candidates
308
+ and ambiguous authority.
309
+ - An **Errors** section distinguishes `tool_failure` from `semantic_uncertainty`.
310
+ - An **Authority** section mirrors `authority_map` with each precedence edge's rule citation.
311
+ - **Cost** is reported plainly and never overstated when coverage is incomplete.
312
+
313
+ ## 6. Stable JSON vs. non-deterministic reasoning
314
+
315
+ `--json` emits the same envelope as Markdown, but stability is scoped deliberately:
316
+
317
+ - **Stable:** the _evidence envelope_ — schema_version, field names and shapes, evidence anchor
318
+ kinds, classification vocabulary (`conflict_type`, `status`), coverage accounting, error typing.
319
+ - **Not stable / never implied deterministic:** the _semantic reasoning_ — which candidates were
320
+ generated, how subject clustering was done, which comparisons were drawn, and the prose
321
+ justifications. Two runs over the same tree may name different candidates; that is expected and
322
+ must not be presented as a classifier regression.
323
+
324
+ Consumers (tests, automation, downstream tools) may rely on the envelope contract and on
325
+ reproducible anchors; they must not rely on candidate-set identity or on any claim of
326
+ deterministic semantic output. This is why `schema_version` is an envelope version only.
327
+
328
+ ## 7. Cross-cutting rules (R2)
329
+
330
+ - Only the six `conflict_type` values are asserted; everything else is a candidate or unresolved.
331
+ - Every finding names the subject, claim type, artifacts, authority path, and reproducible
332
+ anchors (R4).
333
+ - A selected pillar is never silently omitted; absence of an optional authority file is reported
334
+ but does not block the audit (R1).
335
+ - No unbounded all-pairs comparison; candidates come only from the explicit-link candidate graph
336
+ (see [./comparison-protocol.md](comparison-protocol.md)).
337
+ - Audit mode produces findings only; mutation requires `--resolve` + confirmation + freshness
338
+ recheck, routed by owner (see [./remediation-routing.md](remediation-routing.md)).
339
+
340
+ ## Related
341
+
342
+ - Skill entry: [../SKILL.md](../SKILL.md)
343
+ - Authority matrix + fallback: [./authority-resolution.md](authority-resolution.md)
344
+ - Candidate graph + comparison protocol: [./comparison-protocol.md](comparison-protocol.md)
345
+ - Confirmed remediation routing: [./remediation-routing.md](remediation-routing.md)
346
+ - Verification of findings against requirements: `sp:code-verification`