@davesheffer/hunch 1.31.1 → 1.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +2 -1
  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 +606 -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 +128 -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/hookObservations.d.ts +9 -0
  101. package/dist/core/hookObservations.js +33 -0
  102. package/dist/core/hookcache.d.ts +10 -0
  103. package/dist/core/hookpolicy.d.ts +47 -0
  104. package/dist/core/ids.d.ts +36 -0
  105. package/dist/core/importReview.d.ts +30 -0
  106. package/dist/core/io.d.ts +23 -0
  107. package/dist/core/jsonc.d.ts +4 -0
  108. package/dist/core/landscapeAdoption.d.ts +66 -0
  109. package/dist/core/landscapeDelivery.d.ts +76 -0
  110. package/dist/core/memorylog.d.ts +37 -0
  111. package/dist/core/migrate.d.ts +28 -0
  112. package/dist/core/outcomeExperience.d.ts +89 -0
  113. package/dist/core/overlaySafety.d.ts +24 -0
  114. package/dist/core/overlaySafety.js +7 -1
  115. package/dist/core/paths.d.ts +31 -0
  116. package/dist/core/pipeline.d.ts +289 -0
  117. package/dist/core/premises.d.ts +43 -0
  118. package/dist/core/provenance.d.ts +21 -0
  119. package/dist/core/publication.d.ts +54 -0
  120. package/dist/core/refrepair.d.ts +24 -0
  121. package/dist/core/refrepair.js +1 -1
  122. package/dist/core/relativeImports.d.ts +11 -0
  123. package/dist/core/repair.d.ts +44 -0
  124. package/dist/core/repairqueue.d.ts +40 -0
  125. package/dist/core/repairqueue.js +133 -0
  126. package/dist/core/reviewMemory.d.ts +40 -0
  127. package/dist/core/reviewqueue.d.ts +54 -0
  128. package/dist/core/safeRepoFile.d.ts +20 -0
  129. package/dist/core/served.d.ts +57 -0
  130. package/dist/core/served.js +14 -0
  131. package/dist/core/stateContract.d.ts +979 -0
  132. package/dist/core/stateDelivery.d.ts +78 -0
  133. package/dist/core/stateRecords.d.ts +383 -0
  134. package/dist/core/stats.d.ts +88 -0
  135. package/dist/core/strictgate.d.ts +33 -0
  136. package/dist/core/taskReport.d.ts +226 -0
  137. package/dist/core/taskReport.js +514 -0
  138. package/dist/core/taskReportCapture.d.ts +8 -0
  139. package/dist/core/taskReportCapture.js +36 -0
  140. package/dist/core/taskReportEvidence.d.ts +28 -0
  141. package/dist/core/taskReportEvidence.js +272 -0
  142. package/dist/core/taskReportHook.d.ts +20 -0
  143. package/dist/core/taskReportHook.js +76 -0
  144. package/dist/core/taskReportPaths.d.ts +3 -0
  145. package/dist/core/taskReportPaths.js +23 -0
  146. package/dist/core/taskReportPublic.d.ts +31 -0
  147. package/dist/core/taskReportPublic.js +45 -0
  148. package/dist/core/taskReportRender.d.ts +6 -0
  149. package/dist/core/taskReportRender.js +97 -0
  150. package/dist/core/topics.d.ts +73 -0
  151. package/dist/core/types.d.ts +1239 -0
  152. package/dist/core/version.d.ts +10 -0
  153. package/dist/eval/guards.d.ts +45 -0
  154. package/dist/eval/harness.d.ts +58 -0
  155. package/dist/extractors/adrImport.d.ts +59 -0
  156. package/dist/extractors/comments.d.ts +7 -0
  157. package/dist/extractors/correctionSources.d.ts +11 -0
  158. package/dist/extractors/diff.d.ts +40 -0
  159. package/dist/extractors/git.d.ts +304 -0
  160. package/dist/extractors/git.js +208 -20
  161. package/dist/extractors/helm.d.ts +31 -0
  162. package/dist/extractors/indexer.d.ts +55 -0
  163. package/dist/extractors/landscapeDiscovery.d.ts +41 -0
  164. package/dist/extractors/languages.d.ts +77 -0
  165. package/dist/extractors/nativeTreeSitter.d.ts +16 -0
  166. package/dist/extractors/parse.d.ts +54 -0
  167. package/dist/extractors/php.d.ts +26 -0
  168. package/dist/extractors/repoSource.d.ts +53 -0
  169. package/dist/extractors/testreport.d.ts +36 -0
  170. package/dist/integrations/ciAction.d.ts +8 -0
  171. package/dist/integrations/claudeConfig.d.ts +44 -0
  172. package/dist/integrations/claudemd.d.ts +13 -0
  173. package/dist/integrations/claudemd.js +11 -2
  174. package/dist/integrations/gitignore.d.ts +16 -0
  175. package/dist/integrations/gitignore.js +7 -0
  176. package/dist/integrations/health.d.ts +74 -0
  177. package/dist/integrations/health.js +32 -2
  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 +74 -22
  194. package/dist/mcp/taskReportTools.d.ts +188 -0
  195. package/dist/mcp/taskReportTools.js +147 -0
  196. package/dist/serve/app.d.ts +36 -0
  197. package/dist/serve/config.d.ts +100 -0
  198. package/dist/serve/writelock.d.ts +22 -0
  199. package/dist/store/changeLedger.d.ts +132 -0
  200. package/dist/store/compact.d.ts +33 -0
  201. package/dist/store/db.d.ts +9 -0
  202. package/dist/store/embedder.d.ts +32 -0
  203. package/dist/store/hunchStore.d.ts +624 -0
  204. package/dist/store/hunchStore.js +6 -3
  205. package/dist/store/jsonStore.d.ts +125 -0
  206. package/dist/store/merge.d.ts +39 -0
  207. package/dist/store/privateMigrate.d.ts +24 -0
  208. package/dist/store/replay.d.ts +56 -0
  209. package/dist/store/schema.d.ts +17 -0
  210. package/dist/store/stateBinding.d.ts +145 -0
  211. package/dist/store/stateCapture.d.ts +15 -0
  212. package/dist/synthesis/cliAdapter.d.ts +22 -0
  213. package/dist/synthesis/initiator.d.ts +13 -0
  214. package/dist/synthesis/provider.d.ts +307 -0
  215. package/dist/synthesis/synthesize.d.ts +117 -0
  216. package/dist/synthesis/tripwires.d.ts +9 -0
  217. package/dist/taskReports.d.ts +79 -0
  218. package/dist/taskReports.js +69 -0
  219. package/dist/wiki/adopt.d.ts +22 -0
  220. package/dist/wiki/graph.d.ts +87 -0
  221. package/dist/wiki/wiki.d.ts +242 -0
  222. package/package.json +6 -5
  223. package/server.json +2 -2
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Local-only queue of commit-provenance repairs detected opportunistically
3
+ * (typically by the post-merge hook, src/integrations/hooks.ts) but not yet
4
+ * applied. `.hunch/pending-commit-repairs.json` is gitignored the same way
5
+ * `.hunch/local.json` is — never committed, never pushed. It exists because
6
+ * the opportunistic detection window is narrow: `ORIG_HEAD` gets overwritten
7
+ * by the next merge, and the matched-away commit can eventually be gc'd —
8
+ * queuing the exact {id, from, to} triple here lets a human confirm the match
9
+ * later (`hunch repair-provenance --apply`) without losing it.
10
+ *
11
+ * `.hunch/dropped-commit-repairs.json` is the sibling tombstone file: a human
12
+ * rejecting a queued match via `--drop` records the exact {id, from, to}
13
+ * triple here, durably, so detection re-deriving the identical match on a
14
+ * later merge doesn't re-queue what was already rejected — a genuinely
15
+ * different replacement (`to`) for the same still-orphaned commit is a new
16
+ * proposal and still surfaces (see commitrepair.ts's withoutDropped). Same
17
+ * local-only, gitignored discipline as the queue.
18
+ */
19
+ import { existsSync, readFileSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { writeFileAtomic } from "./io.js";
22
+ import { withoutDropped, withheldForUnresolvableTo } from "./commitrepair.js";
23
+ import { commitsExist } from "../extractors/git.js";
24
+ function queuePath(root) {
25
+ return join(root, ".hunch", "pending-commit-repairs.json");
26
+ }
27
+ function droppedPath(root) {
28
+ return join(root, ".hunch", "dropped-commit-repairs.json");
29
+ }
30
+ function isCommitRewrite(value) {
31
+ if (!value || typeof value !== "object")
32
+ return false;
33
+ const { id, from, to } = value;
34
+ // Non-empty, and to !== from — an empty target is never a useful rewrite,
35
+ // and a no-op entry would apply "successfully" while accomplishing nothing.
36
+ // Deliberately NOT a hex-shape check: from/to are opaque strings elsewhere
37
+ // in this codebase's test fixtures, and repairDecisionCommit's own
38
+ // `d.commit === mine.from` guard already makes a garbage `from` inert (it
39
+ // can never match a real decision). A garbage `to` is caught elsewhere,
40
+ // not here: `hunch repair-provenance --apply` runs commitsExist against
41
+ // every `to` it's actually about to act on (the whole queue, or just the
42
+ // one entry `--only <id>` targets) before repairDecisionCommit ever sees
43
+ // it, and leaves a non-resolving entry queued rather than applying it
44
+ // (withheldForUnresolvableTo, src/core/commitrepair.ts) — with the caveat
45
+ // that commitsExist itself fails OPEN if the check can't run at all (not a
46
+ // git repo, git missing, timeout), same as drift.ts's own use of it. This
47
+ // filter stays shape-only on purpose — the existence check needs a
48
+ // repository to run against, which this read-only queue loader doesn't
49
+ // have.
50
+ return typeof id === "string" && !!id
51
+ && typeof from === "string" && !!from
52
+ && typeof to === "string" && !!to
53
+ && to !== from;
54
+ }
55
+ function isDroppedRewrite(value) {
56
+ if (!value || typeof value !== "object")
57
+ return false;
58
+ const { id, from, to } = value;
59
+ return typeof id === "string" && !!id
60
+ && typeof from === "string" && !!from
61
+ && typeof to === "string" && !!to;
62
+ }
63
+ /** Tolerant read: a missing or corrupt queue file is treated as empty — this
64
+ * is local scratch state, never a source of truth worth failing loudly over. */
65
+ export function readPendingRepairs(root) {
66
+ const path = queuePath(root);
67
+ if (!existsSync(path))
68
+ return [];
69
+ try {
70
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
71
+ return Array.isArray(parsed) ? parsed.filter(isCommitRewrite) : [];
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ }
77
+ export function writePendingRepairs(root, rewrites) {
78
+ writeFileAtomic(queuePath(root), JSON.stringify(rewrites, null, 2) + "\n");
79
+ }
80
+ /** Tolerant read, same discipline as readPendingRepairs. */
81
+ export function readDroppedRepairs(root) {
82
+ const path = droppedPath(root);
83
+ if (!existsSync(path))
84
+ return [];
85
+ try {
86
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
87
+ return Array.isArray(parsed) ? parsed.filter(isDroppedRewrite) : [];
88
+ }
89
+ catch {
90
+ return [];
91
+ }
92
+ }
93
+ export function writeDroppedRepairs(root, dropped) {
94
+ writeFileAtomic(droppedPath(root), JSON.stringify(dropped, null, 2) + "\n");
95
+ }
96
+ /** The queue as every READ-ONLY consumer should see it: raw entries minus
97
+ * anything a human already rejected via `--drop`, regardless of how a
98
+ * tombstoned entry ended up back in the raw queue file (e.g. the post-merge
99
+ * hook's backgrounded detection racing a `--drop`). A read-time filter, not
100
+ * a mutation — the raw queue file is untouched.
101
+ *
102
+ * `repair-provenance`'s own action is the one exception: it needs the RAW
103
+ * read (via readPendingRepairs) because it diffs raw-vs-swept to report what
104
+ * it cleaned up, and it persists the sweep back to disk. Every other
105
+ * reader — `hunch escalations`, SessionStart orientation, the `hunch_now`
106
+ * and `hunch_escalations` MCP tools — must call this instead, or a
107
+ * tombstoned entry that hasn't yet been swept by a `repair-provenance` run
108
+ * re-surfaces as if the human never answered it. */
109
+ export function readActivePendingRepairs(root) {
110
+ return withoutDropped(readPendingRepairs(root), readDroppedRepairs(root));
111
+ }
112
+ /** The `queued` entries whose proposed `to` doesn't resolve to a real commit
113
+ * in this repository — the same withheldForUnresolvableTo gate
114
+ * `repair-provenance --apply` itself runs before writing, surfaced here so
115
+ * a READ-ONLY consumer (hunch escalations, hunch_now/hunch_escalations,
116
+ * SessionStart orientation) can tell a permanently-stuck entry apart from
117
+ * one `--apply` can still resolve, instead of advertising a
118
+ * `--apply --only <id>` that's guaranteed to no-op forever. `null` from
119
+ * commitsExist (the check itself failed to run) is treated as fail-open —
120
+ * same discipline as the apply path — so nothing is misreported as
121
+ * withheld just because the check couldn't run.
122
+ *
123
+ * Returns the OBJECTS, not their ids, and every caller must pass the exact
124
+ * same `queued` array into both this function and whatever it hands the
125
+ * result to (commitRepairEscalations) — an id-keyed set would collapse a
126
+ * corrupted queue's two same-id entries (one resolvable, one not) into one
127
+ * unit, exactly the identity confusion withheldForUnresolvableTo's own
128
+ * docstring warns about. */
129
+ export function withheldRewrites(root, queued) {
130
+ const existing = commitsExist(queued.map((r) => r.to), root);
131
+ return new Set(withheldForUnresolvableTo(queued, existing).withheld);
132
+ }
133
+ //# sourceMappingURL=repairqueue.js.map
@@ -0,0 +1,40 @@
1
+ /** Review text is evidence, never executable instructions or policy authority. */
2
+ import { z } from "zod";
3
+ import type { Constraint } from "./types.js";
4
+ declare const commentSchema: z.ZodObject<{
5
+ id: z.ZodNumber;
6
+ body: z.ZodString;
7
+ path: z.ZodString;
8
+ html_url: z.ZodString;
9
+ commit_id: z.ZodString;
10
+ created_at: z.ZodString;
11
+ updated_at: z.ZodString;
12
+ in_reply_to_id: z.ZodOptional<z.ZodNumber>;
13
+ user: z.ZodObject<{
14
+ login: z.ZodString;
15
+ type: z.ZodEnum<{
16
+ User: "User";
17
+ Bot: "Bot";
18
+ }>;
19
+ }, z.core.$strip>;
20
+ }, z.core.$strip>;
21
+ type Comment = z.infer<typeof commentSchema>;
22
+ export interface ReviewCandidate {
23
+ id: string;
24
+ evidence_hash: string;
25
+ file: string;
26
+ comments: Comment[];
27
+ }
28
+ export interface ReviewPacket {
29
+ schema: "hunch.review-memory/1";
30
+ repository: string;
31
+ authority: "none";
32
+ candidates: ReviewCandidate[];
33
+ excluded_bots: number;
34
+ }
35
+ /** Accept GitHub REST review-comment exports, including gh --paginate --slurp pages. */
36
+ export declare function prepareReviewMemory(repository: string, input: unknown): ReviewPacket;
37
+ export declare function validateReviewPacket(input: unknown): ReviewPacket;
38
+ /** A separate, explicit selection supplies the actual rule and how to check it. */
39
+ export declare function compileReviewRules(packetInput: unknown, selections: unknown, now: string): Constraint[];
40
+ export {};
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Review-queue shaping for `hunch review` (the capture → REVIEW → enforce funnel).
3
+ *
4
+ * Pure, deterministic, no I/O — so it's unit-testable away from the store. Reads the
5
+ * `synth:` telemetry line that syncCommit parks in `provenance.evidence` and splits the
6
+ * drafts into two groups so a reviewer can blast through the easy confirmations and then
7
+ * scrutinize the rest:
8
+ * - READY — the Critic AUDITED the draft and found it well-grounded
9
+ * (source includes "verified" AND grounded >= threshold). Best first.
10
+ * - SCRUTINY — everything else (unverified, low-grounded, verify failed/unavailable).
11
+ * Lowest-confidence first, i.e. worst-first triage (unchanged behavior).
12
+ */
13
+ import type { Decision } from "./types.js";
14
+ /** Parsed view of the `synth:` telemetry line (or {} when absent). */
15
+ export interface SynthInfo {
16
+ provider?: string;
17
+ grounded?: number;
18
+ samples?: number;
19
+ agreement?: number;
20
+ pruned?: number;
21
+ /** "unavailable" | "failed" — present only when verification was requested but didn't apply. */
22
+ verify?: string;
23
+ /** the raw telemetry body (the line minus the "synth:" prefix), for display. */
24
+ raw?: string;
25
+ }
26
+ /** Extract the `synth:` line out of a decision's evidence and parse its `k=v` fields. */
27
+ export declare function parseSynth(evidence: string[] | undefined): SynthInfo;
28
+ /** Grounded-ness at/above which a Critic-verified draft is a "quick yes". */
29
+ export declare const READY_MIN_GROUNDED = 0.7;
30
+ /** Whether a decision is an un-vouched draft still awaiting a human — the ONLY thing
31
+ * the review path surfaces under the auto-trust model.
32
+ *
33
+ * Low confidence NO LONGER makes a draft: captured memory is trusted-advisory the
34
+ * moment it lands (status `accepted`, source `llm_draft`), so it grounds and ranks
35
+ * but never nags. Only a DELIBERATE, not-yet-human-vouched `proposed` record — an
36
+ * explicit roadmap/intent entry a human hasn't confirmed — counts as a review draft.
37
+ * (Enforcement authority is granted INLINE, not by draining a background queue.) */
38
+ export declare function isReviewDraft(d: Decision): boolean;
39
+ export interface ReviewItem {
40
+ d: Decision;
41
+ synth: SynthInfo;
42
+ verified: boolean;
43
+ }
44
+ export interface ReviewQueue {
45
+ ready: ReviewItem[];
46
+ scrutiny: ReviewItem[];
47
+ }
48
+ /** A draft is "ready to confirm" only when the Critic actually audited it (source
49
+ * includes "verified") AND judged it well-grounded. A high confidence number alone
50
+ * is NOT enough — an un-audited draft always needs human eyes. */
51
+ export declare function isReady(d: Decision, synth: SynthInfo, minGrounded?: number): boolean;
52
+ /** Split review drafts into ready-to-confirm (best-grounded first) and needs-scrutiny
53
+ * (lowest-confidence first). A draft is never in both groups. */
54
+ export declare function partitionReview(drafts: Decision[], minGrounded?: number): ReviewQueue;
@@ -0,0 +1,20 @@
1
+ export type RepoFileReader = (file: string) => string | null;
2
+ export type RepoFileBufferReader = (file: string) => Buffer | null;
3
+ /** Automatic repository scans are a convenience boundary, not a license to
4
+ * materialize arbitrarily large tracked blobs in memory. Eight MiB is well
5
+ * above ordinary source-file sizes while keeping one malicious/generated file
6
+ * from becoming an unbounded descriptor read. */
7
+ export declare const MAX_REPO_SOURCE_FILE_BYTES: number;
8
+ export interface RepoFileReaderOptions {
9
+ maxBytes?: number;
10
+ }
11
+ /** Build a no-follow reader for automatic repository scanners. A Git-tracked
12
+ * symlink still appears in `git ls-files`; following it can copy host data into
13
+ * generated memory or reports. This reader accepts only one unchanged regular
14
+ * file beneath the canonical repository root and reads through the descriptor
15
+ * whose identity was checked. */
16
+ export declare function createRepoFileBufferReader(root: string, options?: RepoFileReaderOptions): RepoFileBufferReader;
17
+ /** Text facade for parsers and legacy callers. Security-sensitive identities
18
+ * should hash the raw bytes returned by createRepoFileBufferReader first, since
19
+ * distinct invalid UTF-8 sequences can decode to the same replacement text. */
20
+ export declare function createRepoFileReader(root: string, options?: RepoFileReaderOptions): RepoFileReader;
@@ -0,0 +1,57 @@
1
+ type DatabaseSync = import("node:sqlite").DatabaseSync;
2
+ export type ServedEvent = "served" | "refreshed";
3
+ export interface ServedEntry {
4
+ event: ServedEvent;
5
+ /** decisions | constraints | bugs | findings */
6
+ kind: string;
7
+ record_id: string;
8
+ /** what the delivery grounded: a repo-relative file, or a moment like "(subagent:Explore)" */
9
+ target: string;
10
+ session_id?: string;
11
+ rank?: number;
12
+ delivery_reason?: string;
13
+ provenance_status?: string;
14
+ token_cost?: number;
15
+ delivery_profile?: string;
16
+ ranking_policy?: string;
17
+ }
18
+ export interface ServedRow {
19
+ record_id: string;
20
+ kind: string;
21
+ serves: number;
22
+ refreshes: number;
23
+ last_at: string;
24
+ best_rank: number | null;
25
+ average_token_cost: number | null;
26
+ }
27
+ export interface ServedReceipt {
28
+ at: string;
29
+ session_id: string | null;
30
+ event: ServedEvent;
31
+ kind: string;
32
+ record_id: string;
33
+ target: string;
34
+ rank: number | null;
35
+ delivery_reason: string | null;
36
+ provenance_status: string | null;
37
+ token_cost: number | null;
38
+ delivery_profile: string | null;
39
+ ranking_policy: string | null;
40
+ }
41
+ export interface ServedSummary {
42
+ total: number;
43
+ distinct_records: number;
44
+ distinct_sessions: number;
45
+ first_at: string | null;
46
+ last_at: string | null;
47
+ rows: ServedRow[];
48
+ recent: ServedReceipt[];
49
+ }
50
+ /** Shared observation ledger. Explicit report operations surface failures; only
51
+ * passive delivery/hook callers may degrade to best-effort recording. */
52
+ export declare function withServedDatabase<T>(root: string, run: (db: DatabaseSync) => T): T;
53
+ /** Append delivery receipts. Never throws — a receipt must never cost a delivery. */
54
+ export declare function recordServed(root: string, entries: readonly ServedEntry[]): void;
55
+ /** The ledger, aggregated per record. Never throws; an unreadable ledger reads as empty. */
56
+ export declare function servedSummary(root: string): ServedSummary;
57
+ export {};
@@ -15,6 +15,7 @@
15
15
  import { createRequire } from "node:module";
16
16
  import { mkdirSync } from "node:fs";
17
17
  import { join } from "node:path";
18
+ import { assertReportPath } from "./taskReportPaths.js";
18
19
  /** Load node:sqlite while swallowing ONLY its ExperimentalWarning — the same
19
20
  * discipline as src/store/db.ts: this module rides the hook into every CLI
20
21
  * invocation, and Hunch's stderr reaches humans, hooks, and MCP clients. A
@@ -71,6 +72,7 @@ function openServedDb(root) {
71
72
  const dir = join(root, ".hunch-cache");
72
73
  mkdirSync(dir, { recursive: true });
73
74
  const db = new sqlite.DatabaseSync(join(dir, "served.db"));
75
+ db.exec("PRAGMA busy_timeout = 100");
74
76
  db.exec(`CREATE TABLE IF NOT EXISTS served (
75
77
  at TEXT NOT NULL,
76
78
  session TEXT,
@@ -83,6 +85,18 @@ function openServedDb(root) {
83
85
  ensureReceiptColumns(db);
84
86
  return db;
85
87
  }
88
+ /** Shared observation ledger. Explicit report operations surface failures; only
89
+ * passive delivery/hook callers may degrade to best-effort recording. */
90
+ export function withServedDatabase(root, run) {
91
+ assertReportPath(root, ".hunch-cache", "served.db");
92
+ const db = openServedDb(root);
93
+ try {
94
+ return run(db);
95
+ }
96
+ finally {
97
+ db.close();
98
+ }
99
+ }
86
100
  /** Append delivery receipts. Never throws — a receipt must never cost a delivery. */
87
101
  export function recordServed(root, entries) {
88
102
  if (!entries.length)