@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,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerIntegrationCommands(program: Command, refreshGrounding: () => string[]): void;
@@ -1,7 +1,7 @@
1
1
  import { findRoot } from "../core/paths.js";
2
2
  import { CAPABILITIES, HARNESSES, inspectIntegrations, integrationHealthFails, formatIntegrationHealth, repairIntegrationPins } from "../integrations/health.js";
3
3
  import { probeIntegration } from "../integrations/probe.js";
4
- export function registerIntegrationCommands(program) {
4
+ export function registerIntegrationCommands(program, refreshGrounding) {
5
5
  const integrations = program.command("integrations").description("Check harness coverage and repair stale repository Hunch pins");
6
6
  integrations.command("check")
7
7
  .description("Fail on configuration drift; optionally require verified capabilities for CI")
@@ -26,11 +26,14 @@ export function registerIntegrationCommands(program) {
26
26
  process.exitCode = 1;
27
27
  });
28
28
  integrations.command("repair-pins")
29
- .description("Align existing exact-version integration pins with package.json; preserves other settings and does not enable hooks")
29
+ .description("Align existing exact-version pins and refresh existing Hunch instructions; preserves other settings and does not enable hooks")
30
30
  .action(() => {
31
31
  const root = findRoot();
32
32
  const files = repairIntegrationPins(root);
33
33
  console.log(files.length ? `Updated ${files.length} integration file(s): ${files.join(", ")}. Reconnect active MCP sessions.` : "Integration pins already aligned.");
34
+ const grounding = refreshGrounding();
35
+ if (grounding.length)
36
+ console.log(`Updated Hunch instructions: ${grounding.join(", ")}. Reconnect the agent to load task reporting instructions.`);
34
37
  const report = inspectIntegrations(root);
35
38
  console.log(formatIntegrationHealth(report));
36
39
  if (integrationHealthFails(report))
@@ -0,0 +1,35 @@
1
+ import type { Invocation } from "../integrations/scaffold.js";
2
+ import { type ProviderResolution } from "../synthesis/provider.js";
3
+ export interface ResolvedInvocation {
4
+ /** Shell command prefix for the git hook (e.g. `node /abs/dist/cli/index.js`). */
5
+ shell: string;
6
+ /** Portable shell command prefix for tracked assistant hook configuration. */
7
+ agentHookShell: string;
8
+ /** Structured command/args for .mcp.json (subcommand appended by the writer). */
9
+ mcp: Invocation;
10
+ }
11
+ export declare function dim(s: string): string;
12
+ /** Portable invocation written into committed MCP/provider configuration.
13
+ * Keep it independently testable so the distribution pin cannot silently
14
+ * regress to npm's moving latest tag. */
15
+ export declare function publishedMcpInvocation(): Invocation;
16
+ /** Render a structured invocation for the host shell. Safe tokens stay bare so
17
+ * PowerShell can execute the first token; paths and other unsafe tokens use
18
+ * JSON string quoting, which is accepted by PowerShell, cmd, and POSIX sh. */
19
+ export declare function shellInvocation(inv: Invocation): string;
20
+ /** The doctor command's synthesis-status line(s) for a resolved provider.
21
+ * Exported for testing — the previous version (a bare provider-name switch,
22
+ * before the resolveSynthesisProvider preference system existed) had zero
23
+ * test coverage, which is how issue #8 (openai-compat misreported as "no
24
+ * assistant CLI found") shipped unnoticed through three review passes. That
25
+ * bug resurfaces here for the same reason: resolution.statuses carries a
26
+ * `subscription` field for the CLI providers but openai-compat's is null (it
27
+ * isn't a subscription), so it must be special-cased explicitly rather than
28
+ * falling through to the "no assistant CLI" branch. */
29
+ export declare function synthesisStatusLines(resolution: ProviderResolution, env: NodeJS.ProcessEnv): string[];
30
+ /** Gate + fetch the Ollama context-window advisory (issue #11): only relevant
31
+ * for the openai-compat provider, so every other provider is a no-op. Kept
32
+ * separate from synthesisStatusLines (sync, already fully covered) because
33
+ * this one makes a best-effort network call. */
34
+ export declare function maybeWarnOllamaContext(providerName: string, env: NodeJS.ProcessEnv): Promise<string | null>;
35
+ export declare function resolveInvocation(): ResolvedInvocation;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { Constraint } from "../core/types.js";
3
+ import { type ReviewMemoryContext } from "./automaticReviewMemory.js";
4
+ export declare function registerReviewMemoryCommands(program: Command, capture: (records: Constraint[], repository: string, privateOnly: boolean) => void, context: (repository: string, privateOnly?: boolean) => ReviewMemoryContext): void;
@@ -0,0 +1,14 @@
1
+ import { type AgentCliWorker } from "../synthesis/cliAdapter.js";
2
+ /** Origin is invocation metadata, never whichever executables happen to be installed. */
3
+ export declare function reviewInitiator(explicit?: string, env?: NodeJS.ProcessEnv): string;
4
+ /** One origin-bound provider. Never fail over into another agent's account. */
5
+ export declare function boundReviewGenerator(worker: AgentCliWorker): {
6
+ name: string;
7
+ providersUsed: () => string[];
8
+ draftProse(prompt: string): Promise<string>;
9
+ };
10
+ export declare function chooseReviewGenerator(root: string, configFile?: string, initiator?: string): Promise<{
11
+ name: string;
12
+ providersUsed: () => string[];
13
+ draftProse(prompt: string): Promise<string>;
14
+ }>;
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerServeCommands(program: Command): void;
@@ -0,0 +1,6 @@
1
+ import type { Command } from "commander";
2
+ import type { HunchStore } from "../store/hunchStore.js";
3
+ export declare function registerTaskReportCommands(program: Command, openStore: () => {
4
+ store: HunchStore;
5
+ root: string;
6
+ }): void;
@@ -0,0 +1,128 @@
1
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
2
+ import { findRoot } from "../core/paths.js";
3
+ import { writeFileAtomic } from "../core/io.js";
4
+ import { finishReportTask, forgetReportTask, listReportTasks, pruneReportHistory, readTaskReport, readLessonHistory, startReportTask } from "../core/taskReport.js";
5
+ import { DEFAULT_CHECK_TIMEOUT_MS, MAX_CHECK_TIMEOUT_MS, reportSourceSnapshot, runReportCheck, runReportConformance } from "../core/taskReportEvidence.js";
6
+ import { renderTaskReport, writeTaskReportHtml } from "../core/taskReportRender.js";
7
+ import { assertReportPath } from "../core/taskReportPaths.js";
8
+ import { publicTaskReport } from "../core/taskReportPublic.js";
9
+ export function registerTaskReportCommands(program, openStore) {
10
+ const task = program.command("task").description("Record an explicit task lifecycle for Hunch contribution reports");
11
+ task.command("start <title>").option("--id <id>", "retry an exact existing task identity")
12
+ .action((title, opts) => console.log(JSON.stringify(startReportTask(findRoot(), title, opts.id), null, 2)));
13
+ task.command("conform <id>").description("Evaluate each delivered lesson's declared rule against the changed files; Hunch computes the verdict, never the agent")
14
+ .action((id) => {
15
+ const { store, root } = openStore();
16
+ try {
17
+ console.log(JSON.stringify(runReportConformance(root, store, id), null, 2));
18
+ }
19
+ finally {
20
+ store.close();
21
+ }
22
+ });
23
+ task.command("finish <id>").option("--interrupted", "record interruption instead of completion")
24
+ .action((id, opts) => {
25
+ const root = findRoot();
26
+ // Rule evaluation is Hunch's own observation; its failure is disclosed by
27
+ // the report's unknowns and never blocks closing the task.
28
+ if (!opts.interrupted) {
29
+ try {
30
+ const opened = openStore();
31
+ try {
32
+ runReportConformance(opened.root, opened.store, id);
33
+ }
34
+ finally {
35
+ opened.store.close();
36
+ }
37
+ }
38
+ catch { /* disclosed as unverified */ }
39
+ }
40
+ finishReportTask(root, id, opts.interrupted ? "interrupted" : "completed");
41
+ console.log(renderTaskReport(readTaskReport(root, id, reportSourceSnapshot(root).hash)));
42
+ });
43
+ task.command("forget <id>").description("Delete this closed task's local observations and generated report; retains project memory")
44
+ .action((id) => { forgetReportTask(findRoot(), id); console.log("Task report history removed; project memory retained."); });
45
+ task.command("prune").description("Delete local report history for tasks closed more than the retention period ago")
46
+ .option("--days <days>", "retention period in days", "90")
47
+ .action((opts) => console.log(`Removed ${pruneReportHistory(findRoot(), Number(opts.days))} expired task report(s).`));
48
+ task.command("presentation <mode>").description("Enable or disable automatic contribution cards; observations and memory remain available")
49
+ .action((mode) => {
50
+ if (mode !== "on" && mode !== "off")
51
+ throw new Error("presentation must be on or off");
52
+ const root = findRoot(), directory = assertReportPath(root, ".hunch"), file = assertReportPath(root, ".hunch", "local.json");
53
+ const existing = existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : {};
54
+ if (!existing || typeof existing !== "object" || Array.isArray(existing))
55
+ throw new Error("local.json must be an object; refusing to replace it");
56
+ mkdirSync(directory, { recursive: true });
57
+ writeFileAtomic(file, JSON.stringify({ ...existing, reportPresentation: mode === "on" }, null, 2) + "\n");
58
+ console.log(`Automatic contribution cards ${mode}; task evidence remains available with hunch report.`);
59
+ });
60
+ task.command("verify <id> <command...>").description("Explicitly run a verification command and retain its result/hash, never raw output; use -- before the command")
61
+ .option("--label <label>", "short name of the check", "Verification command")
62
+ .option("--timeout <seconds>", `seconds before the command tree is stopped and recorded as timed out (max ${MAX_CHECK_TIMEOUT_MS / 1000})`, String(DEFAULT_CHECK_TIMEOUT_MS / 1000))
63
+ .option("--json", "emit only the result JSON, suppressing live command output")
64
+ .action(async (id, command, opts) => {
65
+ const seconds = Number(opts.timeout);
66
+ if (!Number.isInteger(seconds) || seconds < 1 || seconds * 1000 > MAX_CHECK_TIMEOUT_MS)
67
+ throw new Error(`--timeout must be a whole number of seconds between 1 and ${MAX_CHECK_TIMEOUT_MS / 1000}`);
68
+ const controller = new AbortController();
69
+ let signalExit = 0;
70
+ const interrupt = () => { signalExit = 130; controller.abort(); };
71
+ const terminate = () => { signalExit = 143; controller.abort(); };
72
+ process.on("SIGINT", interrupt);
73
+ process.on("SIGTERM", terminate);
74
+ try {
75
+ const result = await runReportCheck(findRoot(), id, command, opts.label, seconds * 1000, {
76
+ signal: controller.signal,
77
+ onStdout: opts.json ? undefined : chunk => { process.stdout.write(chunk); },
78
+ onStderr: opts.json ? undefined : chunk => { process.stderr.write(chunk); },
79
+ });
80
+ console.log(JSON.stringify(result, null, 2));
81
+ if (signalExit || result.exit_code !== 0 || result.timed_out || result.cancelled)
82
+ process.exitCode = signalExit || 1;
83
+ }
84
+ finally {
85
+ process.removeListener("SIGINT", interrupt);
86
+ process.removeListener("SIGTERM", terminate);
87
+ }
88
+ });
89
+ program.command("report [id]").description("Inspect task-scoped memory delivery and independently observed command results")
90
+ .option("--lesson <record-id>", "inspect retained appearances of this exact lesson across tasks")
91
+ .option("--kind <kind>", "record kind for --lesson, for example constraints or decisions")
92
+ .option("--revision <hash>", "restrict lesson history to one exact content hash")
93
+ .option("--before <cursor>", "continue a fully indexed lesson history page")
94
+ .option("--json", "machine-readable report")
95
+ .option("--html", "write a self-contained private/local evidence view under .hunch-cache/reports")
96
+ .option("--public-only", "export only exact revisions present in the public store, omitting task prose and execution details")
97
+ .action((id, opts) => {
98
+ const root = findRoot();
99
+ if (opts.lesson) {
100
+ if (id || opts.html || opts.publicOnly || !opts.kind)
101
+ throw new Error("lesson history requires --kind and cannot combine a task ID, --html or --public-only");
102
+ console.log(JSON.stringify(readLessonHistory(root, { record_id: opts.lesson, kind: opts.kind, content_hash: opts.revision }, { before: opts.before === undefined ? undefined : Number(opts.before) }), null, 2));
103
+ return;
104
+ }
105
+ if (opts.kind || opts.revision || opts.before)
106
+ throw new Error("--kind, --revision and --before require --lesson");
107
+ if (opts.json && opts.html)
108
+ throw new Error("choose --json or --html");
109
+ if (!id) {
110
+ if (opts.html || opts.publicOnly)
111
+ throw new Error("export requires an explicit task ID");
112
+ const tasks = listReportTasks(root);
113
+ console.log(opts.json ? JSON.stringify(tasks, null, 2) : tasks.length ? tasks.map(t => `${t.task_id} · ${t.state} · ${t.title.replace(/[\u0000-\u001f\u007f-\u009f]/g, " ")}`).join("\n") : "No task reports yet. Reconnect the agent after updating Hunch; task lifecycle calls create reports.");
114
+ return;
115
+ }
116
+ if (opts.html) {
117
+ console.log(writeTaskReportHtml(root, id, opts.publicOnly));
118
+ return;
119
+ }
120
+ if (opts.publicOnly) {
121
+ console.log(JSON.stringify(publicTaskReport(root, id), null, 2));
122
+ return;
123
+ }
124
+ const report = readTaskReport(root, id, reportSourceSnapshot(root).hash);
125
+ console.log(opts.json ? JSON.stringify(report, null, 2) : renderTaskReport(report));
126
+ });
127
+ }
128
+ //# sourceMappingURL=taskReport.js.map
@@ -0,0 +1,14 @@
1
+ import type { Command } from "commander";
2
+ type Run = (args: string[], capture?: boolean) => string;
3
+ export interface UpdateOptions {
4
+ global?: boolean;
5
+ dryRun?: boolean;
6
+ }
7
+ /** Arguments come only from fixed commands and a validated registry version.
8
+ * Windows needs the shell to resolve npm.cmd; cwd is never interpolated. */
9
+ export declare function runNpm(root: string, args: string[], capture?: boolean): string;
10
+ /** Fresh child execution is essential: the currently running CLI still has the
11
+ * old modules loaded after npm replaces its installation. */
12
+ export declare function updateHunch(root: string, opts?: UpdateOptions, run?: Run, log?: (line: string) => void): void;
13
+ export declare function registerUpdateCommand(program: Command): void;
14
+ export {};
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Typed client for nuryel.state/1 over HTTP (`hunch serve`). No dependencies beyond fetch.
3
+ * Import from `@davesheffer/hunch/state`. The principal is the bearer token's; the request
4
+ * shapes are the contract's minus `schema` and `principal`.
5
+ */
6
+ import type { ReadRequest, SubscribeRequest, WriteRequest, ChangeEvent, Scope } from "../core/stateContract.js";
7
+ import type { DeliveryEnvelope } from "../core/delivery.js";
8
+ import type { CaptureRequest, CaptureBatchRequest } from "../core/stateContract.js";
9
+ export type ClientReadRequest = Omit<ReadRequest, "schema" | "principal">;
10
+ export type ClientWriteRequest = Omit<WriteRequest, "schema" | "principal" | "expected_version"> & {
11
+ expected_version?: string | number | null;
12
+ };
13
+ export type ClientSubscribeRequest = Omit<SubscribeRequest, "schema" | "principal">;
14
+ export interface ClientSubscribeResponse {
15
+ schema: string;
16
+ scope: Scope;
17
+ head_seq: number;
18
+ events: ChangeEvent[];
19
+ filtered: boolean;
20
+ }
21
+ export interface StateProblem {
22
+ type: string;
23
+ title: string;
24
+ status: number;
25
+ detail: string;
26
+ conflict?: {
27
+ incumbent_id: string;
28
+ reason: string;
29
+ };
30
+ issues?: string[];
31
+ }
32
+ /** A typed refusal from the server: the problem+json body, with `code` = its title. */
33
+ export declare class StateClientError extends Error {
34
+ readonly status: number;
35
+ readonly code: string;
36
+ readonly problem: StateProblem;
37
+ constructor(status: number, code: string, problem: StateProblem);
38
+ }
39
+ export interface StateClientOptions {
40
+ baseUrl: string;
41
+ token: string;
42
+ fetch?: typeof fetch;
43
+ timeoutMs?: number;
44
+ }
45
+ export declare function createStateClient(opts: StateClientOptions): {
46
+ capabilities: (scope?: Scope) => Promise<{
47
+ protocol: string;
48
+ capabilities: string[];
49
+ repository: Scope;
50
+ partitions: Scope["kind"][];
51
+ principal: {
52
+ id: string;
53
+ kind: string;
54
+ grants: Scope[];
55
+ };
56
+ }>;
57
+ read: (request: ClientReadRequest) => Promise<{
58
+ schema: "nuryel.state.read/1";
59
+ receipt_id: string;
60
+ scope: {
61
+ kind: "repository" | "organization" | "team" | "user";
62
+ id: string;
63
+ };
64
+ state_of_record: {
65
+ subject: string;
66
+ current: {
67
+ facet: "decisions" | "constraints" | "bugs" | "findings" | "receipts" | "commitments" | "derived" | "entities" | "relationships";
68
+ id: string;
69
+ record_hash: string;
70
+ scope: {
71
+ kind: "repository" | "organization" | "team" | "user";
72
+ id: string;
73
+ };
74
+ }[];
75
+ in_force: {
76
+ facet: "decisions" | "constraints" | "bugs" | "findings" | "receipts" | "commitments" | "derived" | "entities" | "relationships";
77
+ id: string;
78
+ record_hash: string;
79
+ scope: {
80
+ kind: "repository" | "organization" | "team" | "user";
81
+ id: string;
82
+ };
83
+ }[];
84
+ done: {
85
+ facet: "decisions" | "constraints" | "bugs" | "findings" | "receipts" | "commitments" | "derived" | "entities" | "relationships";
86
+ id: string;
87
+ record_hash: string;
88
+ scope: {
89
+ kind: "repository" | "organization" | "team" | "user";
90
+ id: string;
91
+ };
92
+ }[];
93
+ depends_on: ({
94
+ kind: "record";
95
+ id: string;
96
+ record_hash: string;
97
+ scope?: {
98
+ kind: "repository" | "organization" | "team" | "user";
99
+ id: string;
100
+ } | undefined;
101
+ } | {
102
+ kind: "external";
103
+ ref: {
104
+ system: string;
105
+ object_type: string;
106
+ object_key: string;
107
+ observed_at: string;
108
+ version?: string | undefined;
109
+ content_hash?: string | undefined;
110
+ locator?: string | undefined;
111
+ };
112
+ } | {
113
+ kind: "schema";
114
+ name: string;
115
+ fingerprint: string;
116
+ })[];
117
+ invalidated_by: string[];
118
+ observed?: {
119
+ facet: "decisions" | "constraints" | "bugs" | "findings" | "receipts" | "commitments" | "derived" | "entities" | "relationships";
120
+ id: string;
121
+ record_hash: string;
122
+ scope: {
123
+ kind: "repository" | "organization" | "team" | "user";
124
+ id: string;
125
+ };
126
+ }[] | undefined;
127
+ observed_truncated?: boolean | undefined;
128
+ observed_page?: {
129
+ snapshot_hash: string;
130
+ total: number;
131
+ next_cursor: {
132
+ snapshot_hash: string;
133
+ offset: number;
134
+ } | null;
135
+ } | undefined;
136
+ relationships_truncated?: boolean | undefined;
137
+ } | null;
138
+ denied_scopes: {
139
+ kind: "repository" | "organization" | "team" | "user";
140
+ id: string;
141
+ }[];
142
+ records?: Record<string, Record<string, unknown>> | undefined;
143
+ scopes?: {
144
+ kind: "repository" | "organization" | "team" | "user";
145
+ id: string;
146
+ }[] | undefined;
147
+ receipts?: {
148
+ scope: {
149
+ kind: "repository" | "organization" | "team" | "user";
150
+ id: string;
151
+ };
152
+ receipt_id: string;
153
+ }[] | undefined;
154
+ } & {
155
+ envelope: DeliveryEnvelope;
156
+ }>;
157
+ write: (request: ClientWriteRequest) => Promise<{
158
+ schema: "nuryel.state.write/1";
159
+ record_id: string;
160
+ record_hash: string;
161
+ durability: "committed" | "pushed" | "local";
162
+ outcome: "updated" | "superseded" | "created" | "replayed";
163
+ conflict: {
164
+ incumbent_id: string;
165
+ reason: string;
166
+ } | null;
167
+ record?: Record<string, unknown> | undefined;
168
+ }>;
169
+ capture: (request: Omit<CaptureRequest, "schema" | "principal">) => Promise<{
170
+ schema: "nuryel.state.write/1";
171
+ record_id: string;
172
+ record_hash: string;
173
+ durability: "committed" | "pushed" | "local";
174
+ outcome: "updated" | "superseded" | "created" | "replayed";
175
+ conflict: {
176
+ incumbent_id: string;
177
+ reason: string;
178
+ } | null;
179
+ record?: Record<string, unknown> | undefined;
180
+ }>;
181
+ captureBatch: (request: Omit<CaptureBatchRequest, "schema" | "principal">) => Promise<{
182
+ schema: "nuryel.state.capture-batch/1";
183
+ results: ({
184
+ index: number;
185
+ status: "saved";
186
+ result: {
187
+ schema: "nuryel.state.write/1";
188
+ record_id: string;
189
+ record_hash: string;
190
+ durability: "committed" | "pushed" | "local";
191
+ outcome: "updated" | "superseded" | "created" | "replayed";
192
+ conflict: {
193
+ incumbent_id: string;
194
+ reason: string;
195
+ } | null;
196
+ record?: Record<string, unknown> | undefined;
197
+ };
198
+ } | {
199
+ index: number;
200
+ status: "refused";
201
+ code: string;
202
+ message: string;
203
+ })[];
204
+ reviews?: ({
205
+ index: number;
206
+ status: "saved";
207
+ result: {
208
+ schema: "nuryel.state.write/1";
209
+ record_id: string;
210
+ record_hash: string;
211
+ durability: "committed" | "pushed" | "local";
212
+ outcome: "updated" | "superseded" | "created" | "replayed";
213
+ conflict: {
214
+ incumbent_id: string;
215
+ reason: string;
216
+ } | null;
217
+ record?: Record<string, unknown> | undefined;
218
+ };
219
+ } | {
220
+ index: number;
221
+ status: "refused";
222
+ code: string;
223
+ message: string;
224
+ })[] | undefined;
225
+ }>;
226
+ subscribe: (request: ClientSubscribeRequest) => Promise<ClientSubscribeResponse>;
227
+ records: (request: {
228
+ scope: Scope;
229
+ ids: string[];
230
+ }) => Promise<{
231
+ schema: "nuryel.state.records/1";
232
+ scope: {
233
+ kind: "repository" | "organization" | "team" | "user";
234
+ id: string;
235
+ };
236
+ records: Record<string, Record<string, unknown>>;
237
+ facets: Record<string, "decisions" | "constraints" | "bugs" | "findings" | "receipts" | "commitments" | "derived" | "entities" | "relationships">;
238
+ missing: string[];
239
+ denied: string[];
240
+ }>;
241
+ health: () => Promise<{
242
+ ok: boolean;
243
+ version: string;
244
+ protocol: string;
245
+ partitions: string[];
246
+ }>;
247
+ };
248
+ export type StateClient = ReturnType<typeof createStateClient>;
@@ -0,0 +1,29 @@
1
+ import type { Constraint } from "../core/types.js";
2
+ import type { HunchStore } from "../store/hunchStore.js";
3
+ import type { PolicyRepository } from "./repository.js";
4
+ import { type DataClass, type EvidenceEvent } from "./schema.js";
5
+ export interface LocalEvidenceOptions {
6
+ since?: string;
7
+ maxEvents?: number;
8
+ publicOnly?: boolean;
9
+ privateOnly?: boolean;
10
+ instructions?: boolean;
11
+ importFiles?: string[];
12
+ now?: string;
13
+ }
14
+ export interface LocalEvidenceReport {
15
+ scanned: number;
16
+ eligible: number;
17
+ normalized: number;
18
+ existing: number;
19
+ covered: number;
20
+ uncompilable: number;
21
+ excluded: number;
22
+ events: EvidenceEvent[];
23
+ }
24
+ /** Canonical evidence projection for one captured correction. Materializers may
25
+ * reuse this projection, but ingestion itself remains evidence-only. */
26
+ export declare function correctionEvidenceEvent(root: string, constraint: Constraint, dataClass: DataClass): EvidenceEvent | null;
27
+ /** Normalize existing local Hunch truth into Constitution EvidenceEvents. This
28
+ * adapter never synthesizes intent and never creates or activates a policy. */
29
+ export declare function ingestLocalEvidence(store: HunchStore, root: string, repository: PolicyRepository, opts?: LocalEvidenceOptions): LocalEvidenceReport;
@@ -0,0 +1,3 @@
1
+ import type { G2BehaviorAttestation } from "./g2BehaviorAttestation.js";
2
+ import type { PolicySpec } from "./schema.js";
3
+ export declare function executableBehaviorAttestationError(policy: PolicySpec, currentAttestations: G2BehaviorAttestation[]): string | null;
@@ -0,0 +1,8 @@
1
+ import { type PolicyEvaluation, type PolicySpec } from "./schema.js";
2
+ import { type BehaviorWorkspaceKind } from "./behaviorWorkspace.js";
3
+ export interface BehaviorEvaluationOptions {
4
+ commit?: string;
5
+ selectedName?: string;
6
+ workspace?: BehaviorWorkspaceKind;
7
+ }
8
+ export declare function evaluateExecutableBehaviorPolicy(root: string, policy: PolicySpec, opts?: BehaviorEvaluationOptions): PolicyEvaluation;
@@ -0,0 +1,9 @@
1
+ import type { PolicyRepository } from "./repository.js";
2
+ import { type PolicyProof, type PolicySpec, type ProofPlan } from "./schema.js";
3
+ export declare function createExecutableBehaviorProofPlan(root: string, repository: PolicyRepository, policy: PolicySpec, opts?: {
4
+ now?: string;
5
+ privateOnly?: boolean;
6
+ }): ProofPlan;
7
+ export declare function proveExecutableBehaviorPolicy(root: string, policy: PolicySpec, plan: ProofPlan, opts?: {
8
+ now?: string;
9
+ }): PolicyProof;
@@ -0,0 +1,25 @@
1
+ export type BehaviorWorkspaceKind = "staged" | "working";
2
+ export interface BehaviorWorkspaceMetadata {
3
+ kind: BehaviorWorkspaceKind;
4
+ base_commit: string;
5
+ snapshot_hash: string;
6
+ files: string[];
7
+ }
8
+ interface UntrackedFile {
9
+ file: string;
10
+ content_hash: string;
11
+ mode: number;
12
+ content: Buffer;
13
+ }
14
+ export interface BehaviorWorkspaceSnapshot {
15
+ metadata: BehaviorWorkspaceMetadata;
16
+ patch: Buffer;
17
+ untracked: UntrackedFile[];
18
+ }
19
+ export declare class BehaviorWorkspaceError extends Error {
20
+ readonly code: string;
21
+ constructor(code: string, message: string);
22
+ }
23
+ export declare function captureBehaviorWorkspace(root: string, baseCommit: string, kind: BehaviorWorkspaceKind, env: NodeJS.ProcessEnv): BehaviorWorkspaceSnapshot;
24
+ export declare function applyBehaviorWorkspace(root: string, checkout: string, snapshot: BehaviorWorkspaceSnapshot, env: NodeJS.ProcessEnv): void;
25
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { HunchStore } from "../store/hunchStore.js";
2
+ import type { PolicyRepository } from "./repository.js";
3
+ import { type EvidenceEvent, type PolicySpec } from "./schema.js";
4
+ export interface BootstrapCandidate {
5
+ evidence: EvidenceEvent;
6
+ policy: PolicySpec;
7
+ }
8
+ export interface BootstrapReport {
9
+ scanned: number;
10
+ eligible: number;
11
+ compiled: BootstrapCandidate[];
12
+ covered: number;
13
+ deferred: number;
14
+ uncompilable: number;
15
+ conflicted: number;
16
+ }
17
+ export interface BootstrapOptions {
18
+ since?: string;
19
+ maxCandidates?: number;
20
+ publicOnly?: boolean;
21
+ privateOnly?: boolean;
22
+ history?: boolean;
23
+ now?: string;
24
+ }
25
+ export declare function clampCandidateLimit(value: number | undefined): number;
26
+ export declare function durationCutoff(since: string, now: string): number;
27
+ /** Model-free Phase-2A bootstrap. It accepts only explicit structured evidence,
28
+ * creates an auditable event, compiles at most three new candidates, and never
29
+ * changes lifecycle authority. */
30
+ export declare function bootstrapPolicies(store: HunchStore, root: string, repository: PolicyRepository, opts?: BootstrapOptions): BootstrapReport;
@@ -0,0 +1,15 @@
1
+ import type { PolicyEvaluation, PolicySpec, ProofPlan } from "./schema.js";
2
+ /** Stable, whitespace-free JSON for hashes and cross-client receipts. Arrays retain
3
+ * semantic order; object keys are recursively sorted. */
4
+ export declare function canonicalJson(value: unknown): string;
5
+ export declare function canonicalHash(value: unknown): string;
6
+ /** Proofs bind evaluator semantics, not mutable lifecycle fields such as approval,
7
+ * severity, timestamps, or state. */
8
+ export declare function policySemanticHash(policy: PolicySpec): string;
9
+ export declare function proofPlanContentHash(plan: ProofPlan): string;
10
+ /** A proof rerun is bound to policy semantics, not a mutable lifecycle revision.
11
+ * Live gate receipts keep policy_revision in their own deterministic hash; this
12
+ * projection is only for immutable proof/replay evidence. */
13
+ export declare function proofEvaluationHash(evaluation: PolicyEvaluation): string;
14
+ export declare function policyId(seed: unknown): string;
15
+ export declare function proofId(seed: unknown): string;