@davesheffer/hunch 1.31.0 → 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 (228) hide show
  1. package/README.md +3 -6
  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/client/state.js +2 -0
  18. package/dist/constitution/adapters.d.ts +29 -0
  19. package/dist/constitution/behaviorAttestationBinding.d.ts +3 -0
  20. package/dist/constitution/behaviorEvaluator.d.ts +8 -0
  21. package/dist/constitution/behaviorProof.d.ts +9 -0
  22. package/dist/constitution/behaviorWorkspace.d.ts +25 -0
  23. package/dist/constitution/bootstrap.d.ts +30 -0
  24. package/dist/constitution/canonical.d.ts +15 -0
  25. package/dist/constitution/card.d.ts +58 -0
  26. package/dist/constitution/compiler.d.ts +52 -0
  27. package/dist/constitution/composition.d.ts +10 -0
  28. package/dist/constitution/corpus.d.ts +7 -0
  29. package/dist/constitution/correctionPolicyMaterializer.d.ts +57 -0
  30. package/dist/constitution/delta.d.ts +4 -0
  31. package/dist/constitution/disposition.d.ts +20 -0
  32. package/dist/constitution/evaluator.d.ts +47 -0
  33. package/dist/constitution/experiment.d.ts +466 -0
  34. package/dist/constitution/experimentRunner.d.ts +7 -0
  35. package/dist/constitution/g2.d.ts +209 -0
  36. package/dist/constitution/g2BehaviorAttestation.d.ts +45 -0
  37. package/dist/constitution/g2BehaviorCandidates.d.ts +123 -0
  38. package/dist/constitution/g2BehaviorDependencies.d.ts +83 -0
  39. package/dist/constitution/g2BehaviorMaterialization.d.ts +77 -0
  40. package/dist/constitution/g2BehaviorPolicyMaterializer.d.ts +48 -0
  41. package/dist/constitution/g2CandidateAttestation.d.ts +43 -0
  42. package/dist/constitution/g2Candidates.d.ts +80 -0
  43. package/dist/constitution/g2Drills.d.ts +33 -0
  44. package/dist/constitution/g3.d.ts +311 -0
  45. package/dist/constitution/g3Conformance.d.ts +33 -0
  46. package/dist/constitution/lifecycle.d.ts +25 -0
  47. package/dist/constitution/mutation.d.ts +15 -0
  48. package/dist/constitution/nodeTestEvidence.d.ts +13 -0
  49. package/dist/constitution/plan.d.ts +18 -0
  50. package/dist/constitution/policyRuntime.d.ts +5 -0
  51. package/dist/constitution/proof.d.ts +11 -0
  52. package/dist/constitution/repairPolicies.d.ts +34 -0
  53. package/dist/constitution/replacementFreeGit.d.ts +14 -0
  54. package/dist/constitution/replay.d.ts +40 -0
  55. package/dist/constitution/replayCache.d.ts +14 -0
  56. package/dist/constitution/replayWorker.d.ts +1 -0
  57. package/dist/constitution/repository.d.ts +129 -0
  58. package/dist/constitution/safeCheckout.d.ts +9 -0
  59. package/dist/constitution/schema.d.ts +1763 -0
  60. package/dist/constitution/scorecard.d.ts +219 -0
  61. package/dist/constitution/service.d.ts +398 -0
  62. package/dist/constitution/shadow.d.ts +54 -0
  63. package/dist/constitution/sourceMutation.d.ts +15 -0
  64. package/dist/constitution/staticGraphBaseline.d.ts +13 -0
  65. package/dist/constitution/structural.d.ts +64 -0
  66. package/dist/core/agenthook.d.ts +63 -0
  67. package/dist/core/agenthook.js +1 -0
  68. package/dist/core/automaticReviewMemory.d.ts +60 -0
  69. package/dist/core/autoreview.d.ts +66 -0
  70. package/dist/core/canonicalOrder.d.ts +3 -0
  71. package/dist/core/capturetoken.d.ts +19 -0
  72. package/dist/core/changeIdentity.d.ts +22 -0
  73. package/dist/core/changeProof.d.ts +14 -0
  74. package/dist/core/checkreport.d.ts +140 -0
  75. package/dist/core/commitrepair.d.ts +171 -0
  76. package/dist/core/commitrepair.js +238 -0
  77. package/dist/core/compare.d.ts +21 -0
  78. package/dist/core/config.d.ts +20 -0
  79. package/dist/core/conformance.d.ts +35 -0
  80. package/dist/core/constraintmatch.d.ts +54 -0
  81. package/dist/core/correction.d.ts +42 -0
  82. package/dist/core/correctionStage.d.ts +224 -0
  83. package/dist/core/declarationClusters.d.ts +149 -0
  84. package/dist/core/delivery.d.ts +110 -0
  85. package/dist/core/docanchors.d.ts +32 -0
  86. package/dist/core/docscan.d.ts +26 -0
  87. package/dist/core/drift.d.ts +13 -0
  88. package/dist/core/drift.js +31 -1
  89. package/dist/core/dupdetect.d.ts +43 -0
  90. package/dist/core/escalations.d.ts +129 -0
  91. package/dist/core/escalations.js +165 -0
  92. package/dist/core/events.d.ts +29 -0
  93. package/dist/core/evidenceMap.d.ts +164 -0
  94. package/dist/core/externalImports.d.ts +8 -0
  95. package/dist/core/format.d.ts +13 -0
  96. package/dist/core/glob.d.ts +9 -0
  97. package/dist/core/groundingLag.d.ts +84 -0
  98. package/dist/core/groundingLag.js +16 -2
  99. package/dist/core/groundingMerge.d.ts +15 -0
  100. package/dist/core/groundingMerge.js +95 -0
  101. package/dist/core/hookcache.d.ts +10 -0
  102. package/dist/core/hookpolicy.d.ts +47 -0
  103. package/dist/core/ids.d.ts +36 -0
  104. package/dist/core/importReview.d.ts +30 -0
  105. package/dist/core/io.d.ts +23 -0
  106. package/dist/core/jsonc.d.ts +4 -0
  107. package/dist/core/landscapeAdoption.d.ts +66 -0
  108. package/dist/core/landscapeDelivery.d.ts +76 -0
  109. package/dist/core/memorylog.d.ts +37 -0
  110. package/dist/core/migrate.d.ts +28 -0
  111. package/dist/core/outcomeExperience.d.ts +89 -0
  112. package/dist/core/overlaySafety.d.ts +24 -0
  113. package/dist/core/overlaySafety.js +7 -1
  114. package/dist/core/paths.d.ts +31 -0
  115. package/dist/core/pipeline.d.ts +289 -0
  116. package/dist/core/premises.d.ts +43 -0
  117. package/dist/core/provenance.d.ts +21 -0
  118. package/dist/core/publication.d.ts +54 -0
  119. package/dist/core/refrepair.d.ts +24 -0
  120. package/dist/core/refrepair.js +1 -1
  121. package/dist/core/relativeImports.d.ts +11 -0
  122. package/dist/core/repair.d.ts +44 -0
  123. package/dist/core/repairqueue.d.ts +40 -0
  124. package/dist/core/repairqueue.js +133 -0
  125. package/dist/core/reviewMemory.d.ts +40 -0
  126. package/dist/core/reviewqueue.d.ts +54 -0
  127. package/dist/core/safeRepoFile.d.ts +20 -0
  128. package/dist/core/served.d.ts +57 -0
  129. package/dist/core/served.js +14 -0
  130. package/dist/core/stateContract.d.ts +979 -0
  131. package/dist/core/stateContract.js +87 -4
  132. package/dist/core/stateDelivery.d.ts +78 -0
  133. package/dist/core/stateRecords.d.ts +383 -0
  134. package/dist/core/stateRecords.js +16 -1
  135. package/dist/core/stats.d.ts +88 -0
  136. package/dist/core/strictgate.d.ts +33 -0
  137. package/dist/core/taskReport.d.ts +226 -0
  138. package/dist/core/taskReport.js +514 -0
  139. package/dist/core/taskReportCapture.d.ts +8 -0
  140. package/dist/core/taskReportCapture.js +36 -0
  141. package/dist/core/taskReportEvidence.d.ts +26 -0
  142. package/dist/core/taskReportEvidence.js +268 -0
  143. package/dist/core/taskReportHook.d.ts +20 -0
  144. package/dist/core/taskReportHook.js +76 -0
  145. package/dist/core/taskReportPaths.d.ts +3 -0
  146. package/dist/core/taskReportPaths.js +23 -0
  147. package/dist/core/taskReportPublic.d.ts +31 -0
  148. package/dist/core/taskReportPublic.js +45 -0
  149. package/dist/core/taskReportRender.d.ts +6 -0
  150. package/dist/core/taskReportRender.js +97 -0
  151. package/dist/core/topics.d.ts +73 -0
  152. package/dist/core/types.d.ts +1239 -0
  153. package/dist/core/version.d.ts +10 -0
  154. package/dist/eval/guards.d.ts +45 -0
  155. package/dist/eval/harness.d.ts +58 -0
  156. package/dist/extractors/adrImport.d.ts +59 -0
  157. package/dist/extractors/comments.d.ts +7 -0
  158. package/dist/extractors/correctionSources.d.ts +11 -0
  159. package/dist/extractors/diff.d.ts +40 -0
  160. package/dist/extractors/git.d.ts +304 -0
  161. package/dist/extractors/git.js +208 -20
  162. package/dist/extractors/helm.d.ts +31 -0
  163. package/dist/extractors/indexer.d.ts +55 -0
  164. package/dist/extractors/landscapeDiscovery.d.ts +41 -0
  165. package/dist/extractors/languages.d.ts +77 -0
  166. package/dist/extractors/nativeTreeSitter.d.ts +16 -0
  167. package/dist/extractors/parse.d.ts +54 -0
  168. package/dist/extractors/php.d.ts +26 -0
  169. package/dist/extractors/repoSource.d.ts +53 -0
  170. package/dist/extractors/testreport.d.ts +36 -0
  171. package/dist/integrations/ciAction.d.ts +8 -0
  172. package/dist/integrations/claudeConfig.d.ts +44 -0
  173. package/dist/integrations/claudemd.d.ts +13 -0
  174. package/dist/integrations/claudemd.js +11 -2
  175. package/dist/integrations/gitignore.d.ts +16 -0
  176. package/dist/integrations/gitignore.js +7 -0
  177. package/dist/integrations/health.d.ts +74 -0
  178. package/dist/integrations/hooks.d.ts +41 -0
  179. package/dist/integrations/hooks.js +92 -66
  180. package/dist/integrations/madrExport.d.ts +39 -0
  181. package/dist/integrations/madrManifest.d.ts +69 -0
  182. package/dist/integrations/mergeDriver.d.ts +3 -0
  183. package/dist/integrations/mergeDriver.js +25 -8
  184. package/dist/integrations/probe.d.ts +4 -0
  185. package/dist/integrations/providers.d.ts +103 -0
  186. package/dist/integrations/scaffold.d.ts +29 -0
  187. package/dist/integrations/sync.d.ts +30 -0
  188. package/dist/integrations/sync.js +3 -2
  189. package/dist/integrations/team.d.ts +70 -0
  190. package/dist/integrations/worktree.d.ts +8 -0
  191. package/dist/mcp/roots.d.ts +16 -0
  192. package/dist/mcp/server.d.ts +36 -0
  193. package/dist/mcp/server.js +114 -25
  194. package/dist/mcp/taskReportTools.d.ts +3 -0
  195. package/dist/mcp/taskReportTools.js +106 -0
  196. package/dist/serve/app.d.ts +36 -0
  197. package/dist/serve/app.js +20 -0
  198. package/dist/serve/config.d.ts +100 -0
  199. package/dist/serve/writelock.d.ts +22 -0
  200. package/dist/store/changeLedger.d.ts +132 -0
  201. package/dist/store/changeLedger.js +40 -9
  202. package/dist/store/compact.d.ts +33 -0
  203. package/dist/store/db.d.ts +9 -0
  204. package/dist/store/embedder.d.ts +32 -0
  205. package/dist/store/hunchStore.d.ts +624 -0
  206. package/dist/store/hunchStore.js +13 -5
  207. package/dist/store/jsonStore.d.ts +125 -0
  208. package/dist/store/jsonStore.js +15 -0
  209. package/dist/store/merge.d.ts +39 -0
  210. package/dist/store/privateMigrate.d.ts +24 -0
  211. package/dist/store/replay.d.ts +56 -0
  212. package/dist/store/schema.d.ts +17 -0
  213. package/dist/store/stateBinding.d.ts +145 -0
  214. package/dist/store/stateBinding.js +110 -15
  215. package/dist/store/stateCapture.d.ts +15 -0
  216. package/dist/store/stateCapture.js +145 -0
  217. package/dist/synthesis/cliAdapter.d.ts +22 -0
  218. package/dist/synthesis/initiator.d.ts +13 -0
  219. package/dist/synthesis/provider.d.ts +307 -0
  220. package/dist/synthesis/synthesize.d.ts +117 -0
  221. package/dist/synthesis/tripwires.d.ts +9 -0
  222. package/dist/taskReports.d.ts +76 -0
  223. package/dist/taskReports.js +67 -0
  224. package/dist/wiki/adopt.d.ts +22 -0
  225. package/dist/wiki/graph.d.ts +87 -0
  226. package/dist/wiki/wiki.d.ts +242 -0
  227. package/package.json +6 -5
  228. package/server.json +2 -2
@@ -0,0 +1,289 @@
1
+ export type Firmness = "off" | "advisory" | "firm" | "strict";
2
+ export declare const EXECUTION_OBLIGATION_CATEGORIES: readonly ["evidence", "behavior", "types", "serialization", "compatibility", "other"];
3
+ export type ExecutionObligationCategory = (typeof EXECUTION_OBLIGATION_CATEGORIES)[number];
4
+ export type ExecutionObligationPhase = "before-edit" | "session" | "after-edit";
5
+ export type ExecutionObligationOrigin = "memory" | "episode" | "manual";
6
+ export declare const CONTRACT_AXES: readonly ["runtime", "static", "serialization", "compatibility"];
7
+ export type ContractAxis = (typeof CONTRACT_AXES)[number];
8
+ export interface ExecutionExpectation {
9
+ /** Whether the tool call itself must succeed or fail. */
10
+ success: boolean;
11
+ /** Case-insensitive output markers that must all be present/absent. */
12
+ output_includes?: string[];
13
+ output_excludes?: string[];
14
+ }
15
+ export interface ExecutableProbe {
16
+ id: string;
17
+ origin: ExecutionObligationOrigin;
18
+ category: ExecutionObligationCategory;
19
+ claim: string;
20
+ falsifier: string;
21
+ /** Exact bounded command shown to the agent; Hunch never executes it itself. */
22
+ command: string;
23
+ /** Optional orchestrator materialization; never written or executed by hooks. */
24
+ artifact?: {
25
+ path: string;
26
+ content: string;
27
+ };
28
+ /** OR-of-AND tokens used to recognize the observed command safely. */
29
+ command_alternatives: string[][];
30
+ expected_before: ExecutionExpectation;
31
+ expected_after: ExecutionExpectation;
32
+ }
33
+ export interface ContractAxisAudit {
34
+ /** Axes promised by the supplied after-edit proof plan. */
35
+ required: ContractAxis[];
36
+ /** Axes already exercised by the executable contrast. */
37
+ covered: ContractAxis[];
38
+ /** Required axes not closed by the contrast itself. */
39
+ missing: ContractAxis[];
40
+ }
41
+ export interface ContractAxisProbeClosure extends ContractAxisAudit {
42
+ /** Independently red→green probes selected for uncovered axes. */
43
+ probes: ExecutableProbe[];
44
+ }
45
+ export interface ContractAxisDisclosure {
46
+ category: ExecutionObligationCategory;
47
+ claim: string;
48
+ falsifier: string;
49
+ }
50
+ export interface ContractAxisRiskHint {
51
+ probe_id: string;
52
+ category: ExecutionObligationCategory;
53
+ owner: string;
54
+ }
55
+ export interface ContractAxisOwnerSource {
56
+ path: string;
57
+ content: string;
58
+ }
59
+ export interface ContractAxisOwnerInference {
60
+ hint: ContractAxisRiskHint;
61
+ level: "symbol" | "file";
62
+ anchor: string;
63
+ score: number;
64
+ runner_up_score: number | null;
65
+ }
66
+ export interface ContractAxisOwnerRanking {
67
+ probe_id: string;
68
+ category: ExecutionObligationCategory;
69
+ candidates: Array<{
70
+ owner: string;
71
+ anchor: string;
72
+ score: number;
73
+ }>;
74
+ }
75
+ export interface ImplementationOwnerRanking {
76
+ candidates: Array<{
77
+ owner: string;
78
+ score: number;
79
+ lexical_score: number;
80
+ symbol_disclosed: boolean;
81
+ path_disclosed: boolean;
82
+ }>;
83
+ }
84
+ export interface ImplementationOwnerInference {
85
+ owner: string;
86
+ score: number;
87
+ runner_up_score: number | null;
88
+ symbol_disclosed: boolean;
89
+ path_disclosed: boolean;
90
+ }
91
+ export interface AdaptiveContractAxisProbeClosure extends ContractAxisProbeClosure {
92
+ /** One staged probe: main contrast first, uncovered consumers only once main is green. */
93
+ probe: ExecutableProbe | null;
94
+ /** Design-time consumer contracts, deliberately excluding executable commands. */
95
+ disclosures: ContractAxisDisclosure[];
96
+ }
97
+ export interface ExecutionProbeBinding {
98
+ id: string;
99
+ stage: "baseline" | "validation";
100
+ claim: string;
101
+ falsifier: string;
102
+ command: string;
103
+ }
104
+ /** A bounded, observable proof obligation. `command_alternatives` is OR-of-AND:
105
+ * one alternative selects a check when every token occurs in its command. The
106
+ * separate `expected` predicate decides whether the observed result proves it.
107
+ * Tokens are data, never executable regexes. */
108
+ export interface ExecutionObligation {
109
+ id: string;
110
+ origin: ExecutionObligationOrigin;
111
+ category: ExecutionObligationCategory;
112
+ phase: ExecutionObligationPhase;
113
+ description: string;
114
+ command_alternatives: string[][];
115
+ expected: ExecutionExpectation;
116
+ /** Present when this obligation was compiled from one red→green probe. */
117
+ probe?: ExecutionProbeBinding;
118
+ }
119
+ export interface ExecutionAttempt {
120
+ command: string;
121
+ outcome: "success" | "failure" | "unknown";
122
+ expectation_met: boolean;
123
+ missing_output?: string[];
124
+ forbidden_output?: string[];
125
+ }
126
+ export interface TrackedExecutionObligation extends ExecutionObligation {
127
+ status: "pending" | "satisfied";
128
+ satisfied_by?: string;
129
+ satisfied_at_edit?: number;
130
+ last_attempt?: ExecutionAttempt;
131
+ }
132
+ export interface PipelineState {
133
+ turn: number;
134
+ soulInjected: boolean;
135
+ /** Stop blocks issued THIS turn (reset on every user prompt). */
136
+ blocks: number;
137
+ /** Pre-edit evidence denials THIS turn; bounded separately from Stop. */
138
+ probeBlocks: number;
139
+ /** Domains activated by edited paths, e.g. { backend: true }. */
140
+ domains: Record<string, boolean>;
141
+ editedFiles: string[];
142
+ /** True until a product edit happens, then true only after a verify command. */
143
+ verifyAfterEdit: boolean;
144
+ /** Monotonic product-edit generation; after-edit proofs bind to this value. */
145
+ editGeneration: number;
146
+ /** Specific proofs supplied by memory, an episode, or an orchestrator. */
147
+ obligations: TrackedExecutionObligation[];
148
+ /** Relevant PostToolUse activity observed while a proof plan is armed. */
149
+ proofActivity: number;
150
+ /** Activity index and count for bounded mid-flight reminders. */
151
+ proofReminderActivity: number;
152
+ proofReminders: number;
153
+ }
154
+ export declare const emptyState: () => PipelineState;
155
+ /** Validate untrusted MCP/env episode data. Invalid entries are ignored so the
156
+ * hook's fail-open safety posture remains intact. */
157
+ export declare function normalizeExecutionObligations(value: unknown): ExecutionObligation[];
158
+ /** Validate untrusted probe specs. Probes are declarative data; only the agent
159
+ * sees the bounded command, and ordinary tool hooks observe its result. */
160
+ export declare function normalizeExecutableProbes(value: unknown): ExecutableProbe[];
161
+ /** Infer which contract consumers an immutable executable contrast actually
162
+ * exercises. This is deliberately conservative: static coverage requires both
163
+ * type-shaped source and a typechecking command, while compatibility requires
164
+ * at least one key=value control that stays identical across red and green. */
165
+ export declare function discoverExecutableProbeContractAxes(value: unknown): ContractAxis[];
166
+ /** Compare a contrast with its broader proof plan. This audit is diagnostic:
167
+ * category-labelled regression tests are not proof that an axis is closed. */
168
+ export declare function auditExecutableProbeContractAxes(probeValue: unknown, obligationValue: unknown): ContractAxisAudit;
169
+ /** Promote only independently falsifiable red→green probes for uncovered axes.
170
+ * A passing neighboring test is intentionally ineligible: the V experiment
171
+ * showed that it can resolve every receipt while leaving the claimed static
172
+ * contract wrong. */
173
+ export declare function compileContractAxisProbeClosure(contrastValue: unknown, obligationValue: unknown, candidateValue: unknown): ContractAxisProbeClosure;
174
+ /** Collapse a qualified axis closure into one staged red→green probe. The main
175
+ * contrast runs first on both passes. While it is red, consumer probes are
176
+ * skipped; once it turns green, only then are the independently qualified
177
+ * static/serialization/compatibility commands executed. This keeps the biting
178
+ * closure of W without forcing every baseline into the agent's pre-edit loop. */
179
+ export declare function compileAdaptiveContractAxisProbeClosure(contrastValue: unknown, obligationValue: unknown, candidateValue: unknown): AdaptiveContractAxisProbeClosure;
180
+ /** Compile one author-ranked consumer risk into a bounded design hint. The
181
+ * selected probe must already belong to the independently qualified closure.
182
+ * Commands, claims, and falsifiers are deliberately excluded: this hint names
183
+ * where to leave design room without turning the deferred consumer into work. */
184
+ export declare function compileContractAxisRiskHint(closure: ContractAxisProbeClosure, value: unknown): ContractAxisRiskHint | null;
185
+ /** Infer one bounded risk owner using only qualified probes and pre-edit source
186
+ * text supplied by the caller. Compatibility is ranked ahead of static and
187
+ * serialization because it most often crosses a public-surface owner. Within
188
+ * the chosen probe, public identifiers nominate existing declarations; an
189
+ * explicit package surface in the probe breaks ties without reading future
190
+ * changes. */
191
+ export declare function rankContractAxisRiskOwners(closure: ContractAxisProbeClosure, sourceValue: unknown): ContractAxisOwnerRanking | null;
192
+ export declare function inferContractAxisRiskHint(closure: ContractAxisProbeClosure, sourceValue: unknown): ContractAxisOwnerInference | null;
193
+ /** Rank likely implementation declarations from issue/reproduction prose. This
194
+ * is deliberately separate from contract-axis owner inference: a public API
195
+ * can own a deferred consumer contract while an internal declaration owns the
196
+ * smallest patch. The ranker is deterministic BM25 over bounded pre-edit
197
+ * declaration text, with literal path/symbol disclosure recorded separately. */
198
+ export declare function rankIssueImplementationOwners(issueValue: unknown, sourceValue: unknown, candidateLimit?: number): ImplementationOwnerRanking | null;
199
+ /** Conservative delivery gate for implementation-owner retrieval. Thresholds
200
+ * are intentionally exposed in the result and require an absolute score plus
201
+ * a stable lead; benchmark policy may impose stricter external promotion. */
202
+ export declare function inferIssueImplementationOwner(issueValue: unknown, sourceValue: unknown): ImplementationOwnerInference | null;
203
+ /** Compile one probe into two independently observed receipts. The baseline is
204
+ * eligible only before a product edit; validation is eligible only afterwards. */
205
+ export declare function compileExecutableProbes(value: unknown): ExecutionObligation[];
206
+ /** Add/refresh controller obligations. Replacing an origin lets a newer
207
+ * hunch_context task discard stale memory obligations without disturbing a
208
+ * benchmark episode or a manually supplied plan. */
209
+ export declare function armExecutionObligations(state: PipelineState, input: unknown, options?: {
210
+ replaceOrigin?: ExecutionObligationOrigin;
211
+ }): PipelineState;
212
+ export declare function pendingExecutionObligations(state: PipelineState): TrackedExecutionObligation[];
213
+ export interface BeforeEditProbeVerdict {
214
+ block: boolean;
215
+ state: PipelineState;
216
+ reason?: string;
217
+ }
218
+ /** Before-edit evidence is useful only before implementation. At firm/strict,
219
+ * deny at most two product edits per prompt until all such receipts exist;
220
+ * then fail open so a broken probe or discriminator cannot deadlock the agent. */
221
+ export declare function beforeEditProbeVerdict(state: PipelineState): BeforeEditProbeVerdict;
222
+ export declare function executionObligationBrief(state: PipelineState): string;
223
+ /** Harness/orchestrator injection. Malformed input returns no obligations. */
224
+ export declare function environmentExecutionObligations(value?: string | undefined): ExecutionObligation[];
225
+ /** Harness/orchestrator probe injection. Malformed input returns no probes. */
226
+ export declare function environmentExecutableProbes(value?: string | undefined): ExecutableProbe[];
227
+ /** What counts as verification, per domain. Paths activate a domain; verify
228
+ * patterns are matched against Bash/PowerShell commands run AFTER an edit. */
229
+ export interface DomainProfile {
230
+ paths: RegExp;
231
+ verify: RegExp;
232
+ }
233
+ export declare const DEFAULT_PROFILES: Record<string, DomainProfile>;
234
+ /** Product code = behavior that ships. Docs, hunch's own graph, and .claude
235
+ * config are not gated — editing THIS machinery must never trip it. */
236
+ export declare function isProductPath(p: string): boolean;
237
+ export declare function classifyDomains(path: string, profiles?: Record<string, DomainProfile>): string[];
238
+ /** New user prompt: fresh block budget. */
239
+ export declare function onPrompt(state: PipelineState): PipelineState;
240
+ /** Edit/Write/MultiEdit landed on `path`. */
241
+ export declare function onEdit(state: PipelineState, path: string, profiles?: Record<string, DomainProfile>): PipelineState;
242
+ /** A shell command ran. After an edit, it counts as verification when it is
243
+ * verify-shaped for an active domain, a generic runner (`node --test`,
244
+ * `node -e` assertions), or names an edited file — a bespoke check on the
245
+ * thing you changed is verification, and uncredited real checks are how a
246
+ * gate gets disabled out of annoyance (first live false-negative: an HTML
247
+ * structure assertion via `node -e` was blocked on 2026-07-08). */
248
+ export declare function onCommand(state: PipelineState, command: string, outcome?: {
249
+ status: "success" | "failure" | "unknown";
250
+ output: string;
251
+ }, profiles?: Record<string, DomainProfile>): PipelineState;
252
+ /** A verification-class skill ran (/verify, /code-review) — counts as coverage. */
253
+ export declare function onSkill(state: PipelineState, skill: string): PipelineState;
254
+ export type ProofActivity = {
255
+ kind: "edit";
256
+ } | {
257
+ kind: "command";
258
+ command: string;
259
+ } | {
260
+ kind: "skill";
261
+ };
262
+ export interface ProofCheckpoint {
263
+ state: PipelineState;
264
+ reminder?: string;
265
+ reason?: "evidence-handoff" | "first-edit" | "proof-invalidated" | "falsifier-pivot" | "attempt-mismatch" | "cadence";
266
+ }
267
+ /** Schedule bounded proof reminders while work is still happening. Stop is too
268
+ * late for clients that terminate at a hard turn budget, so the controller also
269
+ * injects checkpoints at the evidence→implementation handoff, after the first
270
+ * product edit, invalidated proof receipts, mismatched proof attempts, and a
271
+ * small activity cadence. */
272
+ export declare function proofCheckpoint(before: PipelineState, after: PipelineState, activity: ProofActivity): ProofCheckpoint;
273
+ export declare const PIPELINE_LOOP: string;
274
+ export declare const UNVERIFIED_NAG = "Hunch pipeline: earlier product edits are still UNVERIFIED \u2014 run the relevant test/build/typecheck before claiming anything about them.";
275
+ export declare function unverifiedNag(state: PipelineState): string;
276
+ /** Stop-gate verdict. Blocks only at firm/strict, only with unverified product
277
+ * edits, and at most twice per turn. */
278
+ export declare function stopVerdict(state: PipelineState, firmness: Firmness): {
279
+ block: false;
280
+ } | {
281
+ block: true;
282
+ reason: string;
283
+ state: PipelineState;
284
+ };
285
+ export declare function pipelineEnabled(): boolean;
286
+ /** Load session state; on ANY problem return a fresh state (never throw). */
287
+ export declare function loadPipelineState(sessionId: string): PipelineState;
288
+ /** Persist session state (best effort — scratch data, single writer). */
289
+ export declare function savePipelineState(sessionId: string, state: PipelineState): void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Premise decay — the doc≠graph / code≠graph family gains a third spoke:
3
+ * WORLD≠graph. A decision's staleness signal today is code drift; but decisions
4
+ * also die when the REASON under them stops being true while the code and docs
5
+ * stay perfectly in sync ("we had no gateway auth", "no ops team yet"). This
6
+ * module evaluates the checkable premises a decision records and turns dead
7
+ * ones into inline escalations.
8
+ *
9
+ * Hard rules (red-teamed by design):
10
+ * - A dead premise NEVER changes authority. Gates keep gating until a human
11
+ * re-attests, supersedes, or retires — a self-relaxing gate is a gate the
12
+ * actor it guards against can disarm by changing the world.
13
+ * - Cannot-evaluate is NEVER "holds" (the fail-open lesson, dec-recorded in
14
+ * v1.10.2): an unevaluable check fails and surfaces, so a typo'd premise
15
+ * reaches a human instead of silently vouching.
16
+ * - Recorded reasons only: the system cannot notice the premise nobody wrote
17
+ * down, so callers must present premises as "conditioned on [these]",
18
+ * never "verified valid".
19
+ *
20
+ * Pure: the clock and the existence probe are injected, so the CLI, drift, and
21
+ * the MCP surfaces share one semantics and tests need no filesystem.
22
+ */
23
+ import type { Decision } from "./types.js";
24
+ import type { Escalation } from "./escalations.js";
25
+ export interface PremiseEnv {
26
+ /** ISO instant "now" (injected — never read the clock here). */
27
+ now: string;
28
+ /** Repo-relative existence probe. */
29
+ exists(relPath: string): boolean;
30
+ }
31
+ export interface PremiseVerdict {
32
+ claim: string;
33
+ holds: boolean;
34
+ reason: string;
35
+ }
36
+ /** Evaluate every recorded premise of one decision. Empty when none recorded. */
37
+ export declare function evaluatePremises(d: Decision, env: PremiseEnv): PremiseVerdict[];
38
+ /** One inline escalation per LIVE decision with ≥1 dead premise — the question
39
+ * a human must answer, framed with its resolution verbs. Rejected alternatives
40
+ * are MENTIONED (count only), never re-litigated into agent context: reopening
41
+ * a settled rejection is a human call, and consistency alone is a valid reason
42
+ * to keep a decision whose original premise died. */
43
+ export declare function premiseEscalations(decisions: readonly Decision[], env: PremiseEnv): Escalation[];
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Provenance and credential-free text — a LEAF module (zod only) so that record
3
+ * schemas registered in the store can import it without pulling in types.ts,
4
+ * which itself imports the store's kind registry. types.ts re-exports everything
5
+ * here, so existing imports keep working unchanged.
6
+ */
7
+ import { z } from "zod";
8
+ /** Where a fact came from and how much to trust it. Confidence tiers (DESIGN §4):
9
+ * inferred < extracted < llm_draft < llm_draft+human_confirmed/derived. */
10
+ export declare const ProvenanceSchema: z.ZodObject<{
11
+ source: z.ZodString;
12
+ confidence: z.ZodNumber;
13
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
14
+ last_verified: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ export type Provenance = z.infer<typeof ProvenanceSchema>;
17
+ export declare const SENSITIVE_METADATA_KEY: RegExp;
18
+ /** Reject credential material while allowing ordinary architecture prose such as
19
+ * "authentication service" or "secrets are managed externally". */
20
+ export declare function isCredentialFreeText(value: string): boolean;
21
+ export declare function isCredentialFreeValue(value: string): boolean;
@@ -0,0 +1,54 @@
1
+ /** Publication safety — what a record would EXPOSE if it lands in the committed store.
2
+ *
3
+ * Context (2026-08-09, 2026-08-11): a capture defaults to the PUBLIC store, and for a
4
+ * default `hunch init` user `.hunch/*.json` is git-tracked, so an unflagged
5
+ * `hunch_record_*` publishes on the next push. Two leaks reached the public tree that
6
+ * way. Nothing inspected what the records SAID.
7
+ *
8
+ * Two tiers, deliberately unequal:
9
+ *
10
+ * - STRUCTURAL hits (machine paths, overlay paths, secret material) are
11
+ * domain-independent — a Windows home directory is a leak in any repository, in any
12
+ * industry. These are safe to enforce in a package other people install.
13
+ * - VOCABULARY hits are corpus-tuned and ship EMPTY. A term list built from one
14
+ * project's strategy prose fires on another project's ordinary engineering writing
15
+ * ("revenue" is a domain noun in a billing system). A repo opts in through
16
+ * `.hunch/publication.json`; the package never presumes.
17
+ *
18
+ * Nothing here throws or blocks. `con_03a0b94b2e` holds the lifecycle hook to
19
+ * fail-open, and a privacy heuristic is a smoke detector, not a proof — it earns a
20
+ * visible line, not a veto. */
21
+ export type SensitivityKind = "machine-path" | "private-overlay-path" | "secret-material" | "market-vocabulary";
22
+ export interface SensitivityHit {
23
+ kind: SensitivityKind;
24
+ /** Which field carried it — "$" for a whole-record structural match. */
25
+ field: string;
26
+ /** Short, quotable proof. Truncated: a hit is a pointer, not a payload. */
27
+ excerpt: string;
28
+ }
29
+ export declare function isStructural(hit: SensitivityHit): boolean;
30
+ export interface ScanOptions {
31
+ /** Opt-in, repo-local vocabulary. Empty means vocabulary scanning is off. */
32
+ vocabulary?: readonly RegExp[];
33
+ }
34
+ /** Read a repo's opt-in term list, merged from two layers:
35
+ * .hunch/publication.json committed, shareable patterns
36
+ * .hunch/publication.local.json gitignored, per-machine patterns
37
+ *
38
+ * The local layer exists because the list itself can be sensitive. A rule that
39
+ * catches a competitor teardown has to NAME competitors, and committing that
40
+ * publishes a watchlist — the exact class of content the scanner is meant to keep
41
+ * out of a public repo. Patterns that would embarrass you if read belong in the
42
+ * local layer; generic ones can ship.
43
+ *
44
+ * Absent file, malformed JSON, or an invalid pattern all degrade to "no vocabulary".
45
+ * A privacy heuristic that crashes a capture is worse than one that stays quiet, and
46
+ * the structural tier — the part that works for everyone — never depends on this. */
47
+ export declare function loadVocabulary(hunchDir: string): RegExp[];
48
+ /** Pure. No IO, no throw. Returns every sensitivity signal in one record. */
49
+ export declare function scanRecord(record: unknown, opts?: ScanOptions): SensitivityHit[];
50
+ /** One line naming what was matched and the exact remedy. The predecessor of this
51
+ * message was a generic "for sensitive content use private:true" nudge, which was
52
+ * present and ignored during both leaks — a warning that does not quote the offending
53
+ * text reads as boilerplate. */
54
+ export declare function publicationWarning(hits: readonly SensitivityHit[]): string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Deterministic repair for a decision's file references.
3
+ *
4
+ * A path may appear both in `related_files` (the scope used by the guards) and in
5
+ * provenance evidence (the audit trail). Updating only one leaves misleading
6
+ * memory behind, so this small helper always changes both together and only on an
7
+ * exact match — never a risky substring rewrite.
8
+ */
9
+ import type { Decision } from "./types.js";
10
+ export interface DecisionReferenceRepair {
11
+ decision: Decision;
12
+ relatedFiles: number;
13
+ evidence: number;
14
+ }
15
+ export declare function replaceExact(values: string[], from: string, to: string): {
16
+ values: string[];
17
+ changed: number;
18
+ };
19
+ /**
20
+ * Return a corrected copy of a decision, or `null` when the source reference is
21
+ * not present. The decision's semantic content and verification timestamp are
22
+ * intentionally preserved: this repairs a locator, it does not re-approve intent.
23
+ */
24
+ export declare function repairDecisionReference(decision: Decision, from: string, to: string): DecisionReferenceRepair | null;
@@ -1,4 +1,4 @@
1
- function replaceExact(values, from, to) {
1
+ export function replaceExact(values, from, to) {
2
2
  let changed = 0;
3
3
  const replaced = values.map((value) => {
4
4
  if (value !== from)
@@ -0,0 +1,11 @@
1
+ /** Candidate source files for one static relative JS/TS import, in the same
2
+ * deterministic precedence order used by the indexer. Bare packages, URLs,
3
+ * absolute paths, and import-map aliases are deliberately unsupported. */
4
+ export declare function relativeImportCandidates(fromFile: string, specifier: string): string[];
5
+ /** Resolve against an exact file set. The first candidate preserves existing
6
+ * indexer compatibility; callers that need ambiguity metadata can inspect the
7
+ * returned matches instead of guessing a different target. */
8
+ export declare function resolveRelativeImport(fromFile: string, specifier: string, availableFiles: Iterable<string>): {
9
+ path: string | null;
10
+ matches: string[];
11
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Self-repair (Phase 5 slice 1): heal memory bindings after a rename/move, with
3
+ * ZERO guessing. Git's own rename detection (`commitChanges`, -M) is the only
4
+ * source of old→new pairs, and only EXACT path matches are rewritten — a glob, a
5
+ * prefix, or anything ambiguous is left alone. Deleted paths stay the drift
6
+ * detector's job (dead refs); this module never touches them.
7
+ *
8
+ * Per §59.5: safe repairs auto-apply in the background and land as a revertable
9
+ * `repair` move on the memory timeline; anything this planner cannot prove safe
10
+ * simply isn't in the plan. Pure — no store, no git, no IO — so it is fully
11
+ * unit-testable; the sync path and `hunch repair` share it.
12
+ */
13
+ import type { Decision, Constraint } from "./types.js";
14
+ export interface RenamePair {
15
+ before: string;
16
+ after: string;
17
+ }
18
+ export interface BindingRewrite {
19
+ kind: "decisions" | "constraints";
20
+ id: string;
21
+ /** which binding field was healed (for the receipt / commit message). */
22
+ field: "related_files" | "tripwire.scope" | "scope";
23
+ from: string;
24
+ to: string;
25
+ }
26
+ export interface RepairPlan {
27
+ rewrites: BindingRewrite[];
28
+ /** record ids touched, deduped — the mutation surface. */
29
+ records: string[];
30
+ }
31
+ /** Extract the rename pairs from a commit's change records (already 1:1 by git -M). */
32
+ export declare function renamesOf(changes: ReadonlyArray<{
33
+ status: string;
34
+ before: string | null;
35
+ after: string | null;
36
+ }>): RenamePair[];
37
+ /** Plan every safe rewrite. Only exact matches against a git-confirmed rename move;
38
+ * live records only (a superseded/retired record's history stays as written). */
39
+ export declare function planRepair(renames: readonly RenamePair[], decisions: readonly Decision[], constraints: readonly Constraint[]): RepairPlan;
40
+ /** Apply a plan's rewrites to one decision (pure — returns the healed copy, or the
41
+ * original reference when nothing in the plan touches it). */
42
+ export declare function repairDecision(d: Decision, plan: RepairPlan): Decision;
43
+ /** Apply a plan's rewrites to one constraint (pure). */
44
+ export declare function repairConstraint(c: Constraint, plan: RepairPlan): Constraint;
@@ -0,0 +1,40 @@
1
+ import { type CommitRewrite, type DroppedRewrite } from "./commitrepair.js";
2
+ /** Tolerant read: a missing or corrupt queue file is treated as empty — this
3
+ * is local scratch state, never a source of truth worth failing loudly over. */
4
+ export declare function readPendingRepairs(root: string): CommitRewrite[];
5
+ export declare function writePendingRepairs(root: string, rewrites: readonly CommitRewrite[]): void;
6
+ /** Tolerant read, same discipline as readPendingRepairs. */
7
+ export declare function readDroppedRepairs(root: string): DroppedRewrite[];
8
+ export declare function writeDroppedRepairs(root: string, dropped: readonly DroppedRewrite[]): void;
9
+ /** The queue as every READ-ONLY consumer should see it: raw entries minus
10
+ * anything a human already rejected via `--drop`, regardless of how a
11
+ * tombstoned entry ended up back in the raw queue file (e.g. the post-merge
12
+ * hook's backgrounded detection racing a `--drop`). A read-time filter, not
13
+ * a mutation — the raw queue file is untouched.
14
+ *
15
+ * `repair-provenance`'s own action is the one exception: it needs the RAW
16
+ * read (via readPendingRepairs) because it diffs raw-vs-swept to report what
17
+ * it cleaned up, and it persists the sweep back to disk. Every other
18
+ * reader — `hunch escalations`, SessionStart orientation, the `hunch_now`
19
+ * and `hunch_escalations` MCP tools — must call this instead, or a
20
+ * tombstoned entry that hasn't yet been swept by a `repair-provenance` run
21
+ * re-surfaces as if the human never answered it. */
22
+ export declare function readActivePendingRepairs(root: string): CommitRewrite[];
23
+ /** The `queued` entries whose proposed `to` doesn't resolve to a real commit
24
+ * in this repository — the same withheldForUnresolvableTo gate
25
+ * `repair-provenance --apply` itself runs before writing, surfaced here so
26
+ * a READ-ONLY consumer (hunch escalations, hunch_now/hunch_escalations,
27
+ * SessionStart orientation) can tell a permanently-stuck entry apart from
28
+ * one `--apply` can still resolve, instead of advertising a
29
+ * `--apply --only <id>` that's guaranteed to no-op forever. `null` from
30
+ * commitsExist (the check itself failed to run) is treated as fail-open —
31
+ * same discipline as the apply path — so nothing is misreported as
32
+ * withheld just because the check couldn't run.
33
+ *
34
+ * Returns the OBJECTS, not their ids, and every caller must pass the exact
35
+ * same `queued` array into both this function and whatever it hands the
36
+ * result to (commitRepairEscalations) — an id-keyed set would collapse a
37
+ * corrupted queue's two same-id entries (one resolvable, one not) into one
38
+ * unit, exactly the identity confusion withheldForUnresolvableTo's own
39
+ * docstring warns about. */
40
+ export declare function withheldRewrites(root: string, queued: readonly CommitRewrite[]): Set<CommitRewrite>;