@gobing-ai/spur 0.3.40 → 0.3.42
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/.claude-plugin/marketplace.json +15 -0
- package/README.md +15 -1
- package/config/templates/AGENTS.md +5 -3
- package/config/workflows/task-pipeline.yaml +103 -12
- package/package.json +15 -12
- package/plugins/README.md +655 -0
- package/plugins/sp/README.md +621 -0
- package/plugins/sp/agents/expert-spur.md +109 -0
- package/plugins/sp/agents/super-coder.md +126 -0
- package/plugins/sp/agents/super-planner.md +283 -0
- package/plugins/sp/agents/super-reviewer.md +154 -0
- package/plugins/sp/commands/dev-arch.md +30 -0
- package/plugins/sp/commands/dev-brainstorm.md +40 -0
- package/plugins/sp/commands/dev-changelog.md +28 -0
- package/plugins/sp/commands/dev-daily.md +29 -0
- package/plugins/sp/commands/dev-debug.md +29 -0
- package/plugins/sp/commands/dev-dogfood.md +33 -0
- package/plugins/sp/commands/dev-featurechange.md +130 -0
- package/plugins/sp/commands/dev-find-conflict.md +51 -0
- package/plugins/sp/commands/dev-find-issue.md +76 -0
- package/plugins/sp/commands/dev-find-next.md +60 -0
- package/plugins/sp/commands/dev-fixall.md +33 -0
- package/plugins/sp/commands/dev-gitmsg.md +28 -0
- package/plugins/sp/commands/dev-gtd.md +97 -0
- package/plugins/sp/commands/dev-handover.md +26 -0
- package/plugins/sp/commands/dev-idea.md +50 -0
- package/plugins/sp/commands/dev-next.md +31 -0
- package/plugins/sp/commands/dev-parallel.md +30 -0
- package/plugins/sp/commands/dev-plan.md +46 -0
- package/plugins/sp/commands/dev-refine.md +48 -0
- package/plugins/sp/commands/dev-refineall.md +65 -0
- package/plugins/sp/commands/dev-refresh.md +32 -0
- package/plugins/sp/commands/dev-reverse.md +32 -0
- package/plugins/sp/commands/dev-review.md +31 -0
- package/plugins/sp/commands/dev-run.md +63 -0
- package/plugins/sp/commands/dev-runall.md +80 -0
- package/plugins/sp/commands/dev-simplify.md +39 -0
- package/plugins/sp/commands/dev-unit.md +29 -0
- package/plugins/sp/commands/dev-verify.md +48 -0
- package/plugins/sp/commands/dev-verifyall.md +72 -0
- package/plugins/sp/commands/dev-wrap.md +30 -0
- package/plugins/sp/commands/dev-wrapall.md +33 -0
- package/plugins/sp/commands/rule-add.md +18 -0
- package/plugins/sp/commands/rule-refine.md +18 -0
- package/plugins/sp/commands/rule-scan.md +18 -0
- package/plugins/sp/commands/spur-init.md +22 -0
- package/plugins/sp/commands/workflow-add.md +18 -0
- package/plugins/sp/commands/workflow-refine.md +18 -0
- package/plugins/sp/hooks/agent-hint.ts +60 -0
- package/plugins/sp/hooks/careful-guard.ts +147 -0
- package/plugins/sp/hooks/context-post-tool.ts +325 -0
- package/plugins/sp/hooks/context-session-start.ts +182 -0
- package/plugins/sp/hooks/context-session-stop.ts +95 -0
- package/plugins/sp/hooks/hooks.json +51 -0
- package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
- package/plugins/sp/hooks/task-write-guard.ts +84 -0
- package/plugins/sp/plugin.json +8 -0
- package/plugins/sp/scripts/batch-preflight.ts +204 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
- package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
- package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
- package/plugins/sp/scripts/task-size-precheck.ts +202 -0
- package/plugins/sp/scripts/validate-commands.ts +651 -0
- package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
- package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
- package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
- package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
- package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
- package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
- package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +176 -0
- package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
- package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
- package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
- package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
- package/plugins/sp/skills/code-review/SKILL.md +112 -0
- package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
- package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
- package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
- package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
- package/plugins/sp/skills/code-testing/SKILL.md +108 -0
- package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
- package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
- package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
- package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
- package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
- package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
- package/plugins/sp/skills/code-verification/SKILL.md +535 -0
- package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
- package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
- package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
- package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
- package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
- package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
- package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
- package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
- package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
- package/plugins/sp/skills/functional-review/SKILL.md +364 -0
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
- package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
- package/plugins/sp/skills/issue-finding/SKILL.md +424 -0
- package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
- package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
- package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
- package/plugins/sp/skills/issue-finding/references/session-formats.md +121 -0
- package/plugins/sp/skills/next-feature/SKILL.md +125 -0
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
- package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
- package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
- package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
- package/plugins/sp/skills/next-router/SKILL.md +181 -0
- package/plugins/sp/skills/next-router/references/messages.md +90 -0
- package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
- package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +100 -0
- package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
- package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
- package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
- package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
- package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
- package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
- package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
- package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
- package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
- package/plugins/sp/skills/spur-cli/references/features.md +234 -0
- package/plugins/sp/skills/spur-cli/references/init.md +119 -0
- package/plugins/sp/skills/spur-cli/references/message.md +98 -0
- package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
- package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
- package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
- package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
- package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
- package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +278 -0
- package/plugins/sp/skills/spur-cli/references/team.md +133 -0
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
- package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
- package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +664 -0
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +727 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +350 -0
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
- package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +88 -0
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
- package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
- package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
- package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
- package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
- package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
- package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
- package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
- package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
- package/spur.js +6093 -5180
|
@@ -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`
|