@davesheffer/hunch 1.31.1 → 1.32.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 (220) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/automaticReviewMemory.d.ts +13 -0
  3. package/dist/cli/dna.d.ts +2 -0
  4. package/dist/cli/index.d.ts +16 -0
  5. package/dist/cli/index.js +602 -43
  6. package/dist/cli/integrations.d.ts +2 -0
  7. package/dist/cli/integrations.js +5 -2
  8. package/dist/cli/invocation.d.ts +35 -0
  9. package/dist/cli/preflight.d.ts +1 -0
  10. package/dist/cli/reviewMemory.d.ts +4 -0
  11. package/dist/cli/reviewMemoryProvider.d.ts +14 -0
  12. package/dist/cli/serve.d.ts +2 -0
  13. package/dist/cli/taskReport.d.ts +6 -0
  14. package/dist/cli/taskReport.js +124 -0
  15. package/dist/cli/update.d.ts +14 -0
  16. package/dist/client/state.d.ts +248 -0
  17. package/dist/constitution/adapters.d.ts +29 -0
  18. package/dist/constitution/behaviorAttestationBinding.d.ts +3 -0
  19. package/dist/constitution/behaviorEvaluator.d.ts +8 -0
  20. package/dist/constitution/behaviorProof.d.ts +9 -0
  21. package/dist/constitution/behaviorWorkspace.d.ts +25 -0
  22. package/dist/constitution/bootstrap.d.ts +30 -0
  23. package/dist/constitution/canonical.d.ts +15 -0
  24. package/dist/constitution/card.d.ts +58 -0
  25. package/dist/constitution/compiler.d.ts +52 -0
  26. package/dist/constitution/composition.d.ts +10 -0
  27. package/dist/constitution/corpus.d.ts +7 -0
  28. package/dist/constitution/correctionPolicyMaterializer.d.ts +57 -0
  29. package/dist/constitution/delta.d.ts +4 -0
  30. package/dist/constitution/disposition.d.ts +20 -0
  31. package/dist/constitution/evaluator.d.ts +47 -0
  32. package/dist/constitution/experiment.d.ts +466 -0
  33. package/dist/constitution/experimentRunner.d.ts +7 -0
  34. package/dist/constitution/g2.d.ts +209 -0
  35. package/dist/constitution/g2BehaviorAttestation.d.ts +45 -0
  36. package/dist/constitution/g2BehaviorCandidates.d.ts +123 -0
  37. package/dist/constitution/g2BehaviorDependencies.d.ts +83 -0
  38. package/dist/constitution/g2BehaviorMaterialization.d.ts +77 -0
  39. package/dist/constitution/g2BehaviorPolicyMaterializer.d.ts +48 -0
  40. package/dist/constitution/g2CandidateAttestation.d.ts +43 -0
  41. package/dist/constitution/g2Candidates.d.ts +80 -0
  42. package/dist/constitution/g2Drills.d.ts +33 -0
  43. package/dist/constitution/g3.d.ts +311 -0
  44. package/dist/constitution/g3Conformance.d.ts +33 -0
  45. package/dist/constitution/lifecycle.d.ts +25 -0
  46. package/dist/constitution/mutation.d.ts +15 -0
  47. package/dist/constitution/nodeTestEvidence.d.ts +13 -0
  48. package/dist/constitution/plan.d.ts +18 -0
  49. package/dist/constitution/policyRuntime.d.ts +5 -0
  50. package/dist/constitution/proof.d.ts +11 -0
  51. package/dist/constitution/repairPolicies.d.ts +34 -0
  52. package/dist/constitution/replacementFreeGit.d.ts +14 -0
  53. package/dist/constitution/replay.d.ts +40 -0
  54. package/dist/constitution/replayCache.d.ts +14 -0
  55. package/dist/constitution/replayWorker.d.ts +1 -0
  56. package/dist/constitution/repository.d.ts +129 -0
  57. package/dist/constitution/safeCheckout.d.ts +9 -0
  58. package/dist/constitution/schema.d.ts +1763 -0
  59. package/dist/constitution/scorecard.d.ts +219 -0
  60. package/dist/constitution/service.d.ts +398 -0
  61. package/dist/constitution/shadow.d.ts +54 -0
  62. package/dist/constitution/sourceMutation.d.ts +15 -0
  63. package/dist/constitution/staticGraphBaseline.d.ts +13 -0
  64. package/dist/constitution/structural.d.ts +64 -0
  65. package/dist/core/agenthook.d.ts +63 -0
  66. package/dist/core/agenthook.js +1 -0
  67. package/dist/core/automaticReviewMemory.d.ts +60 -0
  68. package/dist/core/autoreview.d.ts +66 -0
  69. package/dist/core/canonicalOrder.d.ts +3 -0
  70. package/dist/core/capturetoken.d.ts +19 -0
  71. package/dist/core/changeIdentity.d.ts +22 -0
  72. package/dist/core/changeProof.d.ts +14 -0
  73. package/dist/core/checkreport.d.ts +140 -0
  74. package/dist/core/commitrepair.d.ts +171 -0
  75. package/dist/core/commitrepair.js +238 -0
  76. package/dist/core/compare.d.ts +21 -0
  77. package/dist/core/config.d.ts +20 -0
  78. package/dist/core/conformance.d.ts +35 -0
  79. package/dist/core/constraintmatch.d.ts +54 -0
  80. package/dist/core/correction.d.ts +42 -0
  81. package/dist/core/correctionStage.d.ts +224 -0
  82. package/dist/core/declarationClusters.d.ts +149 -0
  83. package/dist/core/delivery.d.ts +110 -0
  84. package/dist/core/docanchors.d.ts +32 -0
  85. package/dist/core/docscan.d.ts +26 -0
  86. package/dist/core/drift.d.ts +13 -0
  87. package/dist/core/drift.js +31 -1
  88. package/dist/core/dupdetect.d.ts +43 -0
  89. package/dist/core/escalations.d.ts +129 -0
  90. package/dist/core/escalations.js +165 -0
  91. package/dist/core/events.d.ts +29 -0
  92. package/dist/core/evidenceMap.d.ts +164 -0
  93. package/dist/core/externalImports.d.ts +8 -0
  94. package/dist/core/format.d.ts +13 -0
  95. package/dist/core/glob.d.ts +9 -0
  96. package/dist/core/groundingLag.d.ts +84 -0
  97. package/dist/core/groundingLag.js +16 -2
  98. package/dist/core/groundingMerge.d.ts +15 -0
  99. package/dist/core/groundingMerge.js +95 -0
  100. package/dist/core/hookcache.d.ts +10 -0
  101. package/dist/core/hookpolicy.d.ts +47 -0
  102. package/dist/core/ids.d.ts +36 -0
  103. package/dist/core/importReview.d.ts +30 -0
  104. package/dist/core/io.d.ts +23 -0
  105. package/dist/core/jsonc.d.ts +4 -0
  106. package/dist/core/landscapeAdoption.d.ts +66 -0
  107. package/dist/core/landscapeDelivery.d.ts +76 -0
  108. package/dist/core/memorylog.d.ts +37 -0
  109. package/dist/core/migrate.d.ts +28 -0
  110. package/dist/core/outcomeExperience.d.ts +89 -0
  111. package/dist/core/overlaySafety.d.ts +24 -0
  112. package/dist/core/overlaySafety.js +7 -1
  113. package/dist/core/paths.d.ts +31 -0
  114. package/dist/core/pipeline.d.ts +289 -0
  115. package/dist/core/premises.d.ts +43 -0
  116. package/dist/core/provenance.d.ts +21 -0
  117. package/dist/core/publication.d.ts +54 -0
  118. package/dist/core/refrepair.d.ts +24 -0
  119. package/dist/core/refrepair.js +1 -1
  120. package/dist/core/relativeImports.d.ts +11 -0
  121. package/dist/core/repair.d.ts +44 -0
  122. package/dist/core/repairqueue.d.ts +40 -0
  123. package/dist/core/repairqueue.js +133 -0
  124. package/dist/core/reviewMemory.d.ts +40 -0
  125. package/dist/core/reviewqueue.d.ts +54 -0
  126. package/dist/core/safeRepoFile.d.ts +20 -0
  127. package/dist/core/served.d.ts +57 -0
  128. package/dist/core/served.js +14 -0
  129. package/dist/core/stateContract.d.ts +979 -0
  130. package/dist/core/stateDelivery.d.ts +78 -0
  131. package/dist/core/stateRecords.d.ts +383 -0
  132. package/dist/core/stats.d.ts +88 -0
  133. package/dist/core/strictgate.d.ts +33 -0
  134. package/dist/core/taskReport.d.ts +226 -0
  135. package/dist/core/taskReport.js +514 -0
  136. package/dist/core/taskReportCapture.d.ts +8 -0
  137. package/dist/core/taskReportCapture.js +36 -0
  138. package/dist/core/taskReportEvidence.d.ts +26 -0
  139. package/dist/core/taskReportEvidence.js +268 -0
  140. package/dist/core/taskReportHook.d.ts +20 -0
  141. package/dist/core/taskReportHook.js +76 -0
  142. package/dist/core/taskReportPaths.d.ts +3 -0
  143. package/dist/core/taskReportPaths.js +23 -0
  144. package/dist/core/taskReportPublic.d.ts +31 -0
  145. package/dist/core/taskReportPublic.js +45 -0
  146. package/dist/core/taskReportRender.d.ts +6 -0
  147. package/dist/core/taskReportRender.js +97 -0
  148. package/dist/core/topics.d.ts +73 -0
  149. package/dist/core/types.d.ts +1239 -0
  150. package/dist/core/version.d.ts +10 -0
  151. package/dist/eval/guards.d.ts +45 -0
  152. package/dist/eval/harness.d.ts +58 -0
  153. package/dist/extractors/adrImport.d.ts +59 -0
  154. package/dist/extractors/comments.d.ts +7 -0
  155. package/dist/extractors/correctionSources.d.ts +11 -0
  156. package/dist/extractors/diff.d.ts +40 -0
  157. package/dist/extractors/git.d.ts +304 -0
  158. package/dist/extractors/git.js +208 -20
  159. package/dist/extractors/helm.d.ts +31 -0
  160. package/dist/extractors/indexer.d.ts +55 -0
  161. package/dist/extractors/landscapeDiscovery.d.ts +41 -0
  162. package/dist/extractors/languages.d.ts +77 -0
  163. package/dist/extractors/nativeTreeSitter.d.ts +16 -0
  164. package/dist/extractors/parse.d.ts +54 -0
  165. package/dist/extractors/php.d.ts +26 -0
  166. package/dist/extractors/repoSource.d.ts +53 -0
  167. package/dist/extractors/testreport.d.ts +36 -0
  168. package/dist/integrations/ciAction.d.ts +8 -0
  169. package/dist/integrations/claudeConfig.d.ts +44 -0
  170. package/dist/integrations/claudemd.d.ts +13 -0
  171. package/dist/integrations/claudemd.js +11 -2
  172. package/dist/integrations/gitignore.d.ts +16 -0
  173. package/dist/integrations/gitignore.js +7 -0
  174. package/dist/integrations/health.d.ts +74 -0
  175. package/dist/integrations/hooks.d.ts +41 -0
  176. package/dist/integrations/hooks.js +92 -66
  177. package/dist/integrations/madrExport.d.ts +39 -0
  178. package/dist/integrations/madrManifest.d.ts +69 -0
  179. package/dist/integrations/mergeDriver.d.ts +3 -0
  180. package/dist/integrations/mergeDriver.js +25 -8
  181. package/dist/integrations/probe.d.ts +4 -0
  182. package/dist/integrations/providers.d.ts +103 -0
  183. package/dist/integrations/scaffold.d.ts +29 -0
  184. package/dist/integrations/sync.d.ts +30 -0
  185. package/dist/integrations/sync.js +3 -2
  186. package/dist/integrations/team.d.ts +70 -0
  187. package/dist/integrations/worktree.d.ts +8 -0
  188. package/dist/mcp/roots.d.ts +16 -0
  189. package/dist/mcp/server.d.ts +36 -0
  190. package/dist/mcp/server.js +74 -22
  191. package/dist/mcp/taskReportTools.d.ts +3 -0
  192. package/dist/mcp/taskReportTools.js +106 -0
  193. package/dist/serve/app.d.ts +36 -0
  194. package/dist/serve/config.d.ts +100 -0
  195. package/dist/serve/writelock.d.ts +22 -0
  196. package/dist/store/changeLedger.d.ts +132 -0
  197. package/dist/store/compact.d.ts +33 -0
  198. package/dist/store/db.d.ts +9 -0
  199. package/dist/store/embedder.d.ts +32 -0
  200. package/dist/store/hunchStore.d.ts +624 -0
  201. package/dist/store/hunchStore.js +6 -3
  202. package/dist/store/jsonStore.d.ts +125 -0
  203. package/dist/store/merge.d.ts +39 -0
  204. package/dist/store/privateMigrate.d.ts +24 -0
  205. package/dist/store/replay.d.ts +56 -0
  206. package/dist/store/schema.d.ts +17 -0
  207. package/dist/store/stateBinding.d.ts +145 -0
  208. package/dist/store/stateCapture.d.ts +15 -0
  209. package/dist/synthesis/cliAdapter.d.ts +22 -0
  210. package/dist/synthesis/initiator.d.ts +13 -0
  211. package/dist/synthesis/provider.d.ts +307 -0
  212. package/dist/synthesis/synthesize.d.ts +117 -0
  213. package/dist/synthesis/tripwires.d.ts +9 -0
  214. package/dist/taskReports.d.ts +76 -0
  215. package/dist/taskReports.js +67 -0
  216. package/dist/wiki/adopt.d.ts +22 -0
  217. package/dist/wiki/graph.d.ts +87 -0
  218. package/dist/wiki/wiki.d.ts +242 -0
  219. package/package.json +6 -5
  220. package/server.json +2 -2
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Deterministic repair for a decision's commit provenance after a squash-merge.
3
+ *
4
+ * A squash-merge produces one new commit whose parent is the pre-merge target
5
+ * tip — the original per-commit SHAs it squashed are never ancestors of it.
6
+ * This module matches an orphaned decision to the ONE newly-merged commit
7
+ * whose changed files are a superset of the decision's related_files. Zero or
8
+ * multiple qualifying candidates means "don't guess" — same discipline as
9
+ * repair.ts's rename-repair.
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ import { replaceExact } from "./refrepair.js";
13
+ /** Bind review to the ordered queue and which targets are currently resolvable.
14
+ * Queue order matters: duplicate decision ids use first-match selection. */
15
+ export function commitRepairReviewHash(queued, withheld = new Set()) {
16
+ const snapshot = queued.map((r) => ({ id: r.id, from: r.from, to: r.to, withheld: withheld.has(r) }));
17
+ return `sha256:${createHash("sha256").update(JSON.stringify(snapshot)).digest("hex")}`;
18
+ }
19
+ /** A scope entry is exact (usable as a match key) only when it contains no glob syntax. */
20
+ function isExactPath(entry) {
21
+ return !!entry && !/[*?[\]{}]/.test(entry);
22
+ }
23
+ /** Live decisions whose cited commit still exists here but is no longer an
24
+ * ancestor of the current tip. Only "orphaned" qualifies: a commit that
25
+ * doesn't resolve at all ("unresolvable") is out of repair scope, and a git
26
+ * failure ("unknown") must never be mistaken for repair-eligible. */
27
+ export function orphanedCommitDecisions(decisions, status) {
28
+ return decisions.filter((d) => {
29
+ if (d.status === "superseded" || d.status === "rejected")
30
+ return false;
31
+ if (!d.commit)
32
+ return false;
33
+ return status(d.commit) === "orphaned";
34
+ });
35
+ }
36
+ /** Match each orphaned decision to exactly one candidate whose changed files are
37
+ * a superset of the decision's related_files (non-empty, no globs). */
38
+ export function planCommitRepair(orphaned, candidates) {
39
+ const rewrites = [];
40
+ for (const d of orphaned) {
41
+ const files = (d.related_files ?? []).filter(isExactPath);
42
+ if (!files.length)
43
+ continue;
44
+ const matches = candidates.filter((c) => files.every((f) => c.files.includes(f)));
45
+ if (matches.length !== 1)
46
+ continue; // zero or ambiguous: never guess
47
+ rewrites.push({ id: d.id, from: d.commit, to: matches[0].sha });
48
+ }
49
+ return { rewrites, records: [...new Set(rewrites.map((r) => r.id))] };
50
+ }
51
+ /** Whether a queued rewrite is still worth ASKING about: the decision it
52
+ * names still exists, still cites the commit the entry expects to replace (a
53
+ * decision that already moved on would make repairDecisionCommit's own
54
+ * stale-plan bail refuse it), and hasn't since been superseded/rejected —
55
+ * same exclusion as orphanedCommitDecisions, since repairing dead history's
56
+ * provenance isn't worth asking about. Backs the read-only escalation
57
+ * surface only (commitRepairEscalations) — absence-means-not-askable is
58
+ * safe there because it self-heals the moment visibility returns.
59
+ * repair-provenance itself does NOT use this: it reads the full store and
60
+ * may legitimately list (dry-run) or leave queued (apply) an entry this
61
+ * predicate would call not-live, so the escalation surface and the CLI can
62
+ * disagree about the same entry — see deadRewrites and resolvedRewriteIds
63
+ * for the CLI's own, looser-on-purpose reasoning. */
64
+ export function liveRewrites(queued, decisions) {
65
+ const byId = new Map(decisions.map((d) => [d.id, d]));
66
+ return queued.filter((r) => {
67
+ const d = byId.get(r.id);
68
+ return !!d && d.commit === r.from && d.status !== "superseded" && d.status !== "rejected";
69
+ });
70
+ }
71
+ /** Entries a decision has demonstrably outgrown: the decision IS present in
72
+ * `decisions`, and it either moved on from `from` or has since been
73
+ * superseded/rejected. An id this list can't see is deliberately NOT
74
+ * included — absence is a property of the READER (a branch checkout that
75
+ * predates the decision, an unmounted private overlay), not proof the match
76
+ * is stale. This predicate backs a DESTRUCTIVE prune (repair-provenance
77
+ * deletes what it returns from the queue file); repairqueue.ts's own
78
+ * docstring is why that matters — the queue is the one durable record of a
79
+ * match once ORIG_HEAD moves on and the matched-away commit can be gc'd, so
80
+ * deleting an entry on a merely-absent id would destroy it unrecoverably.
81
+ * Contrast liveRewrites, whose absence-means-not-askable rule is safe on
82
+ * the read-only escalation surface, which self-heals once visibility
83
+ * returns.
84
+ *
85
+ * Caveat: "demonstrably" is only as strong as this run's view of
86
+ * `decisions`, which comes from the same git-tracked, branch-dependent
87
+ * files that motivate treating ABSENCE as inconclusive. A decision whose
88
+ * `commit`/`status` genuinely differ between branches (e.g. a repair
89
+ * already applied and committed on one branch, checked out here from a
90
+ * branch that predates it) could still read as "moved on" when it hasn't,
91
+ * from this branch's perspective. Far narrower than the absence case this
92
+ * function exists to fix, and not addressed here. */
93
+ export function deadRewrites(queued, decisions) {
94
+ const byId = new Map(decisions.map((d) => [d.id, d]));
95
+ return queued.filter((r) => {
96
+ const d = byId.get(r.id);
97
+ return !!d && (d.commit !== r.from || d.status === "superseded" || d.status === "rejected");
98
+ });
99
+ }
100
+ /** Among `toApply` (the queued/matched candidates this run is about to act
101
+ * on), the ids repair-provenance may treat as RESOLVED once it's done: the
102
+ * decision is present in `decisions` this run, whether or not
103
+ * repairDecisionCommit actually changed it (a present decision that already
104
+ * moved on is "resolved" too — repairDecisionCommit's own bail refused it,
105
+ * and there is nothing more this run can do about it). An id whose decision
106
+ * is NOT present is never resolved — same reasoning as deadRewrites:
107
+ * absence is the reader's transient view, not proof the match is settled,
108
+ * so it must stay queued for a run where the decision is visible again. */
109
+ export function resolvedRewriteIds(toApply, decisions) {
110
+ const seen = new Set(decisions.map((d) => d.id));
111
+ return new Set(toApply.filter((r) => seen.has(r.id)).map((r) => r.id));
112
+ }
113
+ /** Remove any match whose exact {id, from, to} triple was already tombstoned
114
+ * by an earlier `--drop` — otherwise a later merge that re-derives the
115
+ * identical candidate would re-queue exactly what the human rejected. A
116
+ * match sharing {id, from} but proposing a different `to` is unaffected: it
117
+ * is a different proposal, not the rejected one.
118
+ *
119
+ * Preserves object identity for every surviving entry (a plain filter, never
120
+ * a clone or a rebuild) — repair-provenance's own action relies on this to
121
+ * diff its swept-vs-active queue by reference (`queue.filter(r =>
122
+ * !active.includes(r))`) rather than re-spelling the {id, from, to} key a
123
+ * third time. Do not change this to normalize or reconstruct entries
124
+ * without updating that call site too. */
125
+ export function withoutDropped(rewrites, dropped) {
126
+ if (!dropped.length)
127
+ return [...rewrites];
128
+ const tombstoned = new Set(dropped.map((t) => `${t.id}\0${t.from}\0${t.to}`));
129
+ return rewrites.filter((r) => !tombstoned.has(`${r.id}\0${r.from}\0${r.to}`));
130
+ }
131
+ /** Append newly-dropped {id, from, to} triples to the tombstone list,
132
+ * deduped — same append-only, dedupe-by-key shape as mergeRewrites. */
133
+ export function addDropped(newly, existing) {
134
+ const seen = new Set(existing.map((t) => `${t.id}\0${t.from}\0${t.to}`));
135
+ const additions = newly.filter((t) => !seen.has(`${t.id}\0${t.from}\0${t.to}`));
136
+ return [...existing, ...additions];
137
+ }
138
+ /** Combine a freshly-computed plan's rewrites with anything already queued
139
+ * (src/core/repairqueue.ts) from an earlier detection. A fresh match —
140
+ * computed just now, against the current range — overrides a queued one for
141
+ * the same decision; queued entries no longer reachable are simply not
142
+ * repeated by the fresh scan.
143
+ *
144
+ * Overrides by object identity, targeting exactly the one queued entry
145
+ * firstFor (id) would pick — the same first-match rule --drop applies, and
146
+ * the same identity-not-id targeting the dead-entry prune applies (#53; the
147
+ * prune itself removes every provably-dead entry, not just a first match).
148
+ * A corrupted queue file, a hand edit, or a bug upstream could otherwise
149
+ * carry a SECOND entry sharing that id; overriding by id alone would
150
+ * silently destroy that still-queued sibling too, with no tombstone and no
151
+ * way to recover it, even though it was never the entry that would have
152
+ * been applied. Any such sibling is left queued and untouched.
153
+ *
154
+ * How a survivor resolves: the dead-entry prune (deadRewrites), once
155
+ * --apply has moved the decision past the sibling's `from`; or a --drop
156
+ * whose tombstone matches the sibling's exact {id, from, to} — the same
157
+ * --drop that dropped the fresh entry, when the sibling happens to share
158
+ * its triple (the drop's own re-sweep, withoutDropped, catches it too), a
159
+ * second explicit --drop otherwise. NOT a later fresh detection: by this
160
+ * same first-match rule it always overrides the fresh entry sitting ahead
161
+ * of it, never the sibling. */
162
+ export function mergeRewrites(fresh, queued) {
163
+ const overridden = new Set();
164
+ for (const r of fresh) {
165
+ const first = firstFor(queued, r.id);
166
+ if (first)
167
+ overridden.add(first);
168
+ }
169
+ return [...fresh, ...queued.filter((r) => !overridden.has(r))];
170
+ }
171
+ /** Partition the entries --apply is about to act on by whether their proposed
172
+ * `to` commit actually exists in this repository. `existing` is
173
+ * `commitsExist`'s result over every `to` in `toApply`: `null` means the
174
+ * check itself failed to run (not a git repo, git missing, timeout) and is
175
+ * treated as fail-open, same discipline as drift.ts's own use of
176
+ * commitsExist — nothing is withheld just because the check couldn't run.
177
+ *
178
+ * A corrupted queue file, a hand-edited entry, or a bug upstream could
179
+ * otherwise get a `to` that never resolves to a real commit written
180
+ * straight into a decision's `commit` field and provenance evidence, then
181
+ * auto-committed into shared team memory. `withheld` entries must stay
182
+ * queued (never deleted, never passed to repairDecisionCommit) — the queue
183
+ * file is the one durable record of the match, same reasoning as
184
+ * deadRewrites/resolvedRewriteIds.
185
+ *
186
+ * Both returned arrays preserve object identity (never clones or rebuilds
187
+ * an entry) — the CLI's queue sweep and its "still queued" reporting both
188
+ * key a `Set` off the exact objects in `withheld`, by reference, precisely
189
+ * because a corrupted queue file can carry two entries sharing an id (one
190
+ * resolvable, one not): an id alone can't tell them apart. Do not change
191
+ * this to normalize or reconstruct entries without updating those call
192
+ * sites too — same caveat withoutDropped's own docstring carries. */
193
+ export function withheldForUnresolvableTo(toApply, existing) {
194
+ if (existing === null)
195
+ return { applicable: [...toApply], withheld: [] };
196
+ const applicable = [];
197
+ const withheld = [];
198
+ for (const r of toApply)
199
+ (existing.has(r.to) ? applicable : withheld).push(r);
200
+ return { applicable, withheld };
201
+ }
202
+ /** The one rule for which entry wins when more than one shares a decision id
203
+ * (a corrupted queue file, a hand edit, or a bug upstream): first match, by
204
+ * construction. Every caller goes through here so no two can independently
205
+ * drift on which entry "won" — this file's own duplicate-id queue handling
206
+ * has drifted between call sites three times already (see withoutDropped's,
207
+ * withheldForUnresolvableTo's, and mergeRewrites' own docstrings). */
208
+ export function firstFor(entries, id) {
209
+ return entries.find((r) => r.id === id);
210
+ }
211
+ /** pickRewrite is firstFor scoped to a plan's own rewrites (planCommitRepair
212
+ * itself never produces same-id duplicates, but a plan carrying them isn't
213
+ * ruled out here — see firstFor). repairDecisionCommit uses this to decide
214
+ * what to WRITE; a caller that needs to know which entry WOULD be picked
215
+ * without writing anything (the CLI's --apply summary and queue sweep)
216
+ * calls this same function, so the two can never independently drift on
217
+ * which entry "won". */
218
+ export function pickRewrite(plan, id) {
219
+ return firstFor(plan.rewrites, id);
220
+ }
221
+ /** Pure: rewrite `commit` for one decision, and its matching `commit:<sha>`
222
+ * evidence entry too if one is present (replaceExact is a no-op when the
223
+ * evidence array never cited the old sha) — or return the same reference
224
+ * when the plan doesn't touch it. If the record moved on since the plan was
225
+ * built (its commit no longer equals the plan's `from`), bail entirely
226
+ * rather than applying a now-stale match. */
227
+ export function repairDecisionCommit(d, plan) {
228
+ const mine = pickRewrite(plan, d.id);
229
+ if (!mine || d.commit !== mine.from)
230
+ return d;
231
+ const evidence = replaceExact(d.provenance.evidence, `commit:${mine.from}`, `commit:${mine.to}`);
232
+ return {
233
+ ...d,
234
+ commit: mine.to,
235
+ provenance: { ...d.provenance, evidence: evidence.values },
236
+ };
237
+ }
238
+ //# sourceMappingURL=commitrepair.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Multi-candidate verdict (roadmap addendum, "evaluate 5 solutions"). Given several
3
+ * candidate refs (branches/commits — e.g. N agent-generated solutions to one task),
4
+ * replay each one's diff against the graph via the SAME deterministic merge-verdict
5
+ * (buildCheckReport + verdict) and RANK them: the candidate that fits the architecture
6
+ * best is the one that trips the fewest in-force invariants, reverses no decisions, and
7
+ * adds the least sprawl. No model in the ranking — it's set-intersection over the graph.
8
+ */
9
+ import type { HunchStore } from "../store/hunchStore.js";
10
+ export interface CandidateResult {
11
+ ref: string;
12
+ verdict: "block" | "warn" | "pass";
13
+ blocking: number;
14
+ direct: number;
15
+ near: number;
16
+ vetoes: number;
17
+ redundant: number;
18
+ files: number;
19
+ error?: string;
20
+ }
21
+ export declare function compareCandidates(store: HunchStore, root: string, base: string, candidates: string[]): CandidateResult[];
@@ -0,0 +1,20 @@
1
+ import type { HunchPaths } from "./paths.js";
2
+ /** How firmly the agent lifecycle hook (`hunch hook`) enforces Hunch on edits:
3
+ * off — emit nothing (hook is a no-op).
4
+ * advisory — inject the relevant Hunch slice (decisions/constraints/bugs) as
5
+ * context before the edit. The default: always informs, never blocks.
6
+ * firm — advisory + explicitly flag invariants in the edited file's scope.
7
+ * strict — firm + DENY an edit that hits a BLOCKING invariant (direct or via
8
+ * blast radius), feeding the invariant back as the refusal reason. */
9
+ export type Firmness = "off" | "advisory" | "firm" | "strict";
10
+ export declare const FIRMNESS_LEVELS: readonly Firmness[];
11
+ export declare const DEFAULT_FIRMNESS: Firmness;
12
+ export interface HunchConfig {
13
+ firmness: Firmness;
14
+ }
15
+ export declare function isFirmness(v: unknown): v is Firmness;
16
+ /** Read `.hunch/config.json`. A missing/unparseable file, or an unknown firmness
17
+ * value, falls back to defaults — the hook must NEVER crash an edit over config. */
18
+ export declare function readConfig(paths: HunchPaths): HunchConfig;
19
+ /** Write `.hunch/config.json`, merging `patch` over the current on-disk config. */
20
+ export declare function writeConfig(paths: HunchPaths, patch: Partial<HunchConfig>): HunchConfig;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Intent-conformance (the inversion). Today's guards ask "did this diff touch a guarded
3
+ * file?". This asks the deeper question: "does the code, right now, still SATISFY the
4
+ * intent a decision recorded?" — by compiling that intent into a DETERMINISTIC check over
5
+ * the symbol/dependency graph Hunch already builds. "pay must verify the session" becomes
6
+ * `pay` reaches `verifySession`; if the code drifts so it no longer does, the intent is
7
+ * violated even though no diff is in scope. No model — pure graph reachability.
8
+ *
9
+ * Note: reachability is over the unified dependency graph (call / import / depends-on /
10
+ * contains edges), so `calls` and `imports` both mean "must reach"; edge-type precision is
11
+ * a later refinement. The point this proves: code can be checked AGAINST intent.
12
+ */
13
+ import type { HunchStore } from "../store/hunchStore.js";
14
+ import type { Edge, Symbol as HunchSymbol } from "./types.js";
15
+ export interface ConformanceResult {
16
+ decision: string;
17
+ title: string;
18
+ assert: string;
19
+ subject: string;
20
+ object?: string;
21
+ satisfied: boolean;
22
+ detail: string;
23
+ }
24
+ export type ConformanceGraph = {
25
+ symbols: HunchSymbol[];
26
+ edges: Edge[];
27
+ };
28
+ /** Check every in-force decision's conformance predicates against the CURRENT graph.
29
+ * `.satisfied === false` means the code drifted from the recorded intent. Deterministic.
30
+ * `publicOnly` selects every input at the JSON read boundary so a private decision,
31
+ * symbol, or edge can never influence (or be rendered into) a public CI receipt. */
32
+ export declare function checkConformance(store: HunchStore, opts?: {
33
+ publicOnly?: boolean;
34
+ graph?: ConformanceGraph;
35
+ }): ConformanceResult[];
@@ -0,0 +1,54 @@
1
+ /** Precise, AST-grounded matching for a constraint's content — the primitive behind
2
+ * "this change actually BREAKS the rule" (dec_… content-matched constraints).
3
+ *
4
+ * A constraint can forbid, in precision order:
5
+ * - deps: an external import (matched against the PARSED import set, so a comment
6
+ * or a string literal that merely names the module can't trip it; a
7
+ * submodule import like "lodash/groupBy" is caught by "lodash").
8
+ * - symbols: an identifier added in scoped code (whole-word, comments stripped).
9
+ * - patterns: a line regex (lint-grade last resort; comments stripped, strings kept).
10
+ *
11
+ * Deciding a violation by CONTENT is verifiable per commit, so a content-matched
12
+ * invariant is immune to file-change "staleness" and keeps its teeth across the file's
13
+ * whole life. The same matcher backs the Veto Guard's tripwires (one matcher, audited
14
+ * once) — see HunchStore.matchTripwire. */
15
+ export interface Forbids {
16
+ deps: string[];
17
+ symbols: string[];
18
+ patterns: string[];
19
+ }
20
+ export interface ForbidMatch {
21
+ tier: "dep" | "symbol" | "pattern";
22
+ evidence: string[];
23
+ }
24
+ /** Walk the precision-first ladder against an analyzed diff/edit: dep (parsed import,
25
+ * exact or submodule) > symbol (whole-word identifier in scoped code) > pattern (scoped
26
+ * regex). Returns the highest-precision match, or null. */
27
+ export declare function matchForbids(f: Forbids, addedDeps: Set<string>, scopedAdded: string[]): ForbidMatch | null;
28
+ /** A constraint's effective forbids: its structured `forbids` plus a legacy `--match`
29
+ * regex folded into the pattern tier (back-compat with v0.35). null when it has none. */
30
+ export declare function effectiveForbids(c: {
31
+ forbids?: Forbids | null;
32
+ match?: string | null;
33
+ }): Forbids | null;
34
+ /** The external import module names on a set of raw lines (for the edit-time hook,
35
+ * which sees proposed lines, not a parsed diff). Relative imports are ignored. */
36
+ export declare function importedDeps(lines: string[]): Set<string>;
37
+ /** Best-effort: derive a forbidden DEP from a natural-language rule like "never import
38
+ * lodash" / "don't use the axios package" — so the seamless capture path (a human
39
+ * correction → enforced constraint) mints a PRECISE matcher, not a scope-only rule that
40
+ * goes stale. Conservative: only fires on an explicit import/require verb + a
41
+ * module-shaped token; returns null otherwise (caller falls back to scope-only). */
42
+ export declare function deriveForbids(rule: string, knownDeps?: readonly string[]): Forbids | null;
43
+ /** The enforceable CODE of an added line: a comment carries no invariant, so the lint-grade
44
+ * symbol/pattern tiers must not fire on it (a `// we avoid lodash` note is not a violation).
45
+ * Strips a line comment, an inline block comment, and a comment-only / JSDoc line — but NOT
46
+ * string literals, since an import specifier (`from "lodash"`) is itself a string.
47
+ * Single-pass and line-local, so a multi-line block-comment BODY line (no marker) is NOT
48
+ * stripped: that residual false-positive is why the DEP tier — gated on the PARSED import
49
+ * set, immune to any comment — is the precise path for "never import X". */
50
+ export declare function matchableCode(line: string): string;
51
+ /** Legacy: compile a constraint's `--match` regex defensively (bad regex → inert). */
52
+ export declare function constraintMatcher(pattern?: string | null): RegExp | null;
53
+ /** True iff any added line's CODE trips a single regex (the v0.35 textual path). */
54
+ export declare function contentViolates(re: RegExp | null, addedLines: string[]): boolean;
@@ -0,0 +1,42 @@
1
+ import type { Constraint } from "./types.js";
2
+ export declare function looksLikeCorrection(prompt: string | undefined | null): boolean;
3
+ /** One-line nudge appended to the UserPromptSubmit hook context when a prompt
4
+ * reads like a correction — surfaces the write tool so the rule gets ENFORCED,
5
+ * not merely remembered. Client-agnostic (no Claude-only wording). */
6
+ export declare const CORRECTION_NUDGE: string;
7
+ export interface CorrectionInput {
8
+ /** The invariant in the human's words, e.g. "never call the pay-per-token API here". */
9
+ rule: string;
10
+ /** A file the correction was about — scopes the constraint to it (conservative default). */
11
+ scope_hint_file?: string;
12
+ severity?: "advisory" | "warning" | "blocking";
13
+ /** True only when the rule is genuinely repo-wide; required to scope to "**". */
14
+ applies_to_all?: boolean;
15
+ type?: "security" | "performance" | "correctness" | "architecture" | "compliance";
16
+ rationale?: string;
17
+ /** id of the decision this correction derives from, if any. */
18
+ source_decision?: string;
19
+ /** The repo's real dependency names (package.json). When given, a dep matcher is
20
+ * auto-derived ONLY for a dep that actually exists — so a non-dependency phrasing
21
+ * never silently mints a never-firing rule. */
22
+ knownDeps?: string[];
23
+ /** Repo root, used to relativize an ABSOLUTE `scope_hint_file`. Agents naturally
24
+ * produce absolute paths (edit-tool payloads and MCP roots are absolute), but every
25
+ * consumer matches repo-relative paths — so without this an absolute hint mints a
26
+ * scope that can never match. */
27
+ root?: string;
28
+ /** True when a capture token was CONSUMED for this write — proof a grilling interview
29
+ * preceded it. Determines the TIER, never whether the write lands: an un-vouched
30
+ * correction still records immediately and still surfaces at edit time and in CI.
31
+ * Only the authority to DENY waits for a countersign. */
32
+ vouched?: boolean;
33
+ }
34
+ /**
35
+ * Build the Constraint a correction mints. Pure (caller passes `now`), so the
36
+ * scope/severity policy is testable in isolation. Key safety rule (research
37
+ * risk #2 — the scope footgun): a repo-wide ("**") constraint may only be
38
+ * BLOCKING when the caller explicitly set applies_to_all; otherwise a single
39
+ * mis-scoped correction would deny every edit under strict firmness, so we
40
+ * down-rank it to a warning.
41
+ */
42
+ export declare function buildCorrectionConstraint(input: CorrectionInput, now: string): Constraint;
@@ -0,0 +1,224 @@
1
+ import { type ContractAxisOwnerSource } from "./pipeline.js";
2
+ import { type VerifiedEvidenceMap } from "./evidenceMap.js";
3
+ import { type FileFirstDeclarationDiagnostic, type ProgressiveDeclarationPlan } from "./declarationClusters.js";
4
+ /** The contract-owning layer suggested by issue/reproduction prose. */
5
+ export type CorrectionStage = "schema-emission" | "schema-ingestion" | "presentation" | "constraint-definition" | "runtime-policy";
6
+ export interface CorrectionStageCandidate {
7
+ owner: string;
8
+ stage: CorrectionStage;
9
+ lexical_score: number;
10
+ symbol_overlap: number;
11
+ runtime_declaration: boolean;
12
+ type_scaffolding: boolean;
13
+ default_locale: boolean;
14
+ }
15
+ export interface AdaptiveCorrectionStageCandidate {
16
+ owner: string;
17
+ stage: CorrectionStage;
18
+ score: number;
19
+ lexical_score: number;
20
+ path_overlap: number;
21
+ symbol_overlap: number;
22
+ component_support: number;
23
+ runtime_declaration: boolean;
24
+ invoked_entrance: boolean;
25
+ generic_entrance: boolean;
26
+ type_scaffolding: boolean;
27
+ }
28
+ export interface EvidenceGuidedCorrectionStageCandidate extends AdaptiveCorrectionStageCandidate {
29
+ baseline_rank: number;
30
+ optimized_rank: number;
31
+ evidence: {
32
+ behavior_sensitive_owner: boolean;
33
+ behavior_sensitive_file: boolean;
34
+ target_only_execution: boolean;
35
+ shared_execution: boolean;
36
+ strong_differential_file: boolean;
37
+ };
38
+ }
39
+ export declare const EVIDENCE_GUIDED_SHORTLIST_RULE: "guarded-evidence-bridge-v3";
40
+ export interface CorrectionStageOptimizationReceipt {
41
+ version: 3;
42
+ receipt_id: string;
43
+ rule: typeof EVIDENCE_GUIDED_SHORTLIST_RULE;
44
+ applied: boolean;
45
+ reason: "evidence-reordered" | "already-ranked" | "claim-mismatch" | "probe-unverified" | "transfer-rejected-read-only" | "no-actionable-evidence" | "no-sensitive-declaration-resolved";
46
+ evidence_level: VerifiedEvidenceMap["level"];
47
+ probe_authenticated: boolean;
48
+ claim_bound: boolean;
49
+ requested_limit: number;
50
+ evidence_slots: number;
51
+ evidence_strategy: "behavior-sensitive" | "direct-high-contrast-execution" | "guarded-execution-file-peer" | null;
52
+ selected_execution_ratio: number | null;
53
+ selected_static_rank: number | null;
54
+ baseline_candidates: string[];
55
+ optimized_candidates: string[];
56
+ promoted_candidates: string[];
57
+ displaced_candidates: string[];
58
+ behavior_sensitive_files: string[];
59
+ strong_differential_files: string[];
60
+ exact_owner_enabled: false;
61
+ }
62
+ export interface CorrectionStageDiagnostic {
63
+ stage: CorrectionStage;
64
+ likely_file: string | null;
65
+ candidates: Array<CorrectionStageCandidate | AdaptiveCorrectionStageCandidate | EvidenceGuidedCorrectionStageCandidate>;
66
+ file_first_declaration_clusters: FileFirstDeclarationDiagnostic;
67
+ progressive_inspection: ProgressiveDeclarationPlan;
68
+ exact_owner_enabled: false;
69
+ optimization: CorrectionStageOptimizationReceipt | null;
70
+ calibration: {
71
+ holdout_tasks: 11;
72
+ likely_file_hits: 9;
73
+ top_five_hits: 8;
74
+ };
75
+ cross_repository_transfer: {
76
+ repositories: readonly ["jquense/yup", "sinclairzx81/typebox"];
77
+ holdout_tasks: 16;
78
+ likely_file_hits: 0;
79
+ top_five_hits: 0;
80
+ decision: "rejected";
81
+ };
82
+ adaptive_transfer: {
83
+ repositories: readonly ["arktypeio/arktype", "typestack/class-validator"];
84
+ scorable_tasks: 11;
85
+ likely_file_hits: 8;
86
+ top_five_hits: 9;
87
+ exact_symbol_hits: 7;
88
+ decision: "promoted-diagnostic";
89
+ };
90
+ adaptive_replication: {
91
+ repositories: readonly ["trpc/trpc", "elysiajs/elysia"];
92
+ scorable_tasks: 11;
93
+ likely_file_hits: 4;
94
+ top_five_hits: 5;
95
+ exact_symbol_hits: 4;
96
+ decision: "failed-replication";
97
+ };
98
+ optimization_policy: typeof CORRECTION_OPTIMIZATION_POLICY;
99
+ }
100
+ export declare const CORRECTION_STAGE_CANDIDATE_LIMIT = 5;
101
+ export declare const EVIDENCE_GUIDED_SLOT_LIMIT = 3;
102
+ export declare const EVIDENCE_GUIDED_BASELINE_FLOOR = 2;
103
+ export declare const EXECUTION_GUIDED_SLOT_LIMIT = 1;
104
+ export declare const EXECUTION_GUIDED_BASELINE_FLOOR = 4;
105
+ export declare const EXECUTION_DIRECT_RATIO_MIN = 4;
106
+ export declare const EXECUTION_DIRECT_STATIC_RANK_MAX = 20;
107
+ export declare const EXECUTION_FILE_RATIO_MIN = 2;
108
+ export declare const EXECUTION_FILE_STATIC_RANK_MAX = 10;
109
+ export declare const CORRECTION_STAGE_CALIBRATION: {
110
+ readonly holdout_tasks: 11;
111
+ readonly likely_file_hits: 9;
112
+ readonly top_five_hits: 8;
113
+ };
114
+ export declare const CORRECTION_STAGE_TRANSFER: {
115
+ readonly repositories: readonly ["jquense/yup", "sinclairzx81/typebox"];
116
+ readonly holdout_tasks: 16;
117
+ readonly likely_file_hits: 0;
118
+ readonly top_five_hits: 0;
119
+ readonly decision: "rejected";
120
+ };
121
+ export declare const ADAPTIVE_CORRECTION_STAGE_TRANSFER: {
122
+ readonly repositories: readonly ["arktypeio/arktype", "typestack/class-validator"];
123
+ readonly scorable_tasks: 11;
124
+ readonly likely_file_hits: 8;
125
+ readonly top_five_hits: 9;
126
+ readonly exact_symbol_hits: 7;
127
+ readonly decision: "promoted-diagnostic";
128
+ };
129
+ export declare const ADAPTIVE_CORRECTION_STAGE_REPLICATION: {
130
+ readonly repositories: readonly ["trpc/trpc", "elysiajs/elysia"];
131
+ readonly scorable_tasks: 11;
132
+ readonly likely_file_hits: 4;
133
+ readonly top_five_hits: 5;
134
+ readonly exact_symbol_hits: 4;
135
+ readonly decision: "failed-replication";
136
+ };
137
+ export declare const CORRECTION_OPTIMIZATION_POLICY: {
138
+ readonly active: readonly [{
139
+ readonly mechanism: "repository-adaptive-ranking";
140
+ readonly verdict: "promote-adaptive-diagnostic";
141
+ }, {
142
+ readonly mechanism: "flat-file-anchored-semantic-clusters";
143
+ readonly verdict: "promote-flat-file-anchored-clusters-v3";
144
+ }];
145
+ readonly advisory_only: readonly [{
146
+ readonly mechanism: "static-stage-shortlist";
147
+ readonly verdict: "retain-diagnostic-stage-shortlist";
148
+ }, {
149
+ readonly mechanism: "progressive-inspection-budget";
150
+ readonly verdict: "retain-efficiency-advisory-v4";
151
+ }];
152
+ readonly disabled: readonly [{
153
+ readonly mechanism: "fixed-repository-stage-router";
154
+ readonly verdict: "reject-cross-repository-transfer";
155
+ }, {
156
+ readonly mechanism: "score-gap-confidence";
157
+ readonly verdict: "reject-shortlist-evidence";
158
+ }, {
159
+ readonly mechanism: "cross-view-confidence";
160
+ readonly verdict: "reject-cross-view-evidence";
161
+ }, {
162
+ readonly mechanism: "causal-slot-owner";
163
+ readonly verdict: "reject-causal-slot";
164
+ }, {
165
+ readonly mechanism: "causal-intervention-owner";
166
+ readonly verdict: "reject-causal-intervention-owner";
167
+ }, {
168
+ readonly mechanism: "evidence-guided-reordering";
169
+ readonly verdict: "reject-guarded-evidence-bridge-v3";
170
+ }, {
171
+ readonly mechanism: "product-source-filter";
172
+ readonly verdict: "reject-development-v5-one-loss";
173
+ }, {
174
+ readonly mechanism: "one-hop-relationship-expansion";
175
+ readonly verdict: "reject-development-v5-no-lift";
176
+ }, {
177
+ readonly mechanism: "same-file-frontier-replacement";
178
+ readonly verdict: "reject-development-v5-three-losses";
179
+ }, {
180
+ readonly mechanism: "additive-same-file-frontier";
181
+ readonly verdict: "reject-additive-frontier-v5-no-fresh-rescue";
182
+ }];
183
+ readonly exact_owner_policy: "disabled";
184
+ readonly per_case_confidence: "disabled";
185
+ };
186
+ /** Classify the layer that owns the broken contract, not the public API through
187
+ * which the symptom happened to surface. This is deterministic and read-only. */
188
+ export declare function inferIssueCorrectionStage(issueValue: unknown): CorrectionStage;
189
+ /** Repository paths that commonly implement each correction stage. Exported so
190
+ * safe source collection can prioritize the relevant layer in very large repos. */
191
+ export declare function correctionStagePathPattern(stage: CorrectionStage, issueValue: unknown): RegExp;
192
+ /** Return a stage-constrained declaration ranking. Public APIs invoked by the
193
+ * reproduction are treated as symptom entrances and excluded whenever deeper
194
+ * candidates exist in the selected stage. */
195
+ export declare function rankIssueCorrectionStageCandidates(issueValue: unknown, sources: ContractAxisOwnerSource[]): CorrectionStageCandidate[];
196
+ /** Reserve a bounded portion of a shortlist for declarations proven to affect
197
+ * the same authenticated behavior. File peers are included because the held
198
+ * intervention experiments localized files more reliably than exact owners. */
199
+ export declare function reserveEvidenceGuidedOwners(baselineOwnersValue: string[], rankedOwnersValue: string[], evidenceMap: VerifiedEvidenceMap, requestedLimit?: number): string[];
200
+ export interface GuardedExecutionBridgeSelection {
201
+ owner: string;
202
+ path: string;
203
+ strategy: "direct-high-contrast-execution" | "guarded-execution-file-peer";
204
+ execution_ratio: number;
205
+ static_rank: number;
206
+ }
207
+ /** Combine execution contrast with static plausibility. Files already covered
208
+ * by the baseline are ignored, generic instrumentation files are excluded,
209
+ * and only the final shortlist slot is eligible. Runtime evidence proposes a
210
+ * bounded hypothesis; it never becomes an exact-owner claim. */
211
+ export declare function selectGuardedExecutionBridge(baselineOwnersValue: string[], rankedOwnersValue: string[], evidenceMap: VerifiedEvidenceMap, requestedLimit?: number): GuardedExecutionBridgeSelection | null;
212
+ export declare function reserveExecutionGuidedFileOwner(baselineOwnersValue: string[], rankedOwnersValue: string[], evidenceMap: VerifiedEvidenceMap, requestedLimit?: number): string[];
213
+ /** Repository-adaptive replacement for fixed Zod path routing. It discovers
214
+ * issue vocabulary in this repository's own paths and symbols, adds local
215
+ * component consensus, and removes an invoked facade only when a deeper
216
+ * repository-native candidate is available. */
217
+ export declare function rankIssueAdaptiveCorrectionCandidates(issueValue: unknown, sources: ContractAxisOwnerSource[]): AdaptiveCorrectionStageCandidate[];
218
+ export declare function optimizeIssueCorrectionCandidates(issueValue: unknown, sources: ContractAxisOwnerSource[], evidenceValue: unknown, requestedLimit?: number): {
219
+ candidates: EvidenceGuidedCorrectionStageCandidate[];
220
+ receipt: CorrectionStageOptimizationReceipt;
221
+ evidence_map: VerifiedEvidenceMap;
222
+ };
223
+ export declare function diagnoseIssueCorrectionStage(issueValue: unknown, sources: ContractAxisOwnerSource[], requestedLimit?: number, evidenceValue?: unknown): CorrectionStageDiagnostic;
224
+ export declare function formatCorrectionStageDiagnostic(diagnostic: CorrectionStageDiagnostic): string;