@davesheffer/hunch 1.23.3 → 1.25.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.
package/README.md CHANGED
@@ -6,28 +6,20 @@
6
6
  [![GitHub stars](https://img.shields.io/github/stars/davesheffer/hunch?color=2742ff&label=%E2%98%85%20star)](https://github.com/davesheffer/hunch)
7
7
  [![license](https://img.shields.io/npm/l/@davesheffer/hunch?color=2742ff)](LICENSE)
8
8
 
9
- Every new AI coding session can read your code. It cannot automatically see why your team chose
10
- this design, which alternative already failed, what an odd-looking line protects, or how this
11
- repository expects work to be explained and reviewed.
9
+ Every new AI coding session can read your code. It cannot automatically see why your team chose this design, which alternative already failed, what an odd-looking line protects, or how this repository expects work to be explained and reviewed.
12
10
 
13
- That is how settled decisions get reopened, fixed bugs return, and technically plausible changes
14
- arrive feeling foreign to the project.
11
+ That is how settled decisions get reopened, fixed bugs return, and technically plausible changes arrive feeling foreign to the project.
15
12
 
16
- **Hunch is evidence-backed project intelligence for the AI coding tools you already use.** It gives
17
- Claude, Codex, Cursor, Copilot, Windsurf, Antigravity, and other MCP clients the same durable
18
- understanding of your codebase:
13
+ **Hunch is evidence-backed deterministic project intelligence for the AI coding tools you already use.** It gives Claude, Codex, Cursor, Copilot, Windsurf, Antigravity and other MCP clients the same durable understanding of your codebase:
19
14
 
20
15
  - why the code is shaped this way;
21
- - how the repository communicates, reviews, and builds;
16
+ - how the repository communicates, reviews and builds;
22
17
  - what depends on the code about to change; and
23
- - which trusted decisions, fixes, and architectural boundaries the result must preserve.
18
+ - which trusted decisions, fixes and architectural boundaries the result must preserve.
24
19
 
25
- For precise rules your team has explicitly trusted, the promise is **Never Twice**: an agent may
26
- propose a different direction, but it cannot quietly re-make a decided decision or re-introduce a
27
- fixed failure without Hunch surfacing the conflict and its evidence.
20
+ For precise rules your team has explicitly trusted, the promise is **Never Twice**: an agent may propose a different direction, but it cannot quietly re-make a decided decision or re-introduce a fixed failure without Hunch surfacing the conflict and its evidence.
28
21
 
29
- Memory starts advisory. Nothing blocks until a human deliberately trusts a precise rule and opts
30
- into strict enforcement.
22
+ Memory starts advisory. Nothing blocks until a human deliberately trusts a precise rule and opts into strict enforcement.
31
23
 
32
24
  ## Start in five minutes
33
25
 
@@ -44,12 +36,19 @@ Reload your coding assistant, then ask a normal question:
44
36
 
45
37
  > Why is this built this way?
46
38
 
47
- `hunch init` indexes the repository, installs local lifecycle hooks, and connects supported
48
- assistants without replacing their existing configuration. The next session receives the relevant
49
- story with its sources, not a giant transcript or a generic prompt wall. Lifecycle coverage
50
- depends on the harness; MCP connectivity alone does not establish automatic grounding or enforcement.
39
+ `hunch init` indexes the repository, installs local lifecycle hooks and connects supported assistants without replacing their existing configuration. The next session receives the relevant story with its sources, not a giant transcript or generic prompt wall.
51
40
 
52
- Check the repository's integrations after upgrading Hunch or switching assistants:
41
+ Lifecycle coverage depends on the harness; MCP connectivity alone does not establish automatic grounding or enforcement.
42
+
43
+ To update Hunch and configured harness pins for the current repository:
44
+
45
+ ```sh
46
+ hunch update
47
+ ```
48
+
49
+ Agents receive an instruction to run this when you ask **“update Hunch”** in generated Hunch guidance. Restart active harnesses afterward.
50
+
51
+ Check integrations after upgrading Hunch or switching assistants:
53
52
 
54
53
  ```sh
55
54
  hunch integrations check
@@ -58,25 +57,11 @@ hunch integrations check --harness claude --probe --require mcp
58
57
  hunch integrations check --harness codex --require context,edit-blocking
59
58
  ```
60
59
 
61
- `check` exits nonzero on stale pins, malformed configuration, or missing expected hooks.
62
- `repair-pins` aligns existing exact npm pins with the exact Hunch dependency in `package.json`
63
- (or the running Hunch version when no dependency is declared). It preserves other settings,
64
- refuses ambiguous/custom TOML and malformed files, and does not enable enforcement.
65
- Reconnect active MCP sessions after repairing pins.
66
-
67
- Capabilities are reported as **verified**, **advisory-only**, **unsupported**, or **untested**.
68
- `--require` fails unless every named capability is verified. The Codex example currently fails:
69
- Hunch's Codex integration supplies MCP and instructions, with no native lifecycle adapter.
70
- The opt-in `--probe` starts the selected generated npm launcher, checks the server version,
71
- and reads memory; it may download the pinned package. It verifies a fresh MCP process only,
72
- not the existing host session, hook delivery, or whether a model follows the memory.
73
- Custom launchers and environment overrides require host-side verification.
74
-
75
- `doctor` includes this report, and session hooks with a context channel surface configuration
76
- problems. Checks cover repository-local configurations; global/managed overrides remain
77
- outside this inspection. Use `hunch integrations check` in CI to prevent pin drift; add
78
- `--require` for capabilities your workflow cannot operate without. Hook failure remains
79
- non-blocking; this explicit CI/preflight gate fails closed on unmet requirements.
60
+ Capabilities are reported as **verified**, **advisory-only**, **unsupported** or **untested**. `--require` fails unless every named capability is verified.
61
+
62
+ The Codex integration currently supplies MCP and instructions, with no native lifecycle adapter. The opt-in `--probe` verifies a fresh MCP process, not whether an existing host session or model actually followed the memory.
63
+
64
+ Use `hunch integrations check` in CI to prevent pin drift; add `--require` for capabilities your workflow cannot operate without.
80
65
 
81
66
  ## One evidence loop, not another model
82
67
 
@@ -98,37 +83,29 @@ Git history + ADRs + corrections + tests + repository conventions
98
83
  deterministic change receipt
99
84
  ```
100
85
 
101
- Hunch is not an agent, orchestrator, or hosted knowledge service. It is the durable reasoning and
102
- validation layer behind the tools that write the code.
86
+ Hunch is not the agent and is not the workflow engine. The model thinks; Hunch holds deterministic, evidence-backed state about the project and validates what must remain true.
103
87
 
104
88
  ## What Hunch understands
105
89
 
106
90
  | Layer | What it adds |
107
91
  | --- | --- |
108
- | **Engineering Memory** | Decisions, rejected alternatives, corrections, bug lineage, findings, and the rationale a future session would otherwise miss. |
109
- | **Code Graph** | Symbols, calls, imports, dependencies, components, blast radius, and architectural reachability across TypeScript, JavaScript, Python, Go, PHP, YAML, and Helm. Memory itself works with any language. |
110
- | **Project DNA** | Revision-specific, evidence-backed observations about how a repository communicates and works: vocabulary, contribution habits, review expectations, engineering conventions, and culture. |
111
- | **Engineering Landscape** | Human-reviewed links from product and capability to system, repository, service, interface, data, delivery resources, runbooks, ownership, dashboards, and SLOs. |
112
- | **Validated Delivery** | The smallest relevant evidence for the current builder, reviewer, or architect, with provenance, currentness, omissions, authority, and a content-addressed receipt. |
113
- | **Native Change Proof** | A sealed exact-change artifact binding revisions, DNA, base/result graphs, memory, blast radius, conformance, guard verdict, and explicit gaps without granting workflow authority. |
114
- | **Change Gate + Constitution** | Deterministic checks for trusted constraints and architectural intent. Policies are compiled, proved, inspected, and explicitly activated by a human—never promoted by an agent in the background. |
92
+ | **Engineering Memory** | Decisions, rejected alternatives, corrections, bug lineage, findings and rationale a future session would otherwise miss. |
93
+ | **Code Graph** | Symbols, calls, imports, dependencies, components, blast radius and architectural reachability across supported languages/configuration. Memory itself works with any language. |
94
+ | **Project DNA** | Revision-specific, evidence-backed observations about how a repository communicates and works: vocabulary, contribution habits, review expectations, engineering conventions and culture. |
95
+ | **Engineering Landscape** | Durable links from product/capability to system, repository, service, interface, data, delivery resources, runbooks, ownership, dashboards and SLOs. |
96
+ | **Validated Delivery** | The smallest relevant evidence for the current builder/reviewer/architect, with provenance, currentness, omissions, authority and a content-addressed receipt. |
97
+ | **Native Change Proof** | A sealed exact-change artifact binding revisions, DNA, base/result graphs, memory, blast radius, conformance, guard verdict and explicit gaps without granting workflow authority. |
98
+ | **Change Gate + Constitution** | Deterministic checks for trusted constraints and architectural intent. Policies are compiled, proved, inspected and explicitly activated by a human. |
115
99
 
116
- Readable JSON in `.hunch/` is the source of truth. SQLite is a fast, rebuildable projection. Git
117
- keeps the memory portable, reviewable, and reversible.
100
+ Readable JSON in `.hunch/` is the repository-scoped source of truth. SQLite is a fast, rebuildable projection. Git keeps the state portable, reviewable and reversible.
118
101
 
119
102
  ## Project DNA: help the agent work like it belongs here
120
103
 
121
- Project DNA is Hunch's evidence-bound model of **how a repository communicates and works**. It is
122
- not a persona, does not impersonate a maintainer, and does not turn frequent behavior into policy.
104
+ Project DNA is Hunch's evidence-bound model of **how a repository communicates and works**. It is not a persona, does not impersonate a maintainer and does not turn frequent behavior into policy.
123
105
 
124
- The deterministic baseline reads an exact Git revision, bounded commit history, and committed
125
- convention files. The current release can also accept bounded, caller-authorized pull-request and
126
- review evidence. Every evidence batch is validated and sealed; raw collaboration text does not
127
- enter the profile.
106
+ The deterministic baseline reads an exact Git revision, bounded commit history and committed convention files. The current release can also accept bounded, caller-authorized pull-request/review evidence. Every evidence batch is validated and sealed; raw collaboration text does not enter the profile.
128
107
 
129
- Each trait keeps its category, confidence, freshness, repository revision, and evidence hash. Hunch
130
- can then include only the relevant DNA in normal context, explain how well a commit, PR, issue, or
131
- message matches repository conventions, and show how the profile changed between two revisions.
108
+ Each trait keeps its category, confidence, freshness, repository revision and evidence hash. Hunch can include only the relevant DNA in normal context, explain how an artifact matches repository conventions and show profile change between revisions.
132
109
 
133
110
  ```bash
134
111
  hunch dna inspect
@@ -136,32 +113,27 @@ hunch dna context
136
113
  hunch dna diff <older-ref> <newer-ref>
137
114
  ```
138
115
 
139
- DNA may shape orientation, terminology, and advisory Project Match checks. It cannot create or
140
- override a decision, constraint, finding, conformance rule, policy, or permission.
116
+ DNA may shape orientation, terminology and advisory Project Match checks. It cannot create or override a decision, constraint, finding, conformance rule, policy or permission.
141
117
 
142
- Read the [Project DNA contract](docs/project-dna.md) and the broader
143
- [Project DNA vision](docs/project-dna-engine.md).
118
+ Read the [Project DNA contract](docs/project-dna.md) and broader [Project DNA vision](docs/project-dna-engine.md).
144
119
 
145
120
  ## Day-to-day
146
121
 
147
- Most capture happens around normal commits and test failures. These commands cover the common
148
- manual paths:
149
-
150
122
  | Command | Use it for |
151
123
  | --- | --- |
152
- | `hunch context "<task>" --profile builder` | Get a bounded builder, reviewer, or architect brief before work starts |
153
- | `hunch why <file-or-symbol>` | See the decisions, bugs, constraints, and blast radius behind code |
154
- | `hunch structure [target]` | Inspect the indexed repository shape without repeated search rounds |
124
+ | `hunch context "<task>" --profile builder` | Get a bounded builder/reviewer/architect brief before work starts |
125
+ | `hunch why <file-or-symbol>` | See decisions, bugs, constraints and blast radius behind code |
126
+ | `hunch structure [target]` | Inspect indexed repository shape without repeated search rounds |
155
127
  | `hunch findings [scope]` | Inherit known-but-unfixed gaps instead of rediscovering them |
156
128
  | `hunch check --working` | Review the current tree against trusted project rules |
157
129
  | `hunch conform` | Prove the code still satisfies recorded architectural intent |
158
130
  | `hunch impact origin/main` | See the dependency and memory surface of a branch |
159
- | `hunch compare branch-a branch-b` | Rank candidate changes by the fewest invariant and decision conflicts |
131
+ | `hunch compare branch-a branch-b` | Rank candidate changes by invariant/decision conflicts |
160
132
  | `hunch prove origin/main --public-only` | Produce a publication-safe `hunch.change-proof/1` artifact for an exact committed change |
161
133
  | `hunch landscape review` | Inspect a hash-bound repository landscape without writing authority |
162
- | `hunch now` | See recent memory and the live decision-backed roadmap |
163
- | `hunch escalations` | See the rare questions that genuinely require a human answer |
164
- | `hunch doctor` | Diagnose setup, provider, index, or overlay problems |
134
+ | `hunch now` | See recent memory and live decision-backed roadmap |
135
+ | `hunch escalations` | See questions that genuinely require a human answer |
136
+ | `hunch doctor` | Diagnose setup, provider, index or overlay problems |
165
137
 
166
138
  When you are ready for deterministic enforcement:
167
139
 
@@ -170,45 +142,70 @@ hunch firmness strict
170
142
  hunch check --staged --strict
171
143
  ```
172
144
 
173
- That is the one moment of teeth. Captured memory cannot silently hard-block on its own.
145
+ Captured memory cannot silently hard-block on its own.
174
146
 
175
- ## What changed after v1.19
147
+ ## Deterministic organizational state — next product direction
148
+
149
+ Repository memory solves one version of a larger problem.
150
+
151
+ As organizations give every employee an agent that can work across CRM, email, messaging, repositories and other tools, the agents become probabilistic writers/readers of the same organization. If each one independently reconstructs what was decided, what was already done or what is still owed, the organization gets multiple conflicting realities.
152
+
153
+ The active roadmap asks whether Hunch can become the deterministic state layer between those agents and the organization:
154
+
155
+ > **Agents are probabilistic. Organizations need deterministic state. Hunch is the state layer between them.**
156
+
157
+ The target is **one product, one authorized state graph and one versioned state contract** across repository, user, team and organization scopes.
176
158
 
177
- The v1.19 correction-search benchmark is still useful evidence, but it no longer describes the
178
- whole product.
159
+ Planned state includes:
179
160
 
180
- - **v1.20 one validated path from reason to result.** Role-shaped context, reviewed Engineering
181
- Landscape fragments, exact change identity, PHP graph support, and hash-bound ADR review moved
182
- source, provenance, currentness, omissions, and human authority through one delivery contract.
183
- - **v1.21 Project DNA.** Hunch gained deterministic, revision-specific repository profiles,
184
- bounded DNA context delivery, explainable Project Match checks, and auditable profile deltas.
185
- - **v1.22 — authorized collaboration evidence.** Hosts can contribute bounded PR and review
186
- evidence to Project DNA through a typed, sealed contract without storing raw collaboration text
187
- or changing policy authority.
161
+ - decisions currently in force;
162
+ - verified action receipts / what was done;
163
+ - commitments and due-state;
164
+ - entities and relationships;
165
+ - code/system changes with proof;
166
+ - repository/user/team/org DNA;
167
+ - derived current state with exact dependencies/invalidation.
188
168
 
189
- See the [changelog](CHANGELOG.md) for the release-by-release detail and the
190
- [roadmap](ROADMAP.md) for what is next and deliberately out of scope.
169
+ Agents continue to own live connector mechanics. Hunch must **not** become a managed proxy that fetches Gmail, CRM, WhatsApp or GitHub on an agent's behalf.
191
170
 
192
- <details>
193
- <summary><strong>The scoped v1.19 benchmark</strong></summary>
171
+ Instead:
194
172
 
195
- On a preregistered 12-problem transfer, the supplemental inspection view found the changed
196
- declaration in 6 cases instead of 3 and the correct file in 10 cases instead of 8. On a separate
197
- 12-case transfer, its progressive queue retained the same five successful finds while reducing the
198
- average declarations to inspect from 18.9 to 11 (41.9% less).
173
+ ```text
174
+ Hunch deterministic state
175
+ ↑ ↓
176
+ agent -> deterministic action gate -> connector -> source system
177
+ ```
178
+
179
+ Hunch may hold durable state **about** external work with credential-free provenance pointers, but should not mirror raw source-system contents into a universal cache.
180
+
181
+ The first real-world pilot is **Sofia**, a working operations agent over CRM, Gmail and WhatsApp. Sofia's approved actions, follow-ups, customer/source relationships and cited summaries map naturally to action receipts, commitments, entities/relationships and dependency-bound state.
182
+
183
+ The pilot measures whether Sofia and a second, different agent stop re-deriving contradictory state when the deterministic state is delivered before they answer or act.
184
+
185
+ ### The state contract, shipped
186
+
187
+ As of 1.25.0 the contract exists as code: `nuryel.state/1` — three verbs (`read` under the
188
+ delivery envelope's receipt, `write` with provenance and an idempotency key, `subscribe` to a
189
+ strictly ordered change stream) over five new record facets: action receipts, commitments,
190
+ derived state that names what it rests on, external entities and their relationships. Ids are
191
+ derived from a record's facts, a replay returns the original, a second live decision on a topic is
192
+ refused with the incumbent named, and derived state without dependencies is not state. Each scope
193
+ keeps a git-native change ledger under `.hunch/changes/`; organization, team and user partitions
194
+ are homed in an overlay, never in a repository. The MCP server binds it as `nuryel_capabilities`,
195
+ `nuryel_read`, `nuryel_write` and `nuryel_subscribe`; every other transport will call the same
196
+ store binding. Contract and evidence: [docs/nuryel-state-contract.md](docs/nuryel-state-contract.md).
197
+
198
+ Read [Deterministic organizational state](docs/deterministic-state.md) and the [roadmap](ROADMAP.md).
199
199
 
200
- These are bounded diagnostic results, not a claim that Hunch is universally twice as accurate.
201
- Failed evidence and causal rerankers remain disabled; evidence can annotate the shortlist but does
202
- not reorder it or claim an exact correction owner. The detailed receipts live in
203
- [`bench/external/results`](bench/external/results).
200
+ ### Naming
204
201
 
205
- </details>
202
+ The product is still **Hunch**. A possible hosted-platform name, **Nuryel**, is intentionally deferred until the state contract and Sofia pilot have evidence. Rename work is not the deliverable.
206
203
 
207
- ## Share one living memory with your team
204
+ ## Share one living repository memory with your team
208
205
 
209
- Hunch can keep a team's memory in a dedicated private Git repository, separate from the code. Hunch
210
- does not host that repository. Give teammates and CI normal Git access, keep credentials in SSH or
211
- the Git credential helper, and have one maintainer connect it:
206
+ The current release can keep a team's **repository-scoped** memory in a dedicated private Git repository, separate from the code.
207
+
208
+ Today Hunch does not host that shared Git repository; teammates/CI use normal Git access and one maintainer connects it:
212
209
 
213
210
  ```bash
214
211
  npm i -g @davesheffer/hunch@1.23.3
@@ -227,34 +224,39 @@ hunch init
227
224
  hunch doctor
228
225
  ```
229
226
 
230
- The committed pointer contains a credential-free repository locator and branch. The local clone,
231
- paths, preferences, and private overlays stay ignored. MCP sessions refresh shared memory at tool
232
- boundaries, and failed pushes are retried by a later capture or `hunch shared --sync`.
227
+ The committed pointer contains a credential-free repository locator and branch. Local clone paths, preferences and private overlays stay ignored. MCP sessions refresh shared memory at tool boundaries; failed pushes can be retried by later capture or `hunch shared --sync`.
228
+
229
+ Use `hunch firmness off` to pause hook enforcement without deleting history. Use `hunch shared --repo <url> --no-auto-commit` when captures should remain local until explicit `hunch shared --sync`.
233
230
 
234
- Use `hunch firmness off` to pause hook enforcement without deleting history. Use
235
- `hunch shared --repo <url> --no-auto-commit` when captures should remain local until an explicit
236
- `hunch shared --sync`.
231
+ This existing Git-sharing feature is not the same thing as the planned organization/team/user state service. The roadmap extends the git-native model rather than declaring today's shared-memory repository to be an organization control plane.
237
232
 
238
233
  ## Trust boundaries that stay visible
239
234
 
240
- - **Local-first.** Hunch has no hosted memory service or telemetry. The graph travels with Git and
241
- speaks MCP instead of belonging to one editor or model provider.
242
- - **Private when needed.** `hunch private --repo <url>` keeps sensitive reasoning in a separate
243
- overlay. Local tools see the union; public CI and documentation remain public-only.
244
- - **Human authority.** Observations, generated drafts, imported ADRs, discovered landscape records,
245
- and proved policy candidates do not silently become trusted truth.
246
- - **Deterministic core.** Indexing, retrieval receipts, currentness, conformance, checks, Project
247
- DNA discovery, and policy evaluation do not require a model.
248
- - **No surprise synthesis bill.** Optional drafting can use a selected Claude Code, Codex, or
249
- Cursor subscription CLI, a local OpenAI-compatible endpoint, or the deterministic fallback.
250
- Public remote endpoints require explicit `HUNCH_SYNTH_ALLOW_METERED=1` opt-in.
251
- - **Traceable releases.** npm packages and the VS Code extension are content-addressed, verified
252
- against their public registries, and tied back to exact source tags.
235
+ - **Local-first today.** Repository Hunch works without a hosted service or telemetry. Git remains the repository-scoped authority.
236
+ - **Hosted state is a roadmap extension, not a shipped claim.** Organization/team/user state will require authenticated scope/visibility, idempotency and durability while preserving git-native truth.
237
+ - **Private when needed.** `hunch private --repo <url>` keeps sensitive repository reasoning in a separate overlay; public CI/documentation remain public-only.
238
+ - **Human authority.** Observations, generated drafts, imported ADRs, discovered landscape records and proved policy candidates do not silently become trusted truth.
239
+ - **Deterministic core.** Indexing, retrieval receipts, currentness, conformance, Project DNA discovery and policy evaluation do not require a model.
240
+ - **Agents own execution.** Hunch state does not silently grant connector permissions, send messages or become a source-system proxy.
241
+ - **No surprise synthesis bill.** Optional drafting can use a selected Claude Code, Codex or Cursor subscription CLI, a local OpenAI-compatible endpoint or deterministic fallback. Public remote endpoints require explicit opt-in.
242
+ - **Traceable releases.** npm packages and the VS Code extension are content-addressed, verified against public registries and tied back to exact source tags.
243
+
244
+ ## What changed after v1.19
245
+
246
+ The v1.19 correction-search benchmark remains scoped evidence, but it no longer describes the whole product.
247
+
248
+ - **v1.20 — one validated path from reason to result.** Role-shaped context, reviewed Engineering Landscape fragments, exact change identity, PHP graph support and hash-bound ADR review moved source, provenance, currentness, omissions and human authority through one delivery contract.
249
+ - **v1.21 — Project DNA.** Hunch gained deterministic, revision-specific repository profiles, bounded DNA context delivery, explainable Project Match checks and auditable profile deltas.
250
+ - **v1.22 — authorized collaboration evidence.** Hosts can contribute bounded PR/review evidence to Project DNA through a typed, sealed contract without raw collaboration persistence or policy-authority change.
251
+ - **v1.23 — native change proof and proof-carrying evidence work.** Exact Git change identity, graph before/after, decisions/constraints, blast radius and Change Gate result can be bound into a sealed evidence artifact without granting authority.
252
+
253
+ See the [changelog](CHANGELOG.md) for release detail and the [roadmap](ROADMAP.md) for active work.
253
254
 
254
255
  ## Learn more
255
256
 
256
257
  - [Full documentation](https://www.hunchmemory.com/docs)
257
258
  - [Copy-paste cookbook](https://www.hunchmemory.com/cookbook)
259
+ - [Deterministic organizational state](docs/deterministic-state.md)
258
260
  - [Project DNA](docs/project-dna.md)
259
261
  - [Native change proof](docs/change-proof.md)
260
262
  - [Engineering Landscape Graph](docs/engineering-landscape.md)
package/dist/cli/index.js CHANGED
@@ -25,6 +25,7 @@ import { writeFileAtomic } from "../core/io.js";
25
25
  import { looksLikeCorrection, CORRECTION_NUDGE } from "../core/correction.js";
26
26
  import { HUNCH_VERSION } from "../core/version.js";
27
27
  import { registerIntegrationCommands } from "./integrations.js";
28
+ import { registerUpdateCommand } from "./update.js";
28
29
  import { inspectIntegrations, formatIntegrationHealth, integrationHealthFails, integrationSessionWarning } from "../integrations/health.js";
29
30
  import { HunchStore } from "../store/hunchStore.js";
30
31
  import { JsonStore } from "../store/jsonStore.js";
@@ -112,6 +113,7 @@ import { resolveInvocation, dim, synthesisStatusLines, maybeWarnOllamaContext }
112
113
  const program = new Command();
113
114
  program.name("hunch").description("Hunch — engineering memory and a deterministic Change Gate for AI-assisted codebases.").version(HUNCH_VERSION);
114
115
  registerIntegrationCommands(program);
116
+ registerUpdateCommand(program);
115
117
  let openStore = null;
116
118
  function openTeamStore(root, opts = {}) {
117
119
  // A committed team.json is an explicit declaration that this checkout belongs
@@ -0,0 +1,72 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { findRoot } from "../core/paths.js";
5
+ const PACKAGE = "@davesheffer/hunch";
6
+ /** Arguments come only from fixed commands and a validated registry version.
7
+ * Windows needs the shell to resolve npm.cmd; cwd is never interpolated. */
8
+ export function runNpm(root, args, capture = false) {
9
+ if (args.some(arg => !/^[a-zA-Z0-9@/_.=+:-]+$/.test(arg)))
10
+ throw new Error("unsafe npm argument");
11
+ const windows = process.platform === "win32";
12
+ const result = spawnSync(windows ? `npm ${args.join(" ")}` : "npm", windows ? [] : args, {
13
+ cwd: root, shell: windows, windowsHide: true,
14
+ encoding: "utf8", stdio: capture ? ["ignore", "pipe", "pipe"] : "inherit",
15
+ });
16
+ if (result.error)
17
+ throw result.error;
18
+ if (result.status !== 0)
19
+ throw new Error(`npm ${args.join(" ")} failed (${result.status ?? result.signal})${result.stderr ? `: ${result.stderr.trim()}` : ""}`);
20
+ return result.stdout ?? "";
21
+ }
22
+ /** Fresh child execution is essential: the currently running CLI still has the
23
+ * old modules loaded after npm replaces its installation. */
24
+ export function updateHunch(root, opts = {}, run = (args, capture) => runNpm(root, args, capture), log = console.log) {
25
+ const file = join(root, "package.json");
26
+ const manifest = existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : {};
27
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest))
28
+ throw new Error("package.json must contain an object");
29
+ if (manifest.name === PACKAGE)
30
+ throw new Error("Run hunch update in a consumer repository, not Hunch's own source checkout.");
31
+ const sections = ["dependencies", "devDependencies", "optionalDependencies"];
32
+ const declared = sections.filter(section => {
33
+ const deps = manifest[section];
34
+ if (deps !== undefined && (!deps || typeof deps !== "object" || Array.isArray(deps)))
35
+ throw new Error(`invalid ${section} in package.json`);
36
+ return deps && Object.hasOwn(deps, PACKAGE);
37
+ });
38
+ if (declared.length > 1)
39
+ throw new Error("Hunch is declared in multiple dependency sections; resolve the duplicate before updating.");
40
+ if (declared.length && (manifest.workspaces || (manifest.packageManager && !/^npm@/.test(manifest.packageManager)) || ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"].some(name => existsSync(join(root, name))))) {
41
+ throw new Error("Automatic dependency updates currently support standalone npm projects. Update Hunch to an exact version with your package manager, then run hunch integrations repair-pins.");
42
+ }
43
+ const version = JSON.parse(run(["view", `${PACKAGE}@latest`, "version", "--json"], true));
44
+ if (typeof version !== "string" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(version))
45
+ throw new Error("npm returned an invalid Hunch version");
46
+ const spec = `${PACKAGE}@${version}`;
47
+ const commands = [];
48
+ if (declared.length) {
49
+ const flag = { dependencies: "--save-prod", devDependencies: "--save-dev", optionalDependencies: "--save-optional" }[declared[0]];
50
+ commands.push(["install", flag, "--save-exact", spec]);
51
+ }
52
+ if (!declared.length || opts.global)
53
+ commands.push(["install", "--global", spec]);
54
+ // The alias prevents npm exec from substituting a stale local hunch binary.
55
+ commands.push(["exec", "--yes", `--package=hunch-exact@npm:${spec}`, "--", "hunch", "integrations", "repair-pins"]);
56
+ log(`${opts.dryRun ? "Preview" : "Updating"}: Hunch ${version} for ${root}`);
57
+ for (const args of commands) {
58
+ log(`npm ${args.join(" ")}`);
59
+ if (!opts.dryRun)
60
+ run(args);
61
+ }
62
+ if (!opts.dryRun)
63
+ log("Hunch updated; repository integration check passed. Restart or reconnect active harnesses to load the new MCP version.");
64
+ }
65
+ export function registerUpdateCommand(program) {
66
+ program.command("update")
67
+ .description("Update Hunch to latest and repair all configured harness pins in this repository")
68
+ .option("--global", "also update the global CLI when a repository dependency exists")
69
+ .option("--dry-run", "resolve latest and print commands without changing files")
70
+ .action((opts) => updateHunch(findRoot(), opts));
71
+ }
72
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1,43 @@
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 const ProvenanceSchema = z.object({
11
+ source: z.string().describe("e.g. extracted | inferred | llm_draft | human_confirmed | test_failure+llm | derived"),
12
+ confidence: z.number().min(0).max(1),
13
+ evidence: z.array(z.string()).default([]).describe("file paths, commit ids, test ids backing the claim"),
14
+ last_verified: z.string().optional().describe("ISO timestamp of last re-validation"),
15
+ });
16
+ export const SENSITIVE_METADATA_KEY = /(^|[_-])(authorization|bearer|credential|password|passwd|private[_-]?key|secret|token|api[_-]?key)($|[_-])/i;
17
+ const SENSITIVE_ASSIGNMENT = /\b(authorization|password|passwd|private[_-]?key|secret|access[_-]?token|refresh[_-]?token|api[_-]?key)\s*[:=]\s*[^\s,;]{4,}/i;
18
+ const PRIVATE_KEY_BLOCK = /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/i;
19
+ const BEARER_VALUE = /\bBearer\s+[A-Za-z0-9._~+\/-]{12,}/i;
20
+ /** Reject credential material while allowing ordinary architecture prose such as
21
+ * "authentication service" or "secrets are managed externally". */
22
+ export function isCredentialFreeText(value) {
23
+ if (PRIVATE_KEY_BLOCK.test(value) || BEARER_VALUE.test(value) || SENSITIVE_ASSIGNMENT.test(value))
24
+ return false;
25
+ try {
26
+ const url = new URL(value);
27
+ if (url.username || url.password)
28
+ return false;
29
+ for (const [key] of url.searchParams)
30
+ if (SENSITIVE_METADATA_KEY.test(key))
31
+ return false;
32
+ }
33
+ catch { /* credential-free canonical locators need not be absolute URLs */ }
34
+ return true;
35
+ }
36
+ /** Bare secret shapes the general detector does not cover: it looks for assignments, bearer
37
+ * values, private-key blocks and URL userinfo; a token pasted on its own into an object key or
38
+ * locator would pass. These prefixes are the common ones. */
39
+ const BARE_SECRET = /(?:^|[^A-Za-z0-9])(?:ghp_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|sk-[A-Za-z0-9_-]{16,}|xox[abpr]-[A-Za-z0-9-]{10,}|AKIA[0-9A-Z]{16}|eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,})/;
40
+ export function isCredentialFreeValue(value) {
41
+ return isCredentialFreeText(value) && !BARE_SECRET.test(value);
42
+ }
43
+ //# sourceMappingURL=provenance.js.map