Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/hunch.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ alwaysApply: true
<!-- HUNCH:START — auto-generated, do not edit by hand -->
## 🧠 Hunch (Engineering Memory)

This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **123 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.
This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **124 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.

**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**

Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- HUNCH:START — auto-generated, do not edit by hand -->
## 🧠 Hunch (Engineering Memory)

This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **123 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.
This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **124 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.

**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**

Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ jobs:
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: 24
registry-url: https://registry.npmjs.org
package-manager-cache: false

# npm trusted publishing currently requires npm >=11.5.1 and Node >=22.14.
Expand Down Expand Up @@ -326,7 +327,14 @@ jobs:
const candidateDirectory = resolve("release-candidate");
const tarballPath = resolve(candidateDirectory, "package.tgz");

for (const tokenName of ["NODE_AUTH_TOKEN", "NPM_TOKEN", "NPM_AUTH_TOKEN"]) {
// setup-node writes an npmrc that references NODE_AUTH_TOKEN and exports this
// documented fixed sentinel when no token was supplied. npm's OIDC client needs
// that registry configuration; only the exact non-secret sentinel is permitted.
const SETUP_NODE_SENTINEL = "XXXXX-XXXXX-XXXXX-XXXXX";
if (process.env.NODE_AUTH_TOKEN && process.env.NODE_AUTH_TOKEN !== SETUP_NODE_SENTINEL) {
throw new Error("long-lived npm credential NODE_AUTH_TOKEN is forbidden");
}
for (const tokenName of ["NPM_TOKEN", "NPM_AUTH_TOKEN"]) {
if (process.env[tokenName]) throw new Error(`long-lived npm credential ${tokenName} is forbidden`);
}
const nonPublishingEnvironment = { ...process.env };
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/vscode-open-vsx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ jobs:
const NAME = "hunch-vscode";
const version = process.env.EXTENSION_VERSION;
const expectedVsixSha256 = process.env.VSIX_SHA256;
const MAX_CONVERGENCE_ATTEMPTS = 36;
if (process.env.EXTENSION_IDENTITY !== IDENTITY || !/^\d+\.\d+\.\d+$/.test(version ?? "")
|| !/^sha256:[0-9a-f]{64}$/.test(expectedVsixSha256 ?? "")) {
throw new Error("refusing invalid extension identity, version, or VSIX digest");
Expand Down Expand Up @@ -827,15 +828,15 @@ jobs:

const poll = async (label, check) => {
let lastError = "exact version not visible";
for (let attempt = 1; attempt <= 12; attempt += 1) {
for (let attempt = 1; attempt <= MAX_CONVERGENCE_ATTEMPTS; attempt += 1) {
try {
const state = await check();
if (state.verified) return { ...state, attempts: attempt };
lastError = "exact version not visible";
} catch (error) {
lastError = error instanceof Error ? error.message : String(error);
}
if (attempt < 12) await pause(5_000);
if (attempt < MAX_CONVERGENCE_ATTEMPTS) await pause(5_000);
}
throw new Error(`${label} did not converge on ${IDENTITY}@${version}: ${lastError}`);
};
Expand Down
47 changes: 47 additions & 0 deletions .hunch/decisions/dec_4d8628df85.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"id": "dec_4d8628df85",
"title": "fix(release): restore npm OIDC registry binding",
"topic": null,
"status": "accepted",
"context": "Touched 4 file(s) across site/blog, test/vscode-open-vsx-workflow.test.ts, test/workflow-release-contract.test.ts, tooling/changelog-locales.mjs.",
"decision": "Changed code in site/blog, test/vscode-open-vsx-workflow.test.ts, test/workflow-release-contract.test.ts, tooling/changelog-locales.mjs (4 file(s)).",
"consequences": [],
"alternatives_rejected": [],
"rejected_tripwires": [],
"related_components": [
"cmp_04c6efb58b",
"cmp_a94a8fe5cc",
"cmp_c099a42a55"
],
"related_files": [
"site/blog/posts.js",
"test/vscode-open-vsx-workflow.test.ts",
"test/workflow-release-contract.test.ts",
"tooling/changelog-locales.mjs"
],
"supersedes": null,
"superseded_by": null,
"caused_by_bug": null,
"commit": "b797fbd",
"valid_from": "2026-07-23T14:25:17+03:00",
"valid_to": null,
"retired": {
"symbols": [],
"deps": []
},
"provenance": {
"source": "inferred",
"confidence": 0.3,
"evidence": [
"commit:b797fbd",
"synth:provider=deterministic",
"branch:codex/npm-oidc-sentinel-v1.9.2",
"site/blog/posts.js",
"test/vscode-open-vsx-workflow.test.ts",
"test/workflow-release-contract.test.ts",
"tooling/changelog-locales.mjs"
],
"last_verified": "2026-07-23T11:25:24.054Z"
},
"date": "2026-07-23T14:25:17+03:00"
}
2 changes: 1 addition & 1 deletion .windsurf/rules/hunch.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Hunch engineering memory — consult the hunch_* MCP tools before e
<!-- HUNCH:START — auto-generated, do not edit by hand -->
## 🧠 Hunch (Engineering Memory)

This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **123 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.
This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **124 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.

**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- HUNCH:START — auto-generated, do not edit by hand -->
## 🧠 Hunch (Engineering Memory)

This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **123 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.
This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **124 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.

**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ This repo's full engineering memory lives in a **private overlay**; a **curated
<!-- HUNCH:START — auto-generated, do not edit by hand -->
## 🧠 Hunch (Engineering Memory)

This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **123 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.
This repo has **Hunch** — a curated graph of *why* the code is the way it is (decisions, bug history, invariants). It currently holds **124 decisions, 2 bugs, 9 constraints, 16 components, 3 policies**.

**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ strict enforcement.
**Memory is the input. The product boundary is the receipt:** relevant evidence before an edit,
then a deterministic check of the change against the rules your team has explicitly trusted.

> **New in v1.9.1:** Matrix mode gives the whole team one live, private Git memory across fresh
> **New in v1.9.2:** Matrix mode gives the whole team one live, private Git memory across fresh
> clones, worktrees, CLI checks, and MCP assistants. npm publishes with short-lived OIDC
> credentials, while the editor companion ships as one immutable, publicly verified Open VSX
> artifact.
Expand Down Expand Up @@ -82,7 +82,7 @@ Git repo that every teammate can access, install the Matrix release on team mach
have one maintainer run:

```bash
npm i -g @davesheffer/hunch@1.9.1
npm i -g @davesheffer/hunch@1.9.2
hunch shared --repo git@github.com:acme/project-hunch-memory.git
git add .gitignore .hunch/team.json
git commit -m "chore: connect shared Hunch memory"
Expand All @@ -97,7 +97,7 @@ printed by Hunch. Omit `--migrate` for a new setup.
After the pointer commit lands, teammates need Hunch installed and Git access to the memory repo:

```bash
npm i -g @davesheffer/hunch@1.9.1
npm i -g @davesheffer/hunch@1.9.2
git pull
hunch init
hunch doctor
Expand Down
10 changes: 5 additions & 5 deletions docs/cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ remote, and the URL committed into the code repository must not contain credenti
On one maintainer machine:

```bash
npm i -g @davesheffer/hunch@1.9.1
npm i -g @davesheffer/hunch@1.9.2
hunch shared --repo git@github.com:acme/project-hunch-memory.git
git add .gitignore .hunch/team.json
git commit -m "chore: connect shared Hunch memory"
Expand All @@ -173,7 +173,7 @@ into the dedicated store. Review the reported untrack/ignore changes and follow
Hunch prints. On every teammate machine:

```bash
npm i -g @davesheffer/hunch@1.9.1
npm i -g @davesheffer/hunch@1.9.2
git pull
hunch init
hunch doctor
Expand Down Expand Up @@ -271,10 +271,10 @@ Matrix memory home as the CLI; it never writes Hunch JSON directly.
For a release audit, start with the exact tags and public registry metadata:

```bash
npm view @davesheffer/hunch@1.9.1 version dist.integrity dist.attestations --json
git tag --list v1.9.1 vscode-v0.17.3
npm view @davesheffer/hunch@1.9.2 version dist.integrity dist.attestations --json
git tag --list v1.9.2 vscode-v0.17.3
```

**Observe:** npm reports `1.9.1`, an integrity digest, and provenance metadata. Open VSX reports
**Observe:** npm reports `1.9.2`, an integrity digest, and provenance metadata. Open VSX reports
`0.17.3`. The GitHub Actions run for each tag shows a credential-free validation job followed by
publication and public byte verification of the same content-addressed artifact.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@davesheffer/hunch",
"version": "1.9.1",
"version": "1.9.2",
"license": "Apache-2.0",
"author": "Dave Sheffer <dave.sheffer1@gmail.com>",
"description": "Engineering memory and a deterministic Change Gate for AI-assisted codebases: decisions, rejected approaches, constraints, and bug lineage become portable context and opt-in enforcement for every MCP assistant.",
Expand Down
3 changes: 2 additions & 1 deletion site/ar/changelog/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ <h1>كل إصدار، منذ <em>v0.1</em>.</h1>
<div class="clog">
<div class="clog-group">
<div class="clog-date">23 يوليو 2026</div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>نشر موثوق عبر Open VSX وnpm</b></span></div>
<div class="clog-row"><span class="rel-tag">v1.9.2</span><span class="clog-t"><b>وصول OIDC الخاص بـnpm إلى السجل</b></span></div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>نشر الإضافة عبر Open VSX فقط</b></span></div>
</div>
<div class="clog-group">
<div class="clog-date">22 يوليو 2026</div>
Expand Down
2 changes: 1 addition & 1 deletion site/blog/posts.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion site/changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ <h1>Every release, since <em>v0.1</em>.</h1>
<div class="clog">
<div class="clog-group">
<div class="clog-date">Jul 23, 2026</div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>Reliable Open VSX and npm publishing</b> — the editor companion now has one explicit public home: Open VSX. Its immutable release gate still validates one credential-free VSIX, publishes only those bytes, and verifies the public download digest. npm trusted publishing no longer receives setup-node's placeholder token, so the OIDC-only gate can reach publication without accepting a long-lived credential.</span></div>
<div class="clog-row"><span class="rel-tag">v1.9.2</span><span class="clog-t"><b>npm OIDC reaches the registry</b> — trusted publishing keeps setup-node's required npm registry configuration, permits only its exact fixed non-secret sentinel, and still rejects every real long-lived npm credential. Open VSX verification also allows the public index a bounded three-minute visibility window. The immutable candidate, provenance, digest, and public-registry verification gates remain unchanged.</span></div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>Open VSX-only editor publishing</b> — the editor companion now has one explicit public home: Open VSX. Its immutable release gate validates one credential-free VSIX, publishes only those bytes, and verifies the public download digest. The accompanying npm hardening exposed setup-node's required sentinel as a follow-up release issue before npm publication.</span></div>
</div>
<div class="clog-group">
<div class="clog-date">Jul 22, 2026</div>
Expand Down
3 changes: 2 additions & 1 deletion site/changelog/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ <h1>Every release, since <em>v0.1</em>.</h1>
<div class="clog">
<div class="clog-group">
<div class="clog-date">Jul 23, 2026</div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>Reliable Open VSX and npm publishing</b> — the editor companion now has one explicit public home: Open VSX. Its immutable release gate still validates one credential-free VSIX, publishes only those bytes, and verifies the public download digest. npm trusted publishing no longer receives setup-node's placeholder token, so the OIDC-only gate can reach publication without accepting a long-lived credential.</span></div>
<div class="clog-row"><span class="rel-tag">v1.9.2</span><span class="clog-t"><b>npm OIDC reaches the registry</b> — trusted publishing keeps setup-node's required npm registry configuration, permits only its exact fixed non-secret sentinel, and still rejects every real long-lived npm credential. Open VSX verification also allows the public index a bounded three-minute visibility window. The immutable candidate, provenance, digest, and public-registry verification gates remain unchanged.</span></div>
<div class="clog-row"><span class="rel-tag">v1.9.1</span><span class="clog-t"><b>Open VSX-only editor publishing</b> — the editor companion now has one explicit public home: Open VSX. Its immutable release gate validates one credential-free VSIX, publishes only those bytes, and verifies the public download digest. The accompanying npm hardening exposed setup-node's required sentinel as a follow-up release issue before npm publication.</span></div>
</div>
<div class="clog-group">
<div class="clog-date">Jul 22, 2026</div>
Expand Down
10 changes: 5 additions & 5 deletions site/cookbook.html
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,13 @@ <h2>9 · Benchmark your own setup<a class="anchor" href="#bench">#</a></h2>
<section id="matrix">
<h2>10 · Connect the team-memory Matrix<a class="anchor" href="#matrix">#</a></h2>
<p>Create a dedicated private Git repository for memory. It must differ from every code-repo remote, and its committed URL must not contain credentials. On one maintainer machine:</p>
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">terminal</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> i -g @davesheffer/hunch@1.9.1
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">terminal</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> i -g @davesheffer/hunch@1.9.2
<span class="k">hunch</span> shared --repo git@github.com:acme/project-hunch-memory.git
<span class="k">git</span> add .gitignore .hunch/team.json
<span class="k">git</span> commit -m "chore: connect shared Hunch memory"
<span class="k">git</span> push</pre></div>
<p>Add <code>--migrate</code> only when moving existing public <code>.hunch/</code> memory into the dedicated store. On every teammate machine:</p>
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">terminal</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> i -g @davesheffer/hunch@1.9.1
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">terminal</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> i -g @davesheffer/hunch@1.9.2
<span class="k">git</span> pull
<span class="k">hunch</span> init
<span class="k">hunch</span> doctor</pre></div>
Expand Down Expand Up @@ -376,9 +376,9 @@ <h2>13 · Use a local or self-hosted model<a class="anchor" href="#local-models"
<section id="editor-release">
<h2>14 · Install the editor companion and verify a release<a class="anchor" href="#editor-release">#</a></h2>
<p>Install Hunch from <a class="link" href="https://open-vsx.org/extension/davesheffer/hunch-vscode" target="_blank" rel="noopener">Open VSX</a>, then open a repository initialized with the Hunch CLI. The extension reads the same public, private, or Matrix memory home and never writes Hunch JSON directly.</p>
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">audit</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> view @davesheffer/hunch@1.9.1 version dist.integrity dist.attestations --json
<span class="k">git</span> tag --list v1.9.1 vscode-v0.17.3</pre></div>
<p><b>Observe:</b> npm reports version 1.9.1, an integrity digest, and provenance metadata; Open VSX reports 0.17.3. Each tag’s GitHub Actions run validates the exact content-addressed artifact before isolated publishing begins and verifies the same public bytes afterward.</p>
<div class="code" data-lang="bash"><div class="code-head"><span class="lbl">audit</span><button class="copy">Copy</button></div><pre><span class="k">npm</span> view @davesheffer/hunch@1.9.2 version dist.integrity dist.attestations --json
<span class="k">git</span> tag --list v1.9.2 vscode-v0.17.3</pre></div>
<p><b>Observe:</b> npm reports version 1.9.2, an integrity digest, and provenance metadata; Open VSX reports 0.17.3. Each tag’s GitHub Actions run validates the exact content-addressed artifact before isolated publishing begins and verifies the same public bytes afterward.</p>
</section>
</main>

Expand Down
Loading
Loading