@davesheffer/hunch 1.7.0 → 1.7.1

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 (63) hide show
  1. package/README.md +214 -0
  2. package/bench/constitution-exp03-v1.json +70 -0
  3. package/dist/cli/index.js +1203 -24
  4. package/dist/constitution/adapters.js +487 -0
  5. package/dist/constitution/behaviorAttestationBinding.js +17 -0
  6. package/dist/constitution/behaviorEvaluator.js +220 -0
  7. package/dist/constitution/behaviorProof.js +205 -0
  8. package/dist/constitution/behaviorWorkspace.js +124 -0
  9. package/dist/constitution/bootstrap.js +133 -0
  10. package/dist/constitution/canonical.js +51 -0
  11. package/dist/constitution/card.js +133 -0
  12. package/dist/constitution/compiler.js +176 -0
  13. package/dist/constitution/composition.js +101 -0
  14. package/dist/constitution/corpus.js +58 -0
  15. package/dist/constitution/delta.js +154 -0
  16. package/dist/constitution/disposition.js +141 -0
  17. package/dist/constitution/evaluator.js +435 -0
  18. package/dist/constitution/experiment.js +948 -0
  19. package/dist/constitution/experimentRunner.js +344 -0
  20. package/dist/constitution/g2.js +291 -0
  21. package/dist/constitution/g2BehaviorAttestation.js +209 -0
  22. package/dist/constitution/g2BehaviorCandidates.js +703 -0
  23. package/dist/constitution/g2BehaviorDependencies.js +379 -0
  24. package/dist/constitution/g2BehaviorMaterialization.js +171 -0
  25. package/dist/constitution/g2BehaviorPolicyMaterializer.js +241 -0
  26. package/dist/constitution/g2CandidateAttestation.js +179 -0
  27. package/dist/constitution/g2Candidates.js +195 -0
  28. package/dist/constitution/g2Drills.js +122 -0
  29. package/dist/constitution/g3.js +511 -0
  30. package/dist/constitution/g3Conformance.js +115 -0
  31. package/dist/constitution/lifecycle.js +189 -0
  32. package/dist/constitution/mutation.js +262 -0
  33. package/dist/constitution/nodeTestEvidence.js +47 -0
  34. package/dist/constitution/plan.js +172 -0
  35. package/dist/constitution/policyRuntime.js +8 -0
  36. package/dist/constitution/proof.js +166 -0
  37. package/dist/constitution/replay.js +361 -0
  38. package/dist/constitution/replayCache.js +89 -0
  39. package/dist/constitution/replayWorker.js +34 -0
  40. package/dist/constitution/repository.js +533 -0
  41. package/dist/constitution/schema.js +545 -0
  42. package/dist/constitution/scorecard.js +106 -0
  43. package/dist/constitution/service.js +1149 -0
  44. package/dist/constitution/shadow.js +235 -0
  45. package/dist/constitution/sourceMutation.js +316 -0
  46. package/dist/constitution/structural.js +601 -0
  47. package/dist/core/autoreview.js +27 -3
  48. package/dist/core/dupdetect.js +10 -3
  49. package/dist/core/events.js +61 -0
  50. package/dist/core/externalImports.js +24 -0
  51. package/dist/core/hookpolicy.js +3 -0
  52. package/dist/core/relativeImports.js +33 -0
  53. package/dist/core/stats.js +115 -0
  54. package/dist/extractors/git.js +81 -0
  55. package/dist/extractors/indexer.js +39 -38
  56. package/dist/extractors/nativeTreeSitter.js +108 -0
  57. package/dist/extractors/parse.js +5 -15
  58. package/dist/integrations/claudemd.js +8 -1
  59. package/dist/integrations/gitignore.js +8 -0
  60. package/dist/integrations/providers.js +32 -10
  61. package/dist/integrations/sync.js +16 -1
  62. package/dist/mcp/server.js +284 -0
  63. package/package.json +5 -1
package/README.md CHANGED
@@ -99,6 +99,205 @@ hunch check --staged --strict
99
99
  hunch conform --strict
100
100
  ```
101
101
 
102
+ ### Hunch Constitution — experimental Gate G1 + evidence bootstrap
103
+
104
+ Hunch can now lift one structured architectural decision into versioned Policy IR, prove its
105
+ deterministic behavior with a clean baseline plus a mutation, and require an explicit human event
106
+ before it becomes enforceable:
107
+
108
+ ```bash
109
+ hunch constitution bootstrap --public-only --since 90d --max-candidates 3
110
+ hunch constitution ingest --public-only --since 90d
111
+ hunch constitution ingest --public-only --instructions --from pr-export.json
112
+ hunch constitution delta dec_fix_or_revert --public-only
113
+ hunch constitution bootstrap --history --public-only --since 90d --max-candidates 3
114
+ hunch policy compile dec_service_boundary --through OrderService
115
+ hunch policy corpus pol_… --import corpus.json
116
+ hunch policy plan pol_… --history 20 --mutations 3
117
+ hunch policy prove pol_…
118
+ hunch policy history pol_…
119
+ hunch policy history pol_… --commit <full-sha> --classify true_positive_actionable --actor github:your-name --reason "Confirmed historical violation"
120
+ hunch policy shadow pol_… --record
121
+ hunch policy shadow pol_…
122
+ hunch policy card pol_…
123
+ hunch policy relations pol_…
124
+ hunch policy accept pol_… --blocking --actor github:your-name
125
+ hunch policy evaluate pol_… --json
126
+ hunch policy evaluate pol_… --working --json
127
+ hunch policy evaluate pol_… --staged --json
128
+ ```
129
+
130
+ Private G2 dogfood stays evidence-only until a separate human signoff. An exact private plan selects
131
+ at least ten P3+ policies and seven category-specific runbooks; drills write no evidence by
132
+ themselves, rehearsals bind the resulting hashes, and historical shadow backfill commits only after
133
+ the complete policy/commit matrix has produced no unknown or error result:
134
+
135
+ ```bash
136
+ hunch constitution g2 --plan private-g2-plan.json
137
+ hunch constitution g2 --drill all
138
+ hunch constitution g2 --rehearse rb_g2_evaluator_error_01 --result passed \
139
+ --actor human:owner --evidence sha1:… --notes "Exact recovery drill passed."
140
+ hunch constitution g2 --backfill 20
141
+ hunch constitution g2 --queue 20
142
+ hunch constitution g2 --strict
143
+ ```
144
+
145
+ Backfill uses distinct real first-parent commits, excludes commits predating an executable policy's
146
+ fixing commit, and deduplicates by exact policy/proof/repository/graph identity. A failed preflight
147
+ writes nothing. Neither a ready packet nor a passed drill activates, warns, blocks, or claims G2;
148
+ the strongest machine result is `eligible_for_human_g2_signoff`.
149
+
150
+ The model-free bootstrap considers only current, accepted, human-confirmed decisions carrying
151
+ exactly one structured `conformance` predicate. It normalizes auditable evidence and keeps a bounded
152
+ queue of at most three unreviewed candidates. Re-running is idempotent, private evidence inherits
153
+ private storage, and every candidate starts with `authority: null`—bootstrap can never activate or
154
+ block on its own.
155
+
156
+ The opt-in history path reads the exact blobs for a human-confirmed fix/revert commit and its first
157
+ parent—without checking out code or running hooks. It also admits an architectural replacement
158
+ when a human-confirmed decision carries an explicit `retired.deps` entry that exactly matches a
159
+ removed external package. It enumerates only assertions the current graph can bind exactly and
160
+ whose symbol/call/package identifiers the human judgment explicitly names. One
161
+ supported meaning may become a compiled candidate; zero, multiple, missing,
162
+ or ambiguous meanings are stored as `uncompilable`, never silently approximated. `constitution
163
+ delta` previews that evidence and candidate set without writing policy state.
164
+
165
+ The external-import slice is deliberately narrow: removing a human-named static ESM package
166
+ specifier can compile into a file-scoped `not-reaches(..., external:<package>)` boundary. Package
167
+ subpaths canonicalize to their package root, the anchor must exist before and after the change, and
168
+ an explicitly retired dependency filters unrelated call/symbol facts from the same replacement
169
+ commit. Exact relative JS/TS imports across two derived components can also compile to direct
170
+ `reaches`/`not-reaches` policies over `depends_on` edges when both component meanings are explicitly
171
+ human-grounded. Same-component imports, ambiguous/missing targets, import-map aliases, `require()`,
172
+ dynamic `import()`, runtime loading, and positive external-package requirements remain visibly
173
+ unsupported.
174
+
175
+ Local correction, incident, and test-failure records can be normalized with `constitution ingest`.
176
+ The adapter stores references and hashes, inherits private storage, and creates no policy authority.
177
+ Add `--instructions` to hash committed AGENTS/CLAUDE/Copilot/Cursor/Windsurf instructions and ADRs
178
+ from immutable Git blobs. Add `--from` for one or more strict local review, conversation, or PR
179
+ export JSON files. Raw prose is never copied into EvidenceEvents; only bounded metadata, references,
180
+ and content hashes persist. Mixed batches validate before the first write, public-only mode refuses
181
+ private/secret items, and unsupported meaning stays explicitly `uncompilable` instead of being
182
+ approximated into a policy.
183
+
184
+ ```json
185
+ {
186
+ "version": 1,
187
+ "source": "pr_export",
188
+ "items": [{
189
+ "id": "pr-431-review-7",
190
+ "kind": "review",
191
+ "occurred_at": "2026-07-10T10:10:00Z",
192
+ "actor": "maintainer:alice",
193
+ "commit": "abc1234",
194
+ "files": ["src/orders.ts"],
195
+ "text": "Use OrderService; do not call persistence here.",
196
+ "data_class": "private",
197
+ "maintainer_confirmed": true
198
+ }]
199
+ }
200
+ ```
201
+
202
+ `policy plan` then writes a content-addressed ProofPlan before execution: exact source/current commits,
203
+ known-good/known-bad corpus, deterministic mutation operators, expectations, and resource budgets.
204
+ `policy corpus --import` accepts bounded labeled `known_bad`/`known_good` Git refs, resolves them
205
+ once to full immutable commit SHAs, stores the manifest in the policy's public/private home, and
206
+ hash-binds it into every resulting plan. A commit cannot be labeled both good and bad, and stale
207
+ policy-bound corpora must be re-imported after semantic policy changes. A `known_good` fixture may
208
+ also carry an explicit human attestation—`{ "actor": "github:your-name", "reason": "…" }`—to
209
+ document why that accepted variant belongs in the corpus. Attested fixtures are replayed once as
210
+ named corpus evidence and excluded from accepted-history sampling; the attestation cannot waive a
211
+ policy result or create authority.
212
+ `policy relations` is a read-only view of those explicit exception-parent links. It shows the
213
+ selected policy, its parent if any, linked narrower exceptions, and a visible missing-parent marker
214
+ for a manually damaged record. When the broad parent is planned, proved, or evaluated, every linked
215
+ exception descendant is instead hash-bound into one canonical composition. The deepest applicable
216
+ explicit scope selects the result; equal-scope ambiguity, missing bindings, or unsupported component
217
+ path precision stays unknown/error rather than falling through to the broad rule.
218
+ `policy consolidation` is also read-only. When a compiler-produced advisory scope suggestion exists,
219
+ it groups only matching narrow policies with the same assertion/data class and syntactically contained
220
+ scopes, then requires three independent decision references with no exception, active-policy,
221
+ conflict, or counterexample signal before marking the packet reviewable. It never merges or widens a
222
+ policy.
223
+ `policy history` inspects every violated accepted-history receipt and its current human disposition.
224
+ Disposition records are strict, content-addressed, stored in the policy's public/private home, and
225
+ bound to the exact policy hash, proof, plan, commit, and replay receipt. Corrections append a new
226
+ record with `--supersedes`; prior judgments remain auditable. Only `true_positive_actionable` clears
227
+ the history-evidence gate. False positives, insufficient-parser unknowns, and accepted exceptions
228
+ remain blockers until the policy/evaluator or combined exception semantics are repaired and
229
+ re-proved. A disposition never activates policy: blocking still requires a separate explicit human
230
+ `policy accept`, and a later corrected disposition is rechecked on every gate evaluation.
231
+ `policy shadow --record` appends one content-addressed evaluation for the exact current graph and
232
+ deduplicates retries of the same receipt. Violations use a separate append-only human disposition
233
+ chain, while `policy shadow` reports raw recent-window counts, confirmed and lower-bound precision,
234
+ unknown/error rate, mutation sensitivity, thresholds, and P4-review eligibility. Shadow records
235
+ never warn, block, change proof class, or activate policy; the MCP shadow tool is read-only.
236
+ Planning runs no replay, test, model, or activation; `policy prove` binds its receipt to that plan.
237
+ Proof execution checks out each unique immutable commit into a disposable worktree with hooks,
238
+ user-global Git configuration, private-overlay discovery, and provider selection disabled. It
239
+ indexes cold snapshots through a bounded four-worker pool (hard maximum eight), reuses
240
+ content-validated data-class-separated graph caches, records canonical current/known-good/
241
+ known-bad/accepted-history receipts, then removes every checkout and transient graph. Scheduling
242
+ and cache statistics never enter proof hashes. Project code, builds, and tests are never executed.
243
+ Timeouts, worker failures, unresolved refs, unknowns, and errors remain explicit.
244
+
245
+ Level-1 evaluators include `must-pass-through` (every statically discovered path from A to C must
246
+ contain B), exact external-package boundaries, and component/component-id selectors over static
247
+ `depends_on` edges. CLI, MCP (`hunch_policy_evaluate`), and strict CI share the exact canonical
248
+ receipt. Direct `reaches`/`not-reaches` contradictions are stored as conflict evidence without
249
+ minting a second policy or changing authority. Candidate records retain the exact alternatives,
250
+ unsupported facts, incumbent, and conflict IDs for proof-card review. Equivalent evidence enriches
251
+ the incumbent idempotently without changing its assertion, scope, proof, lifecycle, or authority.
252
+ Three independently grounded component-policy sources may add an advisory common-path scope
253
+ suggestion, while same-named behavior outside a narrow symbol scope is surfaced as a counterexample.
254
+ Suggestions and counterexamples are review evidence only: the compiled scope is never widened
255
+ automatically.
256
+
257
+ Executable-behavior policies keep their proof and history replay bound to immutable commits and
258
+ exact dependency snapshots. For advisory delivery, `policy evaluate --staged`, `--working`, the MCP
259
+ workspace option, and the pre-commit `check` path materialize the selected pending snapshot in a
260
+ disposable checkout before running the same hash-pinned test. The receipt binds the base commit,
261
+ snapshot hash, and changed paths; untracked regular files are included, repository hooks and global
262
+ Git configuration remain disabled, and dependency-manifest changes return an explicit error rather
263
+ than using stale dependencies. Advisory violations warn but never block, and `--public-only` never
264
+ loads private policies.
265
+ An intentional narrow opposite can be linked explicitly with `hunch policy exception <child>
266
+ --parent <parent> --actor human:<identity> --reason "…"`. The relationship requires identical
267
+ bindings/relation, opposite `reaches` semantics, matching data class/home, and a strictly contained
268
+ scope. Linking invalidates the child's prior proof and authority and returns it to non-blocking
269
+ `compiled` state. The broad parent remains the enforcement unit: its plan, proof, replay and mutation
270
+ receipts bind the full exception tree, and any later exception change retracts blocking eligibility
271
+ until a fresh composite proof is generated. Proof never activates the parent; a separate human
272
+ `policy accept` remains mandatory.
273
+ Models do not participate in evaluation or activation. Plan-bound proofs cover the committed current
274
+ baseline, known-good/known-bad fixtures, bounded accepted history, and a canonical mutation
275
+ manifest. The primary mutation is applied to an immutable disposable source checkout, must remain
276
+ parseable, and persists its exact Git diff plus resulting graph diff. Comment/string parser and
277
+ same-name ambiguity controls remain separate; any failed required receipt prevents blocking review.
278
+ Optional project build/test status is reported separately and is never required for evaluator
279
+ sensitivity. Historical hits are
280
+ not called false positives until classified, and unclassified hits or replay errors prevent
281
+ blocking approval. Shadow evidence and broader compiler inference remain follow-on work and are
282
+ reported as limitations in the proof artifact.
283
+
284
+ `policy card` (also `hunch_policy_card` over MCP) renders the same deterministic review surface for
285
+ every client: exact assertion and scope, raw evidence vector, unclassified hits, unknown/errors,
286
+ blocking readiness, current authority, limitations, and next actions. It never averages evidence
287
+ into a confidence score and never grants authority.
288
+
289
+ The versioned 20-case EXP-03 compiler bank is recomputed with:
290
+
291
+ ```bash
292
+ hunch constitution scorecard
293
+ ```
294
+
295
+ The scorecard reports the raw numerator/denominator, the absolute difference from the preregistered
296
+ 70% threshold, a Wilson 95% interval, per-outcome counts, and silent semantic substitutions. One
297
+ unsupported-to-assertion substitution fails the gate even when the aggregate rate remains above the
298
+ threshold. This curated scorecard measures deterministic compiler classification, not real-user
299
+ authoring speed or acceptance; those human-review arms remain a separate EXP-03 study.
300
+
102
301
  ## Private when the reasoning is sensitive
103
302
 
104
303
  Open-source the code without open-sourcing the reasoning.
@@ -133,6 +332,21 @@ Hunch can answer with the actual context: this boundary exists because of the N+
133
332
  service layer was the chosen repair, and the direct import violates a confirmed constraint. That is
134
333
  the missing layer between fast code generation and durable engineering judgment.
135
334
 
335
+ ## Certify a release candidate
336
+
337
+ ```bash
338
+ npm run gate:release
339
+ ```
340
+
341
+ The same fail-closed runner gates pull requests, main, and npm publication. It binds the package
342
+ version and optional release tag to HEAD; runs typecheck, the full suite, core and VS Code builds,
343
+ a fresh public repository index plus strict architectural conformance, a clean-installed tarball replay/privacy rehearsal, and the
344
+ production dependency audit; then writes a content-addressed receipt under
345
+ `.hunch-cache/release/`. A failed prerequisite stops later commands, a tag/version/commit mismatch
346
+ refuses before execution, and publication remains unreachable unless the exact tagged checkout is
347
+ clean and every gate passes. The receipt includes the prior-version rollback command; it never
348
+ activates, promotes, warns, or blocks a Constitution policy.
349
+
136
350
  ## Learn more
137
351
 
138
352
  - [Full documentation](https://hunch-pi.vercel.app/docs)
@@ -0,0 +1,70 @@
1
+ {
2
+ "version": 1,
3
+ "experiment": "EXP-03",
4
+ "threshold": 0.7,
5
+ "preregistered_metric": "intended supported assertion or honest non-minting classification",
6
+ "cases": [
7
+ {
8
+ "id": "exp03_added_call",
9
+ "family": "direct review correction",
10
+ "evidence": "Human names charge and verifySession; the fix adds the exact call.",
11
+ "expected": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "symbol:src/payments/charge.ts:charge" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/auth/session.ts:verifySession" } }, "scope": { "repos": [], "paths": ["src/payments/charge.ts"], "components": ["cmp_payments"] } },
12
+ "actual": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "symbol:src/payments/charge.ts:charge" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/auth/session.ts:verifySession" } }, "scope": { "repos": [], "paths": ["src/payments/charge.ts"], "components": ["cmp_payments"] } }
13
+ },
14
+ {
15
+ "id": "exp03_removed_call",
16
+ "family": "revert",
17
+ "evidence": "Human names run and dangerous; revert removes the exact call.",
18
+ "expected": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "symbol:src/runtime/worker.ts:run" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/runtime/worker.ts:dangerous" } }, "scope": { "repos": [], "paths": ["src/runtime/worker.ts"], "components": ["cmp_runtime"] } },
19
+ "actual": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "symbol:src/runtime/worker.ts:run" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/runtime/worker.ts:dangerous" } }, "scope": { "repos": [], "paths": ["src/runtime/worker.ts"], "components": ["cmp_runtime"] } }
20
+ },
21
+ {
22
+ "id": "exp03_added_symbol",
23
+ "family": "incident fix",
24
+ "evidence": "Human judgment explicitly names the introduced guard symbol.",
25
+ "expected": { "outcome": "assertion", "assertion": { "kind": "exists", "subject": { "selector": "symbol:src/security/guard.ts:verifyOrigin" } }, "scope": { "repos": [], "paths": ["src/security/guard.ts"], "components": ["cmp_security"] } },
26
+ "actual": { "outcome": "assertion", "assertion": { "kind": "exists", "subject": { "selector": "symbol:src/security/guard.ts:verifyOrigin" } }, "scope": { "repos": [], "paths": ["src/security/guard.ts"], "components": ["cmp_security"] } }
27
+ },
28
+ {
29
+ "id": "exp03_external_retirement",
30
+ "family": "architectural dependency retirement",
31
+ "evidence": "Decision.retired.deps names axios and the stable file anchor remains.",
32
+ "expected": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "symbol:src/services/orders.ts:fetchOrders" }, "relation": { "edges": ["imports"], "transitive": false, "max_depth": 1 }, "object": { "selector": "external:axios" } }, "scope": { "repos": [], "paths": ["src/services/orders.ts"], "components": ["cmp_services"] } },
33
+ "actual": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "symbol:src/services/orders.ts:fetchOrders" }, "relation": { "edges": ["imports"], "transitive": false, "max_depth": 1 }, "object": { "selector": "external:axios" } }, "scope": { "repos": [], "paths": ["src/services/orders.ts"], "components": ["cmp_services"] } }
34
+ },
35
+ {
36
+ "id": "exp03_removed_relative_component",
37
+ "family": "component boundary removal",
38
+ "evidence": "Human names Api and Db; the relative import and component bindings are exact.",
39
+ "expected": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "component-id:cmp_api" }, "relation": { "edges": ["depends_on"], "transitive": false, "max_depth": 1 }, "object": { "selector": "component-id:cmp_db" } }, "scope": { "repos": [], "paths": ["src/api/orders.ts"], "components": ["cmp_api", "cmp_db"] } },
40
+ "actual": { "outcome": "assertion", "assertion": { "kind": "not-reaches", "subject": { "selector": "component-id:cmp_api" }, "relation": { "edges": ["depends_on"], "transitive": false, "max_depth": 1 }, "object": { "selector": "component-id:cmp_db" } }, "scope": { "repos": [], "paths": ["src/api/orders.ts"], "components": ["cmp_api", "cmp_db"] }, "uncertainty": ["Unrelated call facts were rejected as structural coincidence."] }
41
+ },
42
+ {
43
+ "id": "exp03_added_relative_component",
44
+ "family": "component dependency restoration",
45
+ "evidence": "Human names Api and Services; the current depends_on edge is exact.",
46
+ "expected": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "component-id:cmp_api" }, "relation": { "edges": ["depends_on"], "transitive": false, "max_depth": 1 }, "object": { "selector": "component-id:cmp_services" } }, "scope": { "repos": [], "paths": ["src/api/orders.ts"], "components": ["cmp_api", "cmp_services"] } },
47
+ "actual": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "component-id:cmp_api" }, "relation": { "edges": ["depends_on"], "transitive": false, "max_depth": 1 }, "object": { "selector": "component-id:cmp_services" } }, "scope": { "repos": [], "paths": ["src/api/orders.ts"], "components": ["cmp_api", "cmp_services"] } }
48
+ },
49
+ { "id": "exp03_ambiguous_two_calls", "family": "ambiguous before-after", "evidence": "One call is removed and another added; the human text does not select one meaning.", "expected": { "outcome": "uncompilable", "uncertainty": ["two exact alternatives"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["removed-call alternative", "added-call alternative"], "reason": "Hunch refused to choose between two exact supported candidates." } },
50
+ { "id": "exp03_duplicate_target", "family": "ambiguous symbol", "evidence": "The removed callee name resolves to two current symbols.", "expected": { "outcome": "uncompilable", "uncertainty": ["ambiguous target"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["removed-call target is ambiguous"], "reason": "No exact binding exists." } },
51
+ { "id": "exp03_human_unnamed", "family": "structural coincidence", "evidence": "The diff is exact but the human judgment names neither endpoint.", "expected": { "outcome": "uncompilable", "uncertainty": ["human grounding absent"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["structural coincidence not explicitly named"], "reason": "No exact supported structural assertion." } },
52
+ { "id": "exp03_removed_symbol", "family": "retired symbol", "evidence": "The historical symbol has no enforceable current binding.", "expected": { "outcome": "uncompilable", "uncertainty": ["missing current binding"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["removed symbol has no enforceable current binding"] } },
53
+ { "id": "exp03_moved_symbol", "family": "rename and move", "evidence": "A move requires repair semantics and cannot be recast as exists.", "expected": { "outcome": "uncompilable", "uncertainty": ["repair semantics required"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["moved symbol needs repair semantics"] } },
54
+ { "id": "exp03_positive_external", "family": "positive package requirement", "evidence": "Adding an external import does not prove that the package must remain required.", "expected": { "outcome": "uncompilable", "uncertainty": ["positive requirement unsupported"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["positive package requirement evaluator absent"] } },
55
+ { "id": "exp03_same_component_relative", "family": "internal relative import", "evidence": "Both files belong to one component; no component edge represents the file relation.", "expected": { "outcome": "uncompilable", "uncertainty": ["internal edge unsupported"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["component evaluator cannot represent an internal file edge"] } },
56
+ { "id": "exp03_import_map", "family": "import-map boundary", "evidence": "A # alias has no exact local target without project-specific resolution.", "expected": { "outcome": "uncompilable", "uncertainty": ["import map unsupported"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["relative target missing and external package refused"] } },
57
+ { "id": "exp03_missing_relative_target", "family": "missing binding", "evidence": "The relative target no longer exists in the current graph.", "expected": { "outcome": "uncompilable", "uncertainty": ["missing target"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["relative import target is missing"] } },
58
+ { "id": "exp03_direct_conflict", "family": "contradictory decision", "evidence": "A new not-reaches candidate directly opposes an incumbent reaches policy over the same scope.", "expected": { "outcome": "conflicted", "conflicts": ["pol_aaaaaaaaaa"] }, "actual": { "outcome": "conflicted", "conflicts": ["pol_aaaaaaaaaa"], "reason": "No policy minted and no authority changed." } },
59
+ { "id": "exp03_equivalent_incumbent", "family": "existing equivalent", "evidence": "Assertion, scope, and data class exactly match an incumbent.", "expected": { "outcome": "covered", "incumbent": "pol_bbbbbbbbbb" }, "actual": { "outcome": "covered", "incumbent": "pol_bbbbbbbbbb", "reason": "Incumbent lifecycle preserved and evidence linked." } },
60
+ {
61
+ "id": "exp03_private_exact",
62
+ "family": "private evidence",
63
+ "evidence": "A private human-confirmed fix yields the same exact assertion in the private home.",
64
+ "expected": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "symbol:src/payments/charge.ts:charge" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/auth/session.ts:verifySession" } }, "scope": { "repos": [], "paths": ["src/payments/charge.ts"], "components": ["cmp_payments"] } },
65
+ "actual": { "outcome": "assertion", "assertion": { "kind": "reaches", "subject": { "selector": "symbol:src/payments/charge.ts:charge" }, "relation": { "edges": ["calls"], "transitive": false, "max_depth": 1 }, "object": { "selector": "symbol:src/auth/session.ts:verifySession" } }, "scope": { "repos": [], "paths": ["src/payments/charge.ts"], "components": ["cmp_payments"] } }
66
+ },
67
+ { "id": "exp03_prose_only_instruction", "family": "prose-only judgment", "evidence": "The instruction contains no supported structured predicate or attributable delta.", "expected": { "outcome": "uncompilable", "uncertainty": ["no deterministic evaluator"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["normalized instruction is evidence-only"] } },
68
+ { "id": "exp03_multi_family_delta", "family": "mixed large fix", "evidence": "The fix yields exact call, symbol, and import candidates with no human-selected meaning.", "expected": { "outcome": "uncompilable", "uncertainty": ["multiple meanings"] }, "actual": { "outcome": "uncompilable", "uncertainty": ["call alternative", "symbol alternative", "import alternative"] } }
69
+ ]
70
+ }