@davesheffer/hunch 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +242 -0
  2. package/bench/constitution-exp03-v1.json +70 -0
  3. package/dist/cli/index.js +1630 -107
  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 +1007 -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 +132 -0
  31. package/dist/constitution/lifecycle.js +224 -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/repairPolicies.js +78 -0
  38. package/dist/constitution/replay.js +361 -0
  39. package/dist/constitution/replayCache.js +89 -0
  40. package/dist/constitution/replayWorker.js +34 -0
  41. package/dist/constitution/repository.js +533 -0
  42. package/dist/constitution/schema.js +545 -0
  43. package/dist/constitution/scorecard.js +106 -0
  44. package/dist/constitution/service.js +1211 -0
  45. package/dist/constitution/shadow.js +235 -0
  46. package/dist/constitution/sourceMutation.js +316 -0
  47. package/dist/constitution/structural.js +601 -0
  48. package/dist/core/autoreview.js +27 -3
  49. package/dist/core/dupdetect.js +10 -3
  50. package/dist/core/escalations.js +65 -0
  51. package/dist/core/events.js +61 -0
  52. package/dist/core/externalImports.js +24 -0
  53. package/dist/core/hookpolicy.js +3 -0
  54. package/dist/core/memorylog.js +69 -0
  55. package/dist/core/relativeImports.js +33 -0
  56. package/dist/core/repair.js +71 -0
  57. package/dist/core/reviewqueue.js +11 -0
  58. package/dist/core/stats.js +115 -0
  59. package/dist/extractors/git.js +120 -0
  60. package/dist/extractors/indexer.js +39 -38
  61. package/dist/extractors/nativeTreeSitter.js +108 -0
  62. package/dist/extractors/parse.js +5 -15
  63. package/dist/integrations/claudemd.js +8 -1
  64. package/dist/integrations/gitignore.js +8 -0
  65. package/dist/integrations/providers.js +32 -10
  66. package/dist/integrations/sync.js +16 -1
  67. package/dist/mcp/server.js +317 -1
  68. package/dist/synthesis/synthesize.js +8 -1
  69. package/dist/wiki/graph.js +301 -0
  70. package/dist/wiki/wiki.js +31 -3
  71. package/package.json +5 -1
package/README.md CHANGED
@@ -53,6 +53,34 @@ Hunch creates a local graph of:
53
53
  It then puts that context where work happens: MCP tools, the CLI, a VS Code Change Gate, git hooks,
54
54
  and an optional pull-request guard.
55
55
 
56
+ ## Memory that runs itself (v1.8)
57
+
58
+ There is no review queue to manage. Hunch's memory loop is fully automated, and the rare decision
59
+ that genuinely needs a human is asked **inline, at the moment** — never parked in a backlog:
60
+
61
+ - **Auto-trust** — every captured decision enters the graph as live advisory memory the moment it
62
+ lands. It grounds and ranks immediately; it can never hard-block anything until a human
63
+ explicitly vouches for it. Migrate an old draft backlog once with `hunch adopt-drafts`.
64
+ - **A source-control panel for memory** — the VS Code **Hunch Memory** view shows every move
65
+ Hunch makes (capture / adopt / supersede / prune / repair) as a timeline: click for the diff,
66
+ right-click to revert locally. `hunch log` is the same spine in the terminal.
67
+ - **Inline escalations** — `hunch escalations` (and the `hunch_escalations` MCP tool) lists only
68
+ what the graph cannot resolve itself: a topic conflict, a candidate rule awaiting review, a
69
+ proposed rule ready to activate. Each entry is a question with its resolution verb. Normally
70
+ empty.
71
+ - **Self-repair** — rename a file and the next sync automatically heals every decision binding,
72
+ tripwire scope, constraint scope, and policy selector that matched it exactly (git's own rename
73
+ detection, zero guessing). Repairs land as revertable timeline moves; a repaired *policy* asks
74
+ once, inline, for a fresh proof.
75
+ - **Local-first by design** — memory auto-commits locally and rides your next push;
76
+ `hunch push` (or the panel's Approve-to-push) is the one deliberate outward step.
77
+
78
+ ```bash
79
+ hunch log # the memory timeline (what Hunch did, when, revertable)
80
+ hunch escalations # the decisions only you can make — normally empty
81
+ hunch repair --apply # heal bindings after a rename (sync does this automatically)
82
+ ```
83
+
56
84
  ## One graph. Every assistant. No lock-in.
57
85
 
58
86
  Hunch is agent-agnostic by design. It scaffolds MCP and grounding for Claude Code, Cursor, VS Code / Copilot,
@@ -99,6 +127,205 @@ hunch check --staged --strict
99
127
  hunch conform --strict
100
128
  ```
101
129
 
130
+ ### Hunch Constitution — experimental Gate G1 + evidence bootstrap
131
+
132
+ Hunch can now lift one structured architectural decision into versioned Policy IR, prove its
133
+ deterministic behavior with a clean baseline plus a mutation, and require an explicit human event
134
+ before it becomes enforceable:
135
+
136
+ ```bash
137
+ hunch constitution bootstrap --public-only --since 90d --max-candidates 3
138
+ hunch constitution ingest --public-only --since 90d
139
+ hunch constitution ingest --public-only --instructions --from pr-export.json
140
+ hunch constitution delta dec_fix_or_revert --public-only
141
+ hunch constitution bootstrap --history --public-only --since 90d --max-candidates 3
142
+ hunch policy compile dec_service_boundary --through OrderService
143
+ hunch policy corpus pol_… --import corpus.json
144
+ hunch policy plan pol_… --history 20 --mutations 3
145
+ hunch policy prove pol_…
146
+ hunch policy history pol_…
147
+ hunch policy history pol_… --commit <full-sha> --classify true_positive_actionable --actor github:your-name --reason "Confirmed historical violation"
148
+ hunch policy shadow pol_… --record
149
+ hunch policy shadow pol_…
150
+ hunch policy card pol_…
151
+ hunch policy relations pol_…
152
+ hunch policy accept pol_… --blocking --actor github:your-name
153
+ hunch policy evaluate pol_… --json
154
+ hunch policy evaluate pol_… --working --json
155
+ hunch policy evaluate pol_… --staged --json
156
+ ```
157
+
158
+ Private G2 dogfood stays evidence-only until a separate human signoff. An exact private plan selects
159
+ at least ten P3+ policies and seven category-specific runbooks; drills write no evidence by
160
+ themselves, rehearsals bind the resulting hashes, and historical shadow backfill commits only after
161
+ the complete policy/commit matrix has produced no unknown or error result:
162
+
163
+ ```bash
164
+ hunch constitution g2 --plan private-g2-plan.json
165
+ hunch constitution g2 --drill all
166
+ hunch constitution g2 --rehearse rb_g2_evaluator_error_01 --result passed \
167
+ --actor human:owner --evidence sha1:… --notes "Exact recovery drill passed."
168
+ hunch constitution g2 --backfill 20
169
+ hunch constitution g2 --queue 20
170
+ hunch constitution g2 --strict
171
+ ```
172
+
173
+ Backfill uses distinct real first-parent commits, excludes commits predating an executable policy's
174
+ fixing commit, and deduplicates by exact policy/proof/repository/graph identity. A failed preflight
175
+ writes nothing. Neither a ready packet nor a passed drill activates, warns, blocks, or claims G2;
176
+ the strongest machine result is `eligible_for_human_g2_signoff`.
177
+
178
+ The model-free bootstrap considers only current, accepted, human-confirmed decisions carrying
179
+ exactly one structured `conformance` predicate. It normalizes auditable evidence and keeps a bounded
180
+ queue of at most three unreviewed candidates. Re-running is idempotent, private evidence inherits
181
+ private storage, and every candidate starts with `authority: null`—bootstrap can never activate or
182
+ block on its own.
183
+
184
+ The opt-in history path reads the exact blobs for a human-confirmed fix/revert commit and its first
185
+ parent—without checking out code or running hooks. It also admits an architectural replacement
186
+ when a human-confirmed decision carries an explicit `retired.deps` entry that exactly matches a
187
+ removed external package. It enumerates only assertions the current graph can bind exactly and
188
+ whose symbol/call/package identifiers the human judgment explicitly names. One
189
+ supported meaning may become a compiled candidate; zero, multiple, missing,
190
+ or ambiguous meanings are stored as `uncompilable`, never silently approximated. `constitution
191
+ delta` previews that evidence and candidate set without writing policy state.
192
+
193
+ The external-import slice is deliberately narrow: removing a human-named static ESM package
194
+ specifier can compile into a file-scoped `not-reaches(..., external:<package>)` boundary. Package
195
+ subpaths canonicalize to their package root, the anchor must exist before and after the change, and
196
+ an explicitly retired dependency filters unrelated call/symbol facts from the same replacement
197
+ commit. Exact relative JS/TS imports across two derived components can also compile to direct
198
+ `reaches`/`not-reaches` policies over `depends_on` edges when both component meanings are explicitly
199
+ human-grounded. Same-component imports, ambiguous/missing targets, import-map aliases, `require()`,
200
+ dynamic `import()`, runtime loading, and positive external-package requirements remain visibly
201
+ unsupported.
202
+
203
+ Local correction, incident, and test-failure records can be normalized with `constitution ingest`.
204
+ The adapter stores references and hashes, inherits private storage, and creates no policy authority.
205
+ Add `--instructions` to hash committed AGENTS/CLAUDE/Copilot/Cursor/Windsurf instructions and ADRs
206
+ from immutable Git blobs. Add `--from` for one or more strict local review, conversation, or PR
207
+ export JSON files. Raw prose is never copied into EvidenceEvents; only bounded metadata, references,
208
+ and content hashes persist. Mixed batches validate before the first write, public-only mode refuses
209
+ private/secret items, and unsupported meaning stays explicitly `uncompilable` instead of being
210
+ approximated into a policy.
211
+
212
+ ```json
213
+ {
214
+ "version": 1,
215
+ "source": "pr_export",
216
+ "items": [{
217
+ "id": "pr-431-review-7",
218
+ "kind": "review",
219
+ "occurred_at": "2026-07-10T10:10:00Z",
220
+ "actor": "maintainer:alice",
221
+ "commit": "abc1234",
222
+ "files": ["src/orders.ts"],
223
+ "text": "Use OrderService; do not call persistence here.",
224
+ "data_class": "private",
225
+ "maintainer_confirmed": true
226
+ }]
227
+ }
228
+ ```
229
+
230
+ `policy plan` then writes a content-addressed ProofPlan before execution: exact source/current commits,
231
+ known-good/known-bad corpus, deterministic mutation operators, expectations, and resource budgets.
232
+ `policy corpus --import` accepts bounded labeled `known_bad`/`known_good` Git refs, resolves them
233
+ once to full immutable commit SHAs, stores the manifest in the policy's public/private home, and
234
+ hash-binds it into every resulting plan. A commit cannot be labeled both good and bad, and stale
235
+ policy-bound corpora must be re-imported after semantic policy changes. A `known_good` fixture may
236
+ also carry an explicit human attestation—`{ "actor": "github:your-name", "reason": "…" }`—to
237
+ document why that accepted variant belongs in the corpus. Attested fixtures are replayed once as
238
+ named corpus evidence and excluded from accepted-history sampling; the attestation cannot waive a
239
+ policy result or create authority.
240
+ `policy relations` is a read-only view of those explicit exception-parent links. It shows the
241
+ selected policy, its parent if any, linked narrower exceptions, and a visible missing-parent marker
242
+ for a manually damaged record. When the broad parent is planned, proved, or evaluated, every linked
243
+ exception descendant is instead hash-bound into one canonical composition. The deepest applicable
244
+ explicit scope selects the result; equal-scope ambiguity, missing bindings, or unsupported component
245
+ path precision stays unknown/error rather than falling through to the broad rule.
246
+ `policy consolidation` is also read-only. When a compiler-produced advisory scope suggestion exists,
247
+ it groups only matching narrow policies with the same assertion/data class and syntactically contained
248
+ scopes, then requires three independent decision references with no exception, active-policy,
249
+ conflict, or counterexample signal before marking the packet reviewable. It never merges or widens a
250
+ policy.
251
+ `policy history` inspects every violated accepted-history receipt and its current human disposition.
252
+ Disposition records are strict, content-addressed, stored in the policy's public/private home, and
253
+ bound to the exact policy hash, proof, plan, commit, and replay receipt. Corrections append a new
254
+ record with `--supersedes`; prior judgments remain auditable. Only `true_positive_actionable` clears
255
+ the history-evidence gate. False positives, insufficient-parser unknowns, and accepted exceptions
256
+ remain blockers until the policy/evaluator or combined exception semantics are repaired and
257
+ re-proved. A disposition never activates policy: blocking still requires a separate explicit human
258
+ `policy accept`, and a later corrected disposition is rechecked on every gate evaluation.
259
+ `policy shadow --record` appends one content-addressed evaluation for the exact current graph and
260
+ deduplicates retries of the same receipt. Violations use a separate append-only human disposition
261
+ chain, while `policy shadow` reports raw recent-window counts, confirmed and lower-bound precision,
262
+ unknown/error rate, mutation sensitivity, thresholds, and P4-review eligibility. Shadow records
263
+ never warn, block, change proof class, or activate policy; the MCP shadow tool is read-only.
264
+ Planning runs no replay, test, model, or activation; `policy prove` binds its receipt to that plan.
265
+ Proof execution checks out each unique immutable commit into a disposable worktree with hooks,
266
+ user-global Git configuration, private-overlay discovery, and provider selection disabled. It
267
+ indexes cold snapshots through a bounded four-worker pool (hard maximum eight), reuses
268
+ content-validated data-class-separated graph caches, records canonical current/known-good/
269
+ known-bad/accepted-history receipts, then removes every checkout and transient graph. Scheduling
270
+ and cache statistics never enter proof hashes. Project code, builds, and tests are never executed.
271
+ Timeouts, worker failures, unresolved refs, unknowns, and errors remain explicit.
272
+
273
+ Level-1 evaluators include `must-pass-through` (every statically discovered path from A to C must
274
+ contain B), exact external-package boundaries, and component/component-id selectors over static
275
+ `depends_on` edges. CLI, MCP (`hunch_policy_evaluate`), and strict CI share the exact canonical
276
+ receipt. Direct `reaches`/`not-reaches` contradictions are stored as conflict evidence without
277
+ minting a second policy or changing authority. Candidate records retain the exact alternatives,
278
+ unsupported facts, incumbent, and conflict IDs for proof-card review. Equivalent evidence enriches
279
+ the incumbent idempotently without changing its assertion, scope, proof, lifecycle, or authority.
280
+ Three independently grounded component-policy sources may add an advisory common-path scope
281
+ suggestion, while same-named behavior outside a narrow symbol scope is surfaced as a counterexample.
282
+ Suggestions and counterexamples are review evidence only: the compiled scope is never widened
283
+ automatically.
284
+
285
+ Executable-behavior policies keep their proof and history replay bound to immutable commits and
286
+ exact dependency snapshots. For advisory delivery, `policy evaluate --staged`, `--working`, the MCP
287
+ workspace option, and the pre-commit `check` path materialize the selected pending snapshot in a
288
+ disposable checkout before running the same hash-pinned test. The receipt binds the base commit,
289
+ snapshot hash, and changed paths; untracked regular files are included, repository hooks and global
290
+ Git configuration remain disabled, and dependency-manifest changes return an explicit error rather
291
+ than using stale dependencies. Advisory violations warn but never block, and `--public-only` never
292
+ loads private policies.
293
+ An intentional narrow opposite can be linked explicitly with `hunch policy exception <child>
294
+ --parent <parent> --actor human:<identity> --reason "…"`. The relationship requires identical
295
+ bindings/relation, opposite `reaches` semantics, matching data class/home, and a strictly contained
296
+ scope. Linking invalidates the child's prior proof and authority and returns it to non-blocking
297
+ `compiled` state. The broad parent remains the enforcement unit: its plan, proof, replay and mutation
298
+ receipts bind the full exception tree, and any later exception change retracts blocking eligibility
299
+ until a fresh composite proof is generated. Proof never activates the parent; a separate human
300
+ `policy accept` remains mandatory.
301
+ Models do not participate in evaluation or activation. Plan-bound proofs cover the committed current
302
+ baseline, known-good/known-bad fixtures, bounded accepted history, and a canonical mutation
303
+ manifest. The primary mutation is applied to an immutable disposable source checkout, must remain
304
+ parseable, and persists its exact Git diff plus resulting graph diff. Comment/string parser and
305
+ same-name ambiguity controls remain separate; any failed required receipt prevents blocking review.
306
+ Optional project build/test status is reported separately and is never required for evaluator
307
+ sensitivity. Historical hits are
308
+ not called false positives until classified, and unclassified hits or replay errors prevent
309
+ blocking approval. Shadow evidence and broader compiler inference remain follow-on work and are
310
+ reported as limitations in the proof artifact.
311
+
312
+ `policy card` (also `hunch_policy_card` over MCP) renders the same deterministic review surface for
313
+ every client: exact assertion and scope, raw evidence vector, unclassified hits, unknown/errors,
314
+ blocking readiness, current authority, limitations, and next actions. It never averages evidence
315
+ into a confidence score and never grants authority.
316
+
317
+ The versioned 20-case EXP-03 compiler bank is recomputed with:
318
+
319
+ ```bash
320
+ hunch constitution scorecard
321
+ ```
322
+
323
+ The scorecard reports the raw numerator/denominator, the absolute difference from the preregistered
324
+ 70% threshold, a Wilson 95% interval, per-outcome counts, and silent semantic substitutions. One
325
+ unsupported-to-assertion substitution fails the gate even when the aggregate rate remains above the
326
+ threshold. This curated scorecard measures deterministic compiler classification, not real-user
327
+ authoring speed or acceptance; those human-review arms remain a separate EXP-03 study.
328
+
102
329
  ## Private when the reasoning is sensitive
103
330
 
104
331
  Open-source the code without open-sourcing the reasoning.
@@ -133,6 +360,21 @@ Hunch can answer with the actual context: this boundary exists because of the N+
133
360
  service layer was the chosen repair, and the direct import violates a confirmed constraint. That is
134
361
  the missing layer between fast code generation and durable engineering judgment.
135
362
 
363
+ ## Certify a release candidate
364
+
365
+ ```bash
366
+ npm run gate:release
367
+ ```
368
+
369
+ The same fail-closed runner gates pull requests, main, and npm publication. It binds the package
370
+ version and optional release tag to HEAD; runs typecheck, the full suite, core and VS Code builds,
371
+ a fresh public repository index plus strict architectural conformance, a clean-installed tarball replay/privacy rehearsal, and the
372
+ production dependency audit; then writes a content-addressed receipt under
373
+ `.hunch-cache/release/`. A failed prerequisite stops later commands, a tag/version/commit mismatch
374
+ refuses before execution, and publication remains unreachable unless the exact tagged checkout is
375
+ clean and every gate passes. The receipt includes the prior-version rollback command; it never
376
+ activates, promotes, warns, or blocks a Constitution policy.
377
+
136
378
  ## Learn more
137
379
 
138
380
  - [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
+ }