@bluenotelogic/harness 0.1.0 → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,114 @@
1
+ # Changelog
2
+
3
+ Notable changes to `@bluenotelogic/harness`. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). While the version is 0.x, a minor
5
+ release may contain breaking changes; they are listed first.
6
+
7
+ ## [0.2.0] - 2026-10-31
8
+
9
+ Everything since 0.1.0 (the npm release, built from `7b48279`). The product is now ProofMEM, and
10
+ the defaults follow it.
11
+
12
+ ### Breaking
13
+
14
+ - **Default server** `https://mem.bnlgit.com` is now `https://proofmem.com`. Use `--url` to point
15
+ at another deployment.
16
+ - **OAuth client** `blue-note-mem-mcp` is now `proofmem-mcp`. Use `--client-id` if your server
17
+ still registers the old client.
18
+ - **Codex token variable** `BNL_MEMORY_MCP_TOKEN` is now `PROOFMEM_TOKEN`, and the Codex config
19
+ references the new name. Existing `BNL_MEMORY_MCP_TOKEN` and `CAVEAU_MCP_TOKEN` lines in
20
+ `~/.codex/.env` are left in place, with a one-line notice naming them (never their values).
21
+ - **MCP server key** `mem` is now `proofmem`. The key comes from the server's bundle; `proofmem`
22
+ is also the fallback. `--server-name` still overrides it.
23
+ - **No token in the repo, ever.** `--mint-token` and `--codex` no longer write the token into
24
+ the target repo's `.claude/settings.local.json`. `~/.codex/.env` is its only home; Claude Code
25
+ and VS Code use OAuth and need no token.
26
+ - **Codex config is one managed block.** The installer now owns a marked
27
+ `# BEGIN/END @bluenotelogic/harness managed MCP` block in `~/.codex/config.toml`, with
28
+ `default_tools_approval_mode = "prompt"` and approvals for the memory and harness-run tools.
29
+ The 0.1.0 block, and the exact table `codex mcp add` writes, are adopted into it. Any other
30
+ table with the same name is left untouched and reported, never overwritten.
31
+
32
+ ### Added
33
+
34
+ - `--antigravity`: installs the ProofMEM plugin for Google Antigravity. It has a
35
+ tokenless native OAuth MCP config, plus Caveau Harness v2 lifecycle hooks that use their own
36
+ owner-only 90-day key. Needs `--harness-home <caveau-harness-v2>` (or `HARNESS_HOME`), and bash
37
+ plus jq for the hooks. `--antigravity-home` overrides `~/.gemini/config`.
38
+ - Only the memory hooks get the hook key, and they are then pinned to ProofMEM
39
+ (`HARNESS_MEMORY_PROVIDER` and `HARNESS_COORDINATION_STORE` = `caveaumem`). The key and its
40
+ API URL always come as a pair from one source.
41
+ - The guard, checkpoint, lint and verify hooks get no credential-shaped environment variable:
42
+ a name part that is `KEY`, `PAT`, `PWD`, `PASS` or `AUTH` (`AUTH` except in `HARNESS_*`
43
+ names), or that ends in `TOKEN`, `SECRET`, `PASSWORD`, `PASSWD`, `PASSPHRASE`, `CREDENTIAL`,
44
+ `BEARER`, `APIKEY` or `JWT`. Nor do they get the editor's Git and SSH credential bridges,
45
+ which hold no secret but hand a child process your credentials anyway: `GIT_ASKPASS`,
46
+ `SSH_ASKPASS`, `SSH_ASKPASS_REQUIRE`, `SSH_AUTH_SOCK`, `GIT_SSH_COMMAND`, `GIT_SSH`, every
47
+ `VSCODE_GIT_*`, and `GIT_CONFIG_PARAMETERS`, `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_<n>` and
48
+ `GIT_CONFIG_VALUE_<n>`. A trusted project's verify build that needs your SSH agent or Git
49
+ sign-in has to be run by hand. Other names, a credential helper your own Git config names, and
50
+ credential files such as `~/.npmrc`, are not hidden.
51
+ - With `--codex` as well, Codex and the hooks get separate keys, so revoking one leaves the
52
+ other working.
53
+ - `--verify-gate`: opt in to the Antigravity Stop hook running the open project's own
54
+ build/test/lint. Off by default, because it runs that project's code. An empty exported
55
+ `HARNESS_VERIFY_GATE` counts as unset, so it cannot switch the gate on.
56
+ - Sign-in through the proofmem.com OAuth gateway. Its `/oauth/token` already returns a ProofMEM
57
+ key (`cmem_…`), which the CLI now uses directly; sending it to `/api/oidc_exchange.php` again
58
+ was a 401 that made sign-in impossible. A Blue Note ID token, from a server without the
59
+ gateway, is still exchanged.
60
+ - `doctor`: read-only installation checks for the Codex block, the credential store,
61
+ `HARNESS_HOME` and a tokenless repo config. With `--antigravity` it also checks the plugin,
62
+ hook-key expiry and that bash resolves. It never prints a credential.
63
+ - A minted token's expiry (90 days, set by the server) is printed after a real run. The value
64
+ never is.
65
+ - Distinct messages for an identity the server cannot use (422) and for Blue Note ID being
66
+ down (503), so neither reads as a failed login.
67
+ - A sign-in the proofmem.com gateway refuses with `access_denied` (no ProofMEM subscription, or a
68
+ Blue Note ID without a verified email) now says so and where to fix each: `/pricing.php` on
69
+ the server, or `https://id.bluenotelogic.com`. It used to print
70
+ `token exchange failed: 400 {"error":"access_denied"}`, which read as a failed login. With
71
+ `--device` it also lists a declined approval.
72
+ - `NOTICE` and this `CHANGELOG.md` ship in the package.
73
+
74
+ ### Fixed
75
+
76
+ - On Windows the browser opens the whole sign-in URL. It used to go through `cmd /c start`,
77
+ which ends a command at every `&`, so the browser opened `/oauth/authorize?response_type=code`
78
+ only and the server refused it; pasting the printed URL was the only way in. The CLI now
79
+ starts `rundll32 url.dll,FileProtocolHandler` directly, with no shell, and opens only http(s)
80
+ URLs.
81
+ - `--dry-run` no longer mints. It used to create a real, non-expiring token server-side and print
82
+ it in the preview. Credential files are now shown redacted. Signing in still creates one
83
+ short-lived (1 h) session key.
84
+ - A sign-in no longer leaves its refresh grant behind. The CLI asks for `offline_access` but
85
+ never uses the refresh token, and through proofmem.com that token stands for a Blue Note ID
86
+ refresh token the gateway keeps, encrypted, for up to 35 days. Every run, `--dry-run` included,
87
+ now revokes it (RFC 7009) once the configuration is fetched, and says so if the server does not
88
+ confirm.
89
+ - The token no longer lands in the repo (see Breaking): `.claude/settings.local.json` is never
90
+ written.
91
+ - Credential files are owner-only: `chmod 0600` on Linux and macOS, and on Windows an access list
92
+ with exactly one entry for the current user's SID (verified in any language; sandbox entries
93
+ such as `CodexSandboxUsers` are removed). A credential file is recreated rather than rewritten,
94
+ so an old grant cannot survive. If the protection cannot be proved, the file is deleted and the
95
+ install fails.
96
+
97
+ ### Migrating from 0.1.0
98
+
99
+ 1. Re-run `npx @bluenotelogic/harness init` in each configured repo. It adds the `proofmem`
100
+ server to `.mcp.json` and never deletes keys it does not own, so remove the old `mem` entry by
101
+ hand.
102
+ 2. If you used `--mint-token` or `--codex` with 0.1.0, delete the `BNL_MEMORY_MCP_TOKEN` entry
103
+ from that repo's `.claude/settings.local.json`. Tokens from that era may have no expiry, so
104
+ revoke the ones you no longer use at `https://proofmem.com/app/keys.php`.
105
+ 3. Codex: re-run `init --codex`. The managed block switches to `PROOFMEM_TOKEN`. Remove
106
+ `BNL_MEMORY_MCP_TOKEN` / `CAVEAU_MCP_TOKEN` from `~/.codex/.env` once nothing else on the
107
+ machine reads them; `doctor` warns while they are there.
108
+ 4. For a deployment other than proofmem.com, pass `--url`, and `--client-id` if it still uses the
109
+ old OAuth client.
110
+
111
+ ## [0.1.0]
112
+
113
+ First npm release: `init` with browser (PKCE) and `--device` sign-in, a tokenless `.mcp.json`,
114
+ optional `--mint-token` / `--codex`, `--harness-home` routing, and `--timeout`.
package/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ BNL Harness (client)
2
+ Copyright 2026 Blue Note Logic Inc.
3
+
4
+ This product includes software developed at Blue Note Logic Inc.
5
+ (https://bluenotelogic.com/).
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @bluenotelogic/harness
2
2
 
3
- Point a machine at [Blue Note Memory](https://mem.bnlgit.com) in one command.
3
+ Point a machine at [ProofMEM](https://proofmem.com) in one command.
4
4
 
5
5
  ```bash
6
6
  npx @bluenotelogic/harness init
@@ -12,7 +12,7 @@ working MCP config into the current repo.
12
12
  ## What it writes — and what it deliberately does not
13
13
 
14
14
  ```json
15
- { "mcpServers": { "mem": { "type": "http", "url": "https://mem.bnlgit.com/mcp" } } }
15
+ { "mcpServers": { "proofmem": { "type": "http", "url": "https://proofmem.com/mcp" } } }
16
16
  ```
17
17
 
18
18
  **There is no token in that file.** Claude Code and VS Code discover authentication from the
@@ -24,25 +24,63 @@ That is the entire point of this tool. The setup it replaces meant pasting a bea
24
24
  hand into `.mcp.json`, `~/.claude.json`, `~/.codex/config.toml` and a VS Code roaming
25
25
  profile — and rotating anything meant editing every one of them again.
26
26
 
27
- ## Codex and CI
27
+ ## Codex
28
28
 
29
- Those hosts cannot do OAuth yet, so they need a real credential:
29
+ Codex can sign in with OAuth on its own. Codex CLI 0.163.0 runs the OAuth flow for an MCP
30
+ server with `codex mcp login <name>` and keeps that credential itself; this was verified with
31
+ proofmem.com on 2026-10-27. That path needs no token from this CLI. A plain `init` writes no
32
+ Codex config, so add the server to Codex first, then sign in:
33
+
34
+ ```bash
35
+ codex mcp add proofmem --url https://proofmem.com/mcp
36
+ codex mcp login proofmem
37
+ ```
38
+
39
+ The same two steps are in the [ProofMEM docs](https://proofmem.com/docs.php).
40
+
41
+ This CLI does not run Codex's sign-in for you. `--codex` configures Codex with a minted token
42
+ instead (`--codex` implies `--mint-token`):
30
43
 
31
44
  ```bash
32
45
  npx @bluenotelogic/harness init --codex
33
46
  ```
34
47
 
35
- The minted token goes to `~/.codex/.env` and is referenced from `config.toml` by name
36
- (`bearer_token_env_var`), so the config file stays safe to read over someone's shoulder — and
37
- the token still never touches the repo. Minting is opt-in: without `--codex` or
38
- `--mint-token`, this CLI creates no credential and no database row.
48
+ The minted token goes to `~/.codex/.env` as `PROOFMEM_TOKEN` and is referenced from
49
+ `config.toml` by name (`bearer_token_env_var`), so the config file stays safe to read over someone's shoulder — and
50
+ the token still never touches the repo, not even the target repo's own `.claude/settings.local.json`.
51
+ Minting is opt-in: without `--codex` or `--mint-token`, this CLI creates no credential and no
52
+ database row.
53
+
54
+ `BNL_MEMORY_MCP_TOKEN` and `CAVEAU_MCP_TOKEN` are earlier names for that token. If the Codex env
55
+ file still has them, the installer leaves those lines exactly as they are, because other tools
56
+ on the machine may still read them, and prints a one-line notice naming them (never their
57
+ values). Remove them by hand once nothing uses them. The Codex TOML
58
+ writer owns one explicitly marked block; it preserves unrelated servers and settings, updates
59
+ its own block idempotently, and refuses an unowned table whose ownership is ambiguous.
60
+
61
+ Two more things a minted token gets, that a hand-pasted one never did: an expiry — 90 days,
62
+ printed to you (never the value) after a real run — and the file is locked to your own account
63
+ only (`chmod 0600` on Linux/macOS, an owner-only ACL on Windows) immediately after it is
64
+ written. If that protection can't be verified, the file is deleted rather than left in an
65
+ unknown state.
39
66
 
40
- For CI, skip the browser entirely with a token you already hold:
67
+ ## CI
68
+
69
+ A CI runner has no browser and nobody there to sign in, so it needs a real credential. Pass
70
+ a ProofMEM key you already hold (a `cmem_` token) and the CLI skips sign-in entirely:
41
71
 
42
72
  ```bash
43
- npx @bluenotelogic/harness init --token "$BNL_MEMORY_MCP_TOKEN"
73
+ npx @bluenotelogic/harness init --token "$PROOFMEM_TOKEN"
44
74
  ```
45
75
 
76
+ The CLI uses that key only for this run. It writes the same tokenless `.mcp.json` and stores
77
+ no credential, so an agent on the runner gets no key from it. If an agent there needs a key of
78
+ its own, add `--mint-token`: the CLI mints one and writes it to `~/.codex/.env` as
79
+ `PROOFMEM_TOKEN`, outside the repo.
80
+
81
+ `--device` (below) also works without a browser on the machine, but someone has to approve the
82
+ code on another device, so it suits headless machines and SSH sessions, not unattended CI.
83
+
46
84
  ## Headless machines
47
85
 
48
86
  ```bash
@@ -51,29 +89,133 @@ npx @bluenotelogic/harness init --device
51
89
 
52
90
  Prints a short code and a URL to open on any other device. Standard RFC 8628 device flow.
53
91
 
92
+ ## Google Antigravity
93
+
94
+ Google Antigravity signs in to ProofMEM with OAuth, and its Caveau Harness hooks are available now.
95
+ The hooks need a Caveau Harness v2 checkout, which is not publicly distributed: our team sets it up
96
+ with you in a guided Caveau Harness session (contact ProofMEM to book one). With the checkout in
97
+ place, install the ProofMEM plugin and its Caveau Harness v2 lifecycle adapter with:
98
+
99
+ ```bash
100
+ npx @bluenotelogic/harness init --antigravity --harness-home /path/to/caveau-harness-v2
101
+ ```
102
+
103
+ On Windows, `--harness-home C:\\path\\to\\caveau-harness-v2` is accepted. If `HARNESS_HOME`
104
+ already names a v2 checkout, the flag may be omitted.
105
+
106
+ The installed `mcp_config.json` points directly at `https://proofmem.com/mcp` and carries no
107
+ token, header, environment variable, or stdio bridge. Antigravity completes native OAuth/DCR and
108
+ keeps that session in its own protected store. Lifecycle hook processes cannot read that OAuth
109
+ store, so the installer mints a second bounded token solely for hooks and locks it to the current
110
+ OS account under `~/.gemini/config/proofmem/hook-token`. Its value is not copied into the plugin,
111
+ repo, logs, or Codex environment.
112
+
113
+ On Windows the file's access list is replaced with a single entry for the current user (by SID,
114
+ so it holds in every Windows language) and then verified; sandbox groups such as
115
+ `CodexSandboxUsers` are removed rather than tolerated. If that cannot be proved, the file is
116
+ deleted and the install fails. With `--codex` as well, Codex and the hooks get separate tokens.
117
+
118
+ The hook token is never handed to the guard, checkpoint, lint, or verify scripts, so a project's
119
+ own build or test scripts do not inherit it from Antigravity. Nor do they get any environment
120
+ variable whose name, split at every character that is not a letter or digit, has a part that is
121
+ `KEY`, `PAT`, `PWD`, `PASS` or `AUTH`, or that ends in `TOKEN`, `SECRET`, `PASSWORD`, `PASSWD`,
122
+ `PASSPHRASE`, `CREDENTIAL`, `BEARER`, `APIKEY` or `JWT` (case-insensitive, plural or a trailing
123
+ `KEY` allowed): `GITHUB_TOKEN`, `AWS_SECRET_ACCESS_KEY`, `OPENAI_API_KEY`, `NPM_CONFIG__AUTH`,
124
+ `GITEA_PAT`, `DB_PWD`, `SSH_AUTH_SOCK`, `CI_JOB_JWT`, and so on. `PATH`, `HOME`, `PWD` and the
125
+ other process basics are always kept, and an `AUTH` part does not count in the Harness's own
126
+ `HARNESS_*` names, where it is a mode switch (`HARNESS_MEMORY_AUTH`).
127
+ They also lose the editor's credential bridges, variables that hold no secret but let a child
128
+ process use your Git or SSH credentials anyway: `GIT_ASKPASS`, `SSH_ASKPASS`,
129
+ `SSH_ASKPASS_REQUIRE`, `SSH_AUTH_SOCK`, `GIT_SSH_COMMAND`, `GIT_SSH`, every `VSCODE_GIT_*` (the
130
+ editor's askpass helper and its IPC handle, which can answer with your Git account's token), and
131
+ `GIT_CONFIG_PARAMETERS`, `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_<n>` and `GIT_CONFIG_VALUE_<n>`
132
+ (which can inject a credential helper). The memory hooks keep them for SessionStart's Git refresh.
133
+ So if a trusted project's opt-in verify build needs your SSH agent or Git sign-in, run that build
134
+ yourself. A credential under any other name, a credential helper your own Git config already
135
+ names (such as Git Credential Manager), and credential files such as `~/.npmrc` or
136
+ `~/.aws/credentials` are not hidden, which is one more reason the verify gate below is opt-in.
137
+ The memory hooks that do receive the hook token are pinned to ProofMEM
138
+ (`HARNESS_MEMORY_PROVIDER=caveaumem`, `HARNESS_COORDINATION_STORE=caveaumem`), so an exported
139
+ value cannot send that session's memory to another store.
140
+
141
+ The plugin adapts SessionStart bootstrap, focused per-prompt context, destructive-command checks,
142
+ edit checkpoints/lint, and memory capture. Restart Antigravity after install, enable the ProofMEM
143
+ plugin, and authenticate its MCP server when prompted.
144
+
145
+ **Prerequisites for the hooks: bash and jq.** On Windows that is Git for Windows' bash, plus jq
146
+ installed so that it runs from that bash (Git for Windows does not include jq); WSL bash is
147
+ deliberately not used. On Linux and macOS, bash and jq on the `PATH`. Without bash no hook runs,
148
+ and without jq the memory hooks cannot work; either way they fail open rather than block you.
149
+
150
+ The Stop verification gate is **off by default**. When on, it runs the open project's own
151
+ `npm run build`, `npm test` or `npm run lint` each time the agent stops, outside Antigravity's
152
+ command approval, so opening an untrusted repository would run its code. Turn it on with
153
+ `--verify-gate` only for projects you trust. An exported `HARNESS_VERIFY_GATE=0` or `=1` overrides
154
+ that choice; an empty value counts as unset.
155
+
156
+ The hook token is bounded (90 days). `doctor --antigravity` warns 14 days before it expires, and
157
+ SessionStart says so too. Renew it by running the same `init --antigravity` command again; do not
158
+ export a token in the environment instead. The MCP server's `enabledTools` list hides skill/tool
159
+ authoring and vault tools from the agent. It is a convenience, not a security boundary: the
160
+ server enforces each token's scopes, and no ProofMEM token can read the vault.
161
+
54
162
  ## Options
55
163
 
56
164
  | Flag | Effect |
57
165
  |---|---|
58
- | `--dry-run` | Show every file that would change, write nothing |
59
- | `--url <base>` | Point at a self-hosted deployment (default `https://mem.bnlgit.com`) |
166
+ | `--dry-run` | Show every file that would change and write nothing. Mints no long-lived token, but signing in still creates one short-lived (1 h) session key on the server; the sign-in's refresh grant is revoked at once (see below) |
167
+ | `--url <base>` | Point at a self-hosted deployment (default `https://proofmem.com`) |
60
168
  | `--dir <path>` | Repo to configure (default: current directory) |
61
169
  | `--device` | Device-code login for headless boxes and SSH sessions |
62
170
  | `--token <token>` | Use an existing token instead of logging in |
63
171
  | `--mint-token` | Also mint a token for hosts that cannot do OAuth |
64
172
  | `--codex` | Configure Codex too (implies `--mint-token`) |
173
+ | `--antigravity` | Install the ProofMEM Antigravity plugin (implies one hook-token mint) |
174
+ | `--antigravity-home <dir>` | Override Antigravity config home (default `~/.gemini/config`) |
175
+ | `--verify-gate` | Antigravity: run the open project's build/test/lint when the agent stops (off by default) |
65
176
  | `--harness-home <dir>` | Materialize hosted model routing into `<dir>/state/routing/` |
66
177
  | `--server-name <name>` | Override the MCP server key written into `.mcp.json` |
67
178
  | `--no-browser` | Print the login URL instead of opening a browser |
68
179
 
180
+ Validate the result without contacting the service or printing secrets:
181
+
182
+ ```bash
183
+ npx @bluenotelogic/harness doctor --dir /path/to/repo
184
+ ```
185
+
186
+ For the Antigravity installation only:
187
+
188
+ ```bash
189
+ npx @bluenotelogic/harness doctor --antigravity --dir /path/to/repo
190
+ ```
191
+
192
+ The doctor requires the canonical token reference, one installer-managed Codex block, a
193
+ tokenless repo MCP config, and a `HARNESS_HOME` whose `.harness-generation` marker is exactly
194
+ `caveau-harness-v2`. Routing will not be written into an archived or unidentified harness.
195
+
69
196
  Run `--dry-run` first if you like seeing before you commit. It prints the full contents of
70
- every file it would touch.
197
+ every file it would touch — except a credential file (`~/.codex/.env`), which is shown as
198
+ `create`/`update` with its content redacted, whether or not `--dry-run` actually minted
199
+ anything. `--dry-run` writes nothing and never mints a long-lived token: no Codex or hook key is
200
+ created. Signing in still creates one short-lived (1 h) session key on the server, because that
201
+ key is how the CLI reads your configuration; with `--token`, not even that.
202
+
203
+ Signing in also returns a refresh token, which the CLI never uses. Through proofmem.com it stands
204
+ for a sign-in record the gateway keeps (your Blue Note ID refresh token, encrypted, for up to 35
205
+ days). So once the CLI has your configuration, on every run including `--dry-run`, it revokes that
206
+ refresh token at the server's revocation endpoint, and the record is gone. If the server does not
207
+ confirm, the CLI prints a one-line note, and the record lapses on its own when it expires.
208
+
209
+ Revoking: every ProofMEM key, including that session key and the 90-day Codex and hook keys, is
210
+ listed in the ProofMEM console at `https://proofmem.com/app/keys.php`, and revoking it there cuts
211
+ it off. Signing out of Blue Note ID does not: a key already handed to a client stays valid until
212
+ it expires.
71
213
 
72
214
  ## It will not clobber your config
73
215
 
74
- Every write reads what is already on disk and replaces **only** the keys it owns. An
75
- unrelated MCP server in your `.mcp.json` survives untouched; so do unrelated top-level keys,
76
- your Codex settings, and any hooks in `.claude/settings.local.json`.
216
+ Every write reads what is already on disk and replaces **only** the keys or marked blocks it
217
+ owns. An unrelated MCP server in your `.mcp.json` or Codex TOML survives untouched, and so do
218
+ unrelated top-level keys.
77
219
 
78
220
  If a file is not valid JSON, the CLI reports it and **leaves it exactly as it found it** —
79
221
  "it looked broken" is precisely when someone's half-finished hand edit is sitting in it.
@@ -97,16 +239,29 @@ not. `test/writers.test.js` pins that behaviour so it cannot happen again.
97
239
  .mcp.json, routing YAML, optional Codex config
98
240
  ```
99
241
 
242
+ On proofmem.com the OAuth endpoints belong to the ProofMEM gateway, which runs the
243
+ `oidc_exchange.php` step itself and returns the short-lived ProofMEM key (`cmem_…`) as the
244
+ access token. The CLI recognises that key and goes straight to `harness_bootstrap.php`; it only
245
+ calls `oidc_exchange.php` itself when the sign-in returned a Blue Note ID token, as a server
246
+ without the gateway does.
247
+
100
248
  Identity and entitlement are separate on purpose. A Blue Note Account authenticates a person;
101
249
  it does not by itself grant memory access. If you sign in successfully but hold no
102
- subscription you get a clear message saying exactly that, rather than a login error that
103
- sends you looking in the wrong place.
250
+ subscription, the exchange says exactly that, rather than giving a login error that sends you
251
+ looking in the wrong place. Through the gateway that refusal, and an identity the server cannot
252
+ use (no verified email on the Blue Note Account), both end the sign-in with `access_denied`, so
253
+ the CLI names both causes: start a subscription at `https://proofmem.com/pricing.php`, or verify
254
+ the account's email at `https://id.bluenotelogic.com`, then run the command again. Signing in
255
+ again without either change does not help.
104
256
 
105
257
  ## Requirements
106
258
 
107
259
  Node 20 or newer. **No runtime dependencies** — PKCE, the loopback listener and the HTTP
108
260
  client are all Node built-ins, so `npx` is fast and there is no dependency tree to audit.
109
261
 
262
+ The Antigravity hooks also need bash and jq: Git for Windows' bash plus jq on
263
+ Windows, bash plus jq elsewhere. See [Google Antigravity](#google-antigravity).
264
+
110
265
  ## Development
111
266
 
112
267
  ```bash
@@ -119,5 +274,5 @@ npm run lint # tsc --noEmit
119
274
 
120
275
  Apache-2.0 — © 2026 Blue Note Logic Inc. See [LICENSE](LICENSE).
121
276
 
122
- This CLI is free and open source. It configures a machine to talk to Blue Note
123
- Memory; a Blue Note Memory subscription is a separate commercial product.
277
+ This CLI is free and open source. It configures a machine to talk to ProofMEM;
278
+ a ProofMEM subscription is a separate commercial product.
@@ -0,0 +1,69 @@
1
+ # ProofMEM for Google Antigravity
2
+
3
+ Installed and updated by `npx @bluenotelogic/harness init --antigravity`.
4
+
5
+ The MCP server uses Antigravity's native Streamable HTTP OAuth/DCR support. Its
6
+ `mcp_config.json` deliberately contains no bearer header, environment variable, token, or
7
+ stdio bridge. Antigravity owns and refreshes that OAuth session in its protected store.
8
+
9
+ Lifecycle hooks run through Caveau Harness v2. Because Antigravity does not expose its OAuth
10
+ credential to hook subprocesses, the installer mints a separate bounded ProofMEM token for
11
+ those hooks and protects it in the user's Antigravity config directory. `harness-home.json`
12
+ contains paths and the ProofMEM API URL only; it never contains the credential value.
13
+
14
+ If the MCP server first appears as `Unauthorized`, open Antigravity's Customizations / MCP
15
+ Servers panel and authenticate the ProofMEM server. Do not add headers or tokens to the plugin.
16
+
17
+ The hooks need bash and jq. On Windows that means Git for Windows' bash, plus jq installed so
18
+ that it runs from that bash (Git for Windows does not include jq); WSL bash is not used.
19
+ Elsewhere, any bash with jq on its PATH.
20
+
21
+ Only the memory hooks receive the hook credential. When they do, they are also pinned to
22
+ ProofMEM (`HARNESS_MEMORY_PROVIDER` and `HARNESS_COORDINATION_STORE` = `caveaumem`), so an
23
+ exported value cannot send that session's memory to another store. The command guard, edit
24
+ checkpoint, lint and verify scripts run without the credential, and without any environment
25
+ variable whose name has a part (split at every non-letter, non-digit) that is `KEY`, `PAT`, `PWD`,
26
+ `PASS` or `AUTH`, or that ends in `TOKEN`, `SECRET`, `PASSWORD`, `PASSWD`, `PASSPHRASE`,
27
+ `CREDENTIAL`, `BEARER`, `APIKEY` or `JWT`: `GITHUB_TOKEN`, `AWS_SECRET_ACCESS_KEY`,
28
+ `NPM_CONFIG__AUTH`, `GITEA_PAT`, `SSH_AUTH_SOCK`, and so on. `PATH`, `HOME`, `PWD` and the other
29
+ process basics are always kept, and an `AUTH` part does not count in the Harness's own `HARNESS_*`
30
+ names, where it is a mode switch (`HARNESS_MEMORY_AUTH`).
31
+
32
+ Those four scripts also run without the editor's credential bridges, which hold no secret but let
33
+ a child process use your Git or SSH credentials anyway: `GIT_ASKPASS`, `SSH_ASKPASS`,
34
+ `SSH_ASKPASS_REQUIRE`, `SSH_AUTH_SOCK`, `GIT_SSH_COMMAND`, `GIT_SSH`, every `VSCODE_GIT_*` (the
35
+ askpass helper and its IPC handle back into the editor), and `GIT_CONFIG_PARAMETERS`,
36
+ `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_<n>` and `GIT_CONFIG_VALUE_<n>` (which can inject a credential
37
+ helper). The memory hooks keep them for SessionStart's Git refresh. If a trusted project's opt-in
38
+ verify build needs your SSH agent or Git sign-in, run that build yourself. A credential under any
39
+ other name, a credential helper your own Git config already names (such as Git Credential
40
+ Manager), and files such as `~/.npmrc` or `~/.aws/credentials` are not hidden from them.
41
+
42
+ The hook credential lasts 90 days; SessionStart and `doctor --antigravity` warn 14 days ahead.
43
+ Renew it by re-running the same `npx @bluenotelogic/harness init --antigravity ...` command,
44
+ never by exporting a token. To cut it off sooner, revoke it in the ProofMEM console at
45
+ `https://proofmem.com/app/keys.php`. Signing out of Blue Note ID does not cancel a key a client
46
+ already holds: it stays valid until it expires or is revoked there.
47
+
48
+ The installer's own sign-in leaves only the keys it creates on the server (the hook key, and a
49
+ 1-hour session key it reads your configuration with). Once it has your configuration it revokes
50
+ that sign-in's refresh grant, which through proofmem.com is an encrypted Blue Note ID refresh
51
+ token the gateway would otherwise keep for up to 35 days; if the server does not confirm, the
52
+ installer says so and the record lapses on its own. Antigravity's MCP sign-in is different: the
53
+ gateway keeps its refresh token, encrypted, so that Antigravity can stay signed in without asking
54
+ you again.
55
+
56
+ The Stop verification gate is off unless you installed with `--verify-gate`. When on, it runs the
57
+ open project's own build/test/lint whenever the agent stops, outside Antigravity's command
58
+ approval, so enable it only for projects you trust. An exported `HARNESS_VERIFY_GATE=0` or `=1`
59
+ overrides the install choice; an empty value counts as unset.
60
+
61
+ `enabledTools` in `mcp_config.json` controls which tools Antigravity offers. It is a convenience,
62
+ not a security boundary: ProofMEM enforces each token's scopes server-side. The hooks fail open:
63
+ a guard or memory error never blocks your work, so treat their warnings as diagnostics.
64
+
65
+ Run a read-only installation check with:
66
+
67
+ ```text
68
+ npx @bluenotelogic/harness doctor --antigravity --harness-home /path/to/caveau-harness-v2
69
+ ```
@@ -0,0 +1,77 @@
1
+ {
2
+ "proofmem-session-bootstrap": {
3
+ "enabled": true,
4
+ "SessionStart": [
5
+ {
6
+ "type": "command",
7
+ "command": "node ./scripts/antigravity-hook.mjs session-start",
8
+ "timeout": 40
9
+ }
10
+ ]
11
+ },
12
+ "proofmem-focused-memory": {
13
+ "enabled": true,
14
+ "PreInvocation": [
15
+ {
16
+ "type": "command",
17
+ "command": "node ./scripts/antigravity-hook.mjs prompt-context",
18
+ "timeout": 30
19
+ }
20
+ ]
21
+ },
22
+ "proofmem-command-guard": {
23
+ "enabled": true,
24
+ "PreToolUse": [
25
+ {
26
+ "matcher": "run_command",
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "node ./scripts/antigravity-hook.mjs pre-tool",
31
+ "timeout": 15
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ },
37
+ "proofmem-edit-checkpoint": {
38
+ "enabled": true,
39
+ "PreToolUse": [
40
+ {
41
+ "matcher": "write_file|edit_file|write_to_file|replace_file_content|multi_replace_file_content",
42
+ "hooks": [
43
+ {
44
+ "type": "command",
45
+ "command": "node ./scripts/antigravity-hook.mjs pre-edit",
46
+ "timeout": 15
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ },
52
+ "proofmem-post-edit": {
53
+ "enabled": true,
54
+ "PostToolUse": [
55
+ {
56
+ "matcher": "write_file|edit_file|write_to_file|replace_file_content|multi_replace_file_content",
57
+ "hooks": [
58
+ {
59
+ "type": "command",
60
+ "command": "node ./scripts/antigravity-hook.mjs post-edit",
61
+ "timeout": 60
62
+ }
63
+ ]
64
+ }
65
+ ]
66
+ },
67
+ "proofmem-stop-gate": {
68
+ "enabled": true,
69
+ "Stop": [
70
+ {
71
+ "type": "command",
72
+ "command": "node ./scripts/antigravity-hook.mjs stop",
73
+ "timeout": 220
74
+ }
75
+ ]
76
+ }
77
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
+ "name": "proofmem",
4
+ "description": "ProofMEM OAuth MCP plus Caveau Harness v2 lifecycle, memory, safety, and verification adapters for Google Antigravity."
5
+ }
@@ -0,0 +1,9 @@
1
+ # ProofMEM and Caveau Harness
2
+
3
+ - ProofMEM is the durable memory home shared by Antigravity, Claude Code, and Codex. Do not create a second persistent memory system in local markdown files.
4
+ - The SessionStart hook runs `bootstrap`. Do not run it again in the same conversation; use `context` or `persistent_recall` for later retrieval.
5
+ - Use `proposal_create` and `feedback_file` for governed learning. Do not bypass review controls with direct rewrites unless the user explicitly authorizes the change.
6
+ - Use scratch memory only for short-lived coordination and episodic memory for session events.
7
+ - Never put raw credentials in prompts, notes, scratch records, episodic events, committed files, or logs.
8
+ - If the ProofMEM MCP server returns `Unauthorized`, preserve its tokenless `serverUrl` configuration and start Antigravity's native OAuth/DCR flow. Never repair authentication by adding a bearer header, token, environment variable, or stdio bridge to `mcp_config.json`.
9
+ - Treat Harness hook warnings as actionable diagnostics. A fail-open memory warning does not waive repository tests or safety rules.