codex-grok-mcp 0.2.0-beta.5 → 0.2.0-beta.6
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/CONTRIBUTING.md +4 -1
- package/README.md +73 -20
- package/RELEASING.md +127 -0
- package/SECURITY.md +4 -2
- package/dist/bridge-companion.d.ts +6 -1
- package/dist/bridge-companion.js +166 -19
- package/dist/bridge-companion.js.map +1 -1
- package/dist/bridge-lifecycle.d.ts +44 -0
- package/dist/bridge-lifecycle.js +951 -0
- package/dist/bridge-lifecycle.js.map +1 -0
- package/dist/bridge-pairing.d.ts +5 -0
- package/dist/bridge-pairing.js +46 -4
- package/dist/bridge-pairing.js.map +1 -1
- package/dist/bridge-runtime.d.ts +30 -3
- package/dist/bridge-runtime.js +226 -19
- package/dist/bridge-runtime.js.map +1 -1
- package/dist/grok-cli.d.ts +5 -5
- package/dist/grok-cli.js +9 -10
- package/dist/grok-cli.js.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/relay-transport.js +13 -5
- package/dist/relay-transport.js.map +1 -1
- package/dist/schema.d.ts +5 -0
- package/dist/schema.js +3 -1
- package/dist/schema.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/relay/src/index.ts +11 -3
- package/relay/test/relay.test.ts +16 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -4,7 +4,8 @@ Thanks for helping keep this bridge small, safe, and dependable.
|
|
|
4
4
|
|
|
5
5
|
## Before opening a change
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Use the [bug report form](https://github.com/Fato07/codex-grok-mcp/issues/new?template=bug-report.yml) for reproducible defects.
|
|
8
|
+
- Open a [feature request](https://github.com/Fato07/codex-grok-mcp/issues/new?template=feature-request.yml) before adding a tool, adapter, dependency, authentication path, or supported platform.
|
|
8
9
|
- Keep `grok_ask` isolated from persistent Bot support.
|
|
9
10
|
- Never commit credentials, authentication files, private prompts, responses, transcripts, or unredacted logs.
|
|
10
11
|
- Never scrape Grok Bot state, decrypt descriptors, read Keychain, or infer gateway credentials.
|
|
@@ -41,6 +42,8 @@ npm pack --dry-run
|
|
|
41
42
|
|
|
42
43
|
Do not add postinstall scripts or telemetry. Version changes belong in release work, not ordinary feature pull requests.
|
|
43
44
|
|
|
45
|
+
For a stable release candidate, use the single maintainer checklist in [RELEASING.md](RELEASING.md).
|
|
46
|
+
|
|
44
47
|
## Compatibility claims
|
|
45
48
|
|
|
46
49
|
Mocks are not platform proof. A new supported environment needs a redacted live result containing OS, architecture, Node, Codex, Grok CLI, selected model, and a successful response. Do not include response content.
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://fato07.github.io/codex-grok-mcp/">Website</a> ·
|
|
9
9
|
<a href="https://www.npmjs.com/package/codex-grok-mcp">npm</a> ·
|
|
10
|
-
<a href="https://github.com/Fato07/codex-grok-mcp/releases/tag/v0.2.0-beta.
|
|
10
|
+
<a href="https://github.com/Fato07/codex-grok-mcp/releases/tag/v0.2.0-beta.6">v0.2.0-beta.6</a>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
An unofficial, local-first bridge that lets Codex ask Grok once or collaborate with named Grok Bots already running inside the Grok Bot app.
|
|
@@ -21,11 +21,11 @@ An unofficial, local-first bridge that lets Codex ask Grok once or collaborate w
|
|
|
21
21
|
|---|---|
|
|
22
22
|
| Isolated Grok CLI call | Public beta; live-tested on macOS |
|
|
23
23
|
| Persistent Grok Bot collaboration: list, read, wait, and exact-ID send | Experimental; live operator smoke test passed |
|
|
24
|
-
| Companion lifecycle |
|
|
24
|
+
| Companion lifecycle | Managed beta candidate; Linux CI passed, live Grok Bot VM validation pending |
|
|
25
25
|
| Linux isolated CLI path | Unverified |
|
|
26
26
|
| Windows, WSL, and Codex cloud | Unsupported or unverified |
|
|
27
27
|
|
|
28
|
-
The supported public beta is the exact npm package `codex-grok-mcp@0.2.0-beta.
|
|
28
|
+
The supported public beta is the exact npm package `codex-grok-mcp@0.2.0-beta.6` and its immutable GitHub prerelease.
|
|
29
29
|
|
|
30
30
|
## Quick start
|
|
31
31
|
|
|
@@ -33,13 +33,14 @@ You need:
|
|
|
33
33
|
|
|
34
34
|
- macOS;
|
|
35
35
|
- Node.js 20.19.2 or newer;
|
|
36
|
-
- Codex CLI or desktop
|
|
37
|
-
|
|
36
|
+
- Codex CLI or desktop.
|
|
37
|
+
|
|
38
|
+
For one-off `grok_ask` calls, install and sign in to Grok CLI (`grok --version` and `grok models`). Persistent Bot collaboration instead uses Grok Bot and the companion setup below.
|
|
38
39
|
|
|
39
40
|
Install the immutable marketplace release and plugin:
|
|
40
41
|
|
|
41
42
|
```bash
|
|
42
|
-
codex plugin marketplace add Fato07/codex-grok-mcp --ref v0.2.0-beta.
|
|
43
|
+
codex plugin marketplace add Fato07/codex-grok-mcp --ref v0.2.0-beta.6
|
|
43
44
|
codex plugin add codex-grok-mcp@codex-grok
|
|
44
45
|
```
|
|
45
46
|
|
|
@@ -51,12 +52,12 @@ Ask Grok to challenge this architecture and return the three strongest objection
|
|
|
51
52
|
|
|
52
53
|
That uses the one-off path. To work with Bots already running in Grok Bot, complete [the persistent Bot setup](#connect-codex-to-grok-bots).
|
|
53
54
|
|
|
54
|
-
The plugin runs only `codex-grok-mcp@0.2.0-beta.
|
|
55
|
+
The plugin runs only `codex-grok-mcp@0.2.0-beta.6` through `npx`. It does not change Grok authentication.
|
|
55
56
|
|
|
56
57
|
For direct MCP setup without the plugin wrapper:
|
|
57
58
|
|
|
58
59
|
```bash
|
|
59
|
-
codex mcp add grok -- npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
60
|
+
codex mcp add grok -- npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-mcp
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
Start a new Codex task after adding the server.
|
|
@@ -64,7 +65,7 @@ Start a new Codex task after adding the server.
|
|
|
64
65
|
## Check setup
|
|
65
66
|
|
|
66
67
|
```bash
|
|
67
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
68
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-mcp --doctor
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
Doctor checks the local executable, login, and selected model without sending a prompt. It must not print authentication material.
|
|
@@ -79,13 +80,21 @@ Codex -> local MCP server -> isolated Grok CLI -> xAI
|
|
|
79
80
|
|
|
80
81
|
`grok_ask` starts one constrained Grok CLI turn with a private temporary home. It cannot enter a persistent Bot conversation, use Bot memory, read files, run commands, use subagents, or search the web.
|
|
81
82
|
|
|
83
|
+
Each call may select one supported model. Omit `model` to use `GROK_MCP_MODEL`; provider, base URL, endpoint, and persistent Bot model settings are not accepted.
|
|
84
|
+
|
|
82
85
|
The persistent path is the collaborative mode. Codex can list named non-group Bots running inside Grok Bot, inspect one, send it a task once, wait for its activity state, and read its latest bounded messages. Codex can then continue its own work using that update while the Bot's ongoing conversation stays in Grok Bot.
|
|
83
86
|
|
|
84
87
|
This creates a practical `send -> wait -> read -> continue` loop. The bridge does not claim that a message answers a specific send or that an idle Bot completed its task.
|
|
85
88
|
|
|
86
89
|
The gateway token stays inside the Grok Bot VM. Codex and the companion connect outward to a self-hosted relay. Application frames are encrypted end to end; the relay forwards ciphertext and stores no messages.
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
## Architecture
|
|
92
|
+
|
|
93
|
+
[](https://fato07.github.io/codex-grok-mcp/architecture.html)
|
|
94
|
+
|
|
95
|
+
Both paths enter through the same local MCP server. Credentials stay at their endpoints, and uncertain writes are never retried automatically.
|
|
96
|
+
|
|
97
|
+
[Explore the interactive architecture](https://fato07.github.io/codex-grok-mcp/architecture.html) · [View the architecture source](docs/architecture.json)
|
|
89
98
|
|
|
90
99
|
## Tools
|
|
91
100
|
|
|
@@ -122,7 +131,7 @@ From the repository root on the Mac:
|
|
|
122
131
|
|
|
123
132
|
```bash
|
|
124
133
|
CODEX_GROK_RELAY_TOKEN="$RELAY_TOKEN" \
|
|
125
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
134
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- \
|
|
126
135
|
codex-grok-mcp pair --relay-url wss://YOUR-WORKER.workers.dev/v1/connect
|
|
127
136
|
unset RELAY_TOKEN
|
|
128
137
|
```
|
|
@@ -134,8 +143,8 @@ The command prints a private pairing code only in the interactive terminal.
|
|
|
134
143
|
In **Grok Bot's Computer** terminal, not in a Bot chat, run:
|
|
135
144
|
|
|
136
145
|
```bash
|
|
137
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
138
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
146
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge probe
|
|
147
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge connect
|
|
139
148
|
```
|
|
140
149
|
|
|
141
150
|
Paste the pairing code into the no-echo prompt. Keep the terminal running while using Bot tools.
|
|
@@ -145,8 +154,8 @@ Paste the pairing code into the no-echo prompt. Keep the terminal running while
|
|
|
145
154
|
Stop the foreground companion with `Ctrl-C`, then run the chosen exact version:
|
|
146
155
|
|
|
147
156
|
```bash
|
|
148
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
149
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
157
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge probe
|
|
158
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge run
|
|
150
159
|
```
|
|
151
160
|
|
|
152
161
|
For automatic beta updates on each restart, with the reproducibility tradeoff made explicit:
|
|
@@ -158,6 +167,45 @@ npx --yes --prefer-online --package=codex-grok-mcp@beta -- codex-grok-bridge run
|
|
|
158
167
|
|
|
159
168
|
This mutable command never edits pairing state or updates a running process. Prefer exact versions for audited or unattended environments. Roll back by stopping the companion and running a previously verified version.
|
|
160
169
|
|
|
170
|
+
### Managed lifecycle beta
|
|
171
|
+
|
|
172
|
+
`0.2.0-beta.6` introduces managed lifecycle commands. Linux CI covers the detached process path, while public support remains pending the redacted live Grok Bot VM gate.
|
|
173
|
+
|
|
174
|
+
After pairing, stop the old foreground companion once. Then install and start an exact lifecycle-capable release:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
VERSION=<exact-version>
|
|
178
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge install
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`status`, `start`, `stop`, and `ensure` are idempotent. `restart` intentionally performs a fresh cycle:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge status
|
|
185
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge start
|
|
186
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge stop
|
|
187
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge restart
|
|
188
|
+
npx --yes --package "codex-grok-mcp@${VERSION}" -- codex-grok-bridge ensure
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
An exact update stages and checks the replacement before the healthy process stops. The prior exact release stays available for one retry-safe rollback:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
NEXT_VERSION=<new-exact-version>
|
|
195
|
+
npx --yes --package "codex-grok-mcp@${NEXT_VERSION}" -- codex-grok-bridge update
|
|
196
|
+
npx --yes --package "codex-grok-mcp@${NEXT_VERSION}" -- codex-grok-bridge rollback
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The rollback operation uses the retained release, and a repeated rollback is a no-op. Pairing is read and revalidated, never rewritten. For VM resume recovery, a Grok Bot routine may run the exact pinned `ensure` command. Routine creation remains an explicit operator action.
|
|
200
|
+
|
|
201
|
+
To opt into the mutable beta channel for one update, make the channel visible in that command:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx --yes --prefer-online --package=codex-grok-mcp@beta -- codex-grok-bridge update
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The resolved release is stored as an exact version. Later `start`, `restart`, `ensure`, and `rollback` operations do not resolve a mutable channel.
|
|
208
|
+
|
|
161
209
|
## Collaborating safely with persistent Bots
|
|
162
210
|
|
|
163
211
|
1. Call `grok_bridge_status`, then use `grok_list_bots` to choose one exact Bot ID.
|
|
@@ -165,7 +213,7 @@ This mutable command never edits pairing state or updates a running process. Pre
|
|
|
165
213
|
3. Use `grok_send_bot_message` once for one exact target.
|
|
166
214
|
4. For all-Bot `PING`, preview the roster and review the native confirmation before accepting it.
|
|
167
215
|
|
|
168
|
-
Reads return sanitized text only.
|
|
216
|
+
Reads return sanitized text only. Attachments and other non-text transcript entries are omitted. Reads do not prove that a message answered a particular send or that a task finished. A successful send receipt means only that the gateway accepted the request. Timeouts and interrupted sends remain `outcome_unknown`; do not retry them automatically.
|
|
169
217
|
|
|
170
218
|
## Configuration
|
|
171
219
|
|
|
@@ -185,24 +233,29 @@ The plugin passes only these connector options. Pairing is stored in a private m
|
|
|
185
233
|
- **CLI missing or signed out:** run `grok --version`, `grok models`, and the pinned doctor command. Complete normal Grok login outside Codex.
|
|
186
234
|
- **`UPGRADE_REQUIRED`:** stop and restart the VM companion with the same package version as the connector.
|
|
187
235
|
- **`DATA_ROOT_SYMLINK`:** set `SAND_DATA_ROOT` to the real Grok Bot data directory, not a symlink. The companion rejects symlinked descriptor parents.
|
|
188
|
-
- **`companion_lease_stale`:** verify the recorded PID is
|
|
236
|
+
- **`companion_lease_stale`:** a lifecycle-capable managed install can run the exact pinned `ensure` command, which clears only a revalidated dead managed lease. For a foreground install, verify the recorded PID is gone before removing only the adjacent `bridge.json.lock`.
|
|
189
237
|
- **Uncertain send:** inspect the Bot before considering any new action. A retry may duplicate a message.
|
|
190
238
|
|
|
191
239
|
When reporting a bug, include redacted OS, architecture, Node, Codex, Grok CLI, and connector versions. Never attach authentication files, pairing codes, gateway/relay tokens, prompts, responses, transcripts, or private paths.
|
|
192
240
|
|
|
193
241
|
## Uninstall
|
|
194
242
|
|
|
195
|
-
1. Stop the
|
|
243
|
+
1. Stop the VM companion. Press `Ctrl-C` for a foreground process. For a managed beta.6 install, run:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge stop
|
|
247
|
+
```
|
|
248
|
+
|
|
196
249
|
2. In the VM terminal, remove its pairing:
|
|
197
250
|
|
|
198
251
|
```bash
|
|
199
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
252
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-bridge unpair
|
|
200
253
|
```
|
|
201
254
|
|
|
202
255
|
3. On the Mac, remove the local pairing:
|
|
203
256
|
|
|
204
257
|
```bash
|
|
205
|
-
npx --yes --package=codex-grok-mcp@0.2.0-beta.
|
|
258
|
+
npx --yes --package=codex-grok-mcp@0.2.0-beta.6 -- codex-grok-mcp unpair
|
|
206
259
|
```
|
|
207
260
|
|
|
208
261
|
4. Uninstall **Codex Grok MCP** in Codex. If configured directly, run `codex mcp remove grok`. Then remove the marketplace with `codex plugin marketplace remove codex-grok`.
|
package/RELEASING.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# v0.2.0 stable release gate
|
|
2
|
+
|
|
3
|
+
This is the sole maintainer checklist for promoting `codex-grok-mcp` from beta to stable. The default decision is **NO-SHIP** until every required item passes.
|
|
4
|
+
|
|
5
|
+
Run the checklist from a clean checkout of the final candidate commit. Every proof must name and come from that same 40-character commit SHA. Any source, test, lockfile, metadata, workflow, or documentation change creates a new candidate and invalidates earlier proof. Earlier beta results are context, not acceptance evidence.
|
|
6
|
+
|
|
7
|
+
Copy this file outside the candidate checkout to record results and evidence links. Never edit the candidate checkout while testing, because that would create a different candidate.
|
|
8
|
+
|
|
9
|
+
## Candidate identity
|
|
10
|
+
|
|
11
|
+
Record one immutable identity before testing:
|
|
12
|
+
|
|
13
|
+
| Field | Required value |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Package | `codex-grok-mcp@0.2.0` |
|
|
16
|
+
| Intended Git tag | `v0.2.0` |
|
|
17
|
+
| Final candidate commit | `<40-character SHA>` |
|
|
18
|
+
| Packed artifact | `codex-grok-mcp-0.2.0.tgz` |
|
|
19
|
+
| Artifact integrity | `<integrity from npm pack --json>` |
|
|
20
|
+
| Rollback package | `codex-grok-mcp@<previous verified exact version>` |
|
|
21
|
+
| Evidence record | `<durable URL>` |
|
|
22
|
+
|
|
23
|
+
- [ ] The checkout is clean and `HEAD` equals the recorded candidate commit.
|
|
24
|
+
- [ ] Package metadata, lockfiles, source version, plugin metadata, launcher pin, public documentation, packed manifest, and intended tag all identify `0.2.0`.
|
|
25
|
+
- [ ] The packed artifact was built from the recorded commit outside the checkout and matches the recorded SHA-512.
|
|
26
|
+
- [ ] Every live candidate install uses that artifact and verifies its SHA-512 first. No command uses `@beta`, `@latest`, or an unpinned branch.
|
|
27
|
+
|
|
28
|
+
## Required dependencies
|
|
29
|
+
|
|
30
|
+
Each dependency must be complete, included where applicable in the final candidate, and linked from the evidence record.
|
|
31
|
+
|
|
32
|
+
- [ ] [#4, one-command companion lifecycle and safe upgrade](https://github.com/Fato07/codex-grok-mcp/issues/4): exact-version install, status, update, restart, and rollback preserve pairing and recover the prior version after failure.
|
|
33
|
+
- [ ] [#5, clean install, upgrade, rollback, and uninstall](https://github.com/Fato07/codex-grok-mcp/issues/5): a clean Codex host and Grok Bot VM pass the full lifecycle with redacted receipts.
|
|
34
|
+
- [ ] [#6, reconnect, restart, and gateway-rotation soak](https://github.com/Fato07/codex-grok-mcp/issues/6): recovery is bounded, post-dispatch ambiguity remains `outcome_unknown`, and sends are not retried.
|
|
35
|
+
- [ ] [#7, invalid-pairing diagnostics](https://github.com/Fato07/codex-grok-mcp/issues/7): wrong-key failures are distinct from `UPGRADE_REQUIRED`, sanitized, and covered by the full suites.
|
|
36
|
+
- [ ] [#8, protected main and required CI](https://github.com/Fato07/codex-grok-mcp/issues/8): a test pull request proves the ruleset requires green CI for the candidate while retaining explicit maintainer recovery.
|
|
37
|
+
- [ ] [#9, release-metadata alignment check](https://github.com/Fato07/codex-grok-mcp/issues/9): the dependency-free check passes and reports exact file and field mismatches when deliberately tested.
|
|
38
|
+
|
|
39
|
+
## Supported environment
|
|
40
|
+
|
|
41
|
+
The stable claim is limited to the rows proven below. For `v0.2.0`, the host scope is macOS, Node support starts at `20.19.2`, and automated coverage is Node `20.19.2`, `22`, and `24` on macOS and Ubuntu. Linux is CI evidence only, not live isolated-CLI support. Windows, WSL, and Codex cloud remain unsupported or unverified unless the final candidate adds their own live evidence and updates the public support claim.
|
|
42
|
+
|
|
43
|
+
| Path | Exact evidence required |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Isolated `grok_ask` | macOS version and architecture; Node, Codex, Grok CLI, connector, and selected Grok model versions; successful doctor and one bounded response |
|
|
46
|
+
| Paired persistent Bots | macOS version and architecture; Grok Bot VM OS or image and architecture; host and VM Node versions; Codex, connector, companion, protocol, and Grok Bot app or host versions; successful lifecycle below |
|
|
47
|
+
|
|
48
|
+
- [ ] The evidence record contains every version and architecture named in each supported row, using `n/a` only when a component is not part of that path.
|
|
49
|
+
- [ ] Public support text matches only the live-proven rows and does not turn CI, mocks, or an earlier beta run into platform support.
|
|
50
|
+
|
|
51
|
+
## Automated candidate checks
|
|
52
|
+
|
|
53
|
+
Run from the clean candidate checkout and link the candidate-specific CI run or redacted log.
|
|
54
|
+
|
|
55
|
+
Ordinary pull-request and `main` CI stays deterministic and does not call npm's network-dependent audit service. Before tagging, manually dispatch the CI workflow against the exact candidate ref; audits run fail-closed on its Node 24 Ubuntu job. `v*` tag runs execute the same audit gate again.
|
|
56
|
+
|
|
57
|
+
- [ ] `npm ci` and `npm ci --prefix relay` complete from the committed lockfiles.
|
|
58
|
+
- [ ] `npm run test:all` passes. This includes the root build and core tests plus relay type checks and tests.
|
|
59
|
+
- [ ] `npm audit --omit=dev` passes.
|
|
60
|
+
- [ ] `npm audit --prefix relay` passes.
|
|
61
|
+
- [ ] `npm pack --dry-run` passes and its file list contains only intended publish content.
|
|
62
|
+
- [ ] `npm pack --json --pack-destination /path/outside/candidate-checkout` creates the one recorded artifact and integrity value without changing the checkout.
|
|
63
|
+
- [ ] The release-metadata alignment check from #9 passes.
|
|
64
|
+
- [ ] Required GitHub CI passes for Node `20.19.2`, `22`, and `24` on both macOS and Ubuntu at the candidate SHA.
|
|
65
|
+
|
|
66
|
+
## Live candidate checks
|
|
67
|
+
|
|
68
|
+
Use accounts and data the maintainer is authorized to use. Store only redacted receipts. Use separate clean environments for the two flows.
|
|
69
|
+
|
|
70
|
+
### Clean candidate flow
|
|
71
|
+
|
|
72
|
+
- [ ] On a clean host, install the exact candidate, start a fresh Codex task, discover the tools, run doctor, and complete one isolated `grok_ask` call.
|
|
73
|
+
- [ ] On a clean host and VM, create a new pairing without exposing it, then probe and start the exact candidate companion.
|
|
74
|
+
- [ ] From a fresh Codex task, verify status, list, bounded read, bounded wait, and one send to one exact non-group Bot ID with no retry.
|
|
75
|
+
- [ ] Stop and restart the exact candidate, then repeat status plus one read-only operation without pairing again.
|
|
76
|
+
- [ ] Uninstall the exact candidate last, and verify that only connector-owned configuration is removed. Grok authentication, Bot data, and unrelated files remain unchanged.
|
|
77
|
+
|
|
78
|
+
### Upgrade and rollback flow
|
|
79
|
+
|
|
80
|
+
- [ ] Starting from the recorded rollback version and a new pairing, exercise one controlled failed update and verify that version remains healthy and recoverable.
|
|
81
|
+
- [ ] Upgrade to the recorded candidate artifact, restart it, and repeat status plus one read-only operation without pairing again.
|
|
82
|
+
- [ ] Complete the #6 soak scenarios for relay reconnect, companion restart, VM idle and resume, gateway descriptor/process/token rotation, read and wait recovery, and one no-retry exact-ID send.
|
|
83
|
+
- [ ] Exercise the #7 wrong-key and valid-legacy cases and observe their distinct sanitized results.
|
|
84
|
+
- [ ] Roll back as specified below.
|
|
85
|
+
|
|
86
|
+
## Pairing-preserving rollback
|
|
87
|
+
|
|
88
|
+
1. Pair once on the recorded previous verified exact version.
|
|
89
|
+
2. Verify pairing-file byte identity and private permissions locally on both sides, recording only pass or fail, never the digest, file contents, or private path.
|
|
90
|
+
3. Attempt one controlled failed update before replacement becomes active. Verify the previous version remains healthy and recoverable.
|
|
91
|
+
4. Upgrade using the recorded candidate artifact, verify its SHA-512 and the active connector, companion, and protocol versions, then stop and restart it.
|
|
92
|
+
5. Roll back both sides to the recorded previous exact version. Do not run `pair`, `pair --force`, or `unpair`, and do not delete, replace, or regenerate pairing files.
|
|
93
|
+
6. Verify the previous versions, bridge status, and one read-only operation through the original pairing. Repeat the local byte-identity and permission check.
|
|
94
|
+
|
|
95
|
+
- [ ] The candidate passed this sequence, the original pairing remained byte-identical and usable, and a failed update left the previous version recoverable.
|
|
96
|
+
|
|
97
|
+
## Proof levels
|
|
98
|
+
|
|
99
|
+
Record these separately. Passing one never implies a later level.
|
|
100
|
+
|
|
101
|
+
| Proof | What it establishes | What it does not establish |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| Gateway acceptance | The exact-ID send received an accepted gateway receipt | Persistence, a reply, correlation, or completion |
|
|
104
|
+
| Transcript response observed | A later bounded Bot-authored transcript entry was observed | That the entry answers this send |
|
|
105
|
+
| Bot activity observed | A point-in-time activity state was read | Reply correlation or task completion |
|
|
106
|
+
| Task completion verified | A maintainer separately checked explicit task acceptance criteria or an artifact | A claim the bridge derives from acceptance, transcript order, or idle state |
|
|
107
|
+
|
|
108
|
+
- [ ] The live evidence uses all applicable proof labels and makes no stronger claim than the evidence supports.
|
|
109
|
+
|
|
110
|
+
## Evidence and redaction
|
|
111
|
+
|
|
112
|
+
Evidence may contain the candidate SHA, public software versions, OS and architecture, protocol numbers, timestamps, coarse results, CI URLs, and sanitized request identifiers.
|
|
113
|
+
|
|
114
|
+
- [ ] Before upload, inspect every receipt and remove prompts, responses, transcripts, Bot IDs or names, roster fingerprints, credentials, authentication data, pairing codes or files, channels, keys, tokens, gateway or relay URLs, environment values, private paths, and raw stdout or stderr bodies.
|
|
115
|
+
- [ ] Evidence links are durable, access-appropriate, and identify the candidate SHA and exact check without exposing private data.
|
|
116
|
+
|
|
117
|
+
## Decision
|
|
118
|
+
|
|
119
|
+
Select exactly one in the evidence record. A decision records the gate result; tagging, publishing, and changing a dist-tag are separate actions.
|
|
120
|
+
|
|
121
|
+
- [ ] **SHIP**: every required item above passed for the recorded candidate, all #4 through #9 dependencies are resolved, and no stable-release blocker remains.
|
|
122
|
+
- [ ] **NO-SHIP**: one or more items are unproved, stale, failed, unsafe to disclose, or tied to a different commit. Record the blocker and leave beta and release state unchanged.
|
|
123
|
+
|
|
124
|
+
- Maintainer: `<name>`
|
|
125
|
+
- Decision time (UTC): `<timestamp>`
|
|
126
|
+
- Candidate commit: `<40-character SHA>`
|
|
127
|
+
- Decision: `<SHIP or NO-SHIP>`
|
package/SECURITY.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Supported versions
|
|
4
4
|
|
|
5
|
-
`0.2.0-beta.
|
|
5
|
+
`0.2.0-beta.6` is the supported public beta. Security fixes target the current source revision and the next prerelease.
|
|
6
6
|
|
|
7
7
|
## Trust boundary
|
|
8
8
|
|
|
@@ -42,7 +42,9 @@ The persistent Bot adapter is registered only after a pairing file passes strict
|
|
|
42
42
|
|
|
43
43
|
Codex and the VM companion make outbound WebSocket connections. Before allocating a Durable Object, the included relay derives and checks the bearer for that exact channel and rejects browser-originated connections. Application frames use AES-256-GCM with random nonces and authenticated data binding the protocol version, channel, and sender role. The relay routes opaque frames between one `codex` and one `bridge` socket per channel, caps frames at 128 KiB, stores no payloads or credentials, and contains no payload logging. Default Cloudflare invocation logs and traces are explicitly disabled because the channel appears in the request path. The relay can still observe live connection timing, IP metadata, the random channel, and roles; it can drop, replay, or delay traffic, but it cannot decrypt or forge valid frames without the pairing key. The included deployment master is intended for one operator's self-hosted relay, not a shared public service.
|
|
44
44
|
|
|
45
|
-
Each request also carries an authenticated timestamp and UUID. The companion rejects requests older than 60 seconds before invoking the gateway, persists send UUIDs to a private bounded ledger before delivery, and caches authenticated responses in memory. The ledger uses a mode-`0700` persistent XDG state directory and mode-`0600` markers; unpairing does not remove fresh markers. A same-process duplicate receives the original receipt; a replay after restart is blocked and reported as `outcome_unknown`. One process-wide in-flight guard remains active across relay reconnects. An exclusive config-path lease prevents concurrent companions, forced re-pairing, or unpairing from racing a live process.
|
|
45
|
+
Each request also carries an authenticated timestamp and UUID. The companion rejects requests older than 60 seconds before invoking the gateway, persists send UUIDs to a private bounded ledger before delivery, and caches authenticated responses in memory. The ledger uses a mode-`0700` persistent XDG state directory and mode-`0600` markers; unpairing does not remove fresh markers. A same-process duplicate receives the original receipt; a replay after restart is blocked and reported as `outcome_unknown`. One process-wide in-flight guard remains active across relay reconnects. An exclusive config-path lease prevents concurrent companions, forced re-pairing, or unpairing from racing a live process. Generic stale leases fail closed. The managed lifecycle may clear only the same private lease after two identity checks prove its recorded Linux process is gone; failed-candidate cleanup also requires the exact launch token. Active or unknown identities are never cleared. The same UUID is also sent as the gateway `clientNonce`, but callers do not rely on undocumented host deduplication.
|
|
46
|
+
|
|
47
|
+
The managed lifecycle uses a detached Node child because the verified Grok Bot VM exposes no systemd, supervisord, or PM2 service manager. Install and update resolve the currently invoked package to one exact version, stage it under a private XDG data directory, validate its npm SHA-512 record, pairing identity, and local gateway before cutover, then wait for a private readiness receipt. Restart, ensure, and rollback use retained exact releases and do not resolve a mutable channel. The long-lived child receives only home and XDG paths, required Grok gateway discovery values, and its managed launch fields. It inherits no npm, provider, cloud, or unrelated application environment variables. Pairing is read before and after cutover but never copied, rewritten, or printed.
|
|
46
48
|
|
|
47
49
|
The companion uses a Node-20-compatible local client for a bounded loopback-only command set: discovery, health, `listAgents`, transcript-tail and activity-status reads, and exact-ID `sendPrompt`. The contract was cross-checked against the MIT-licensed `grokbot-sdk`; the full SDK is not installed because it declares Node.js 22 while the verified VM provides Node.js 20. Each whole bridge operation pins one verified descriptor/token snapshot, including its roster check and subsequent reads or send. Every subrequest verifies that snapshot before dispatch and again after the complete bounded body passes schema validation; rotation fails closed without retry. For a send, any failure after send dispatch remains delivery-uncertain. Standalone client calls outside a bridge operation resolve a fresh snapshot per request. The client also bounds response bytes and duration, rejects redirects and non-loopback URLs, normalizes an upstream wildcard bind advertisement to `127.0.0.1` instead of connecting to the wildcard address, validates descriptor ownership and permissions, verifies on Linux that the descriptor PID owns the listening socket, validates response shapes, and sanitizes errors. The gateway token stays in VM memory and is never returned to Codex or the relay. The companion does not expose arbitrary gateway commands, raw transcript rows, files, shell, delete/reset, or credential APIs. It refreshes the roster before every read or send.
|
|
48
50
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { type LocalAgentSummary, type LocalGatewayDiscovery, type LocalGatewayHealth, type LocalSendPromptInput } from "./grok-bot-client.js";
|
|
3
3
|
import { type BridgeRequest, type BridgeResponse } from "./bridge-protocol.js";
|
|
4
4
|
import { type PairingConfig } from "./bridge-pairing.js";
|
|
5
|
+
import { type LifecycleCommand, type LifecycleResult } from "./bridge-lifecycle.js";
|
|
5
6
|
export type BridgeProbeClient = {
|
|
6
7
|
discovery(): Pick<LocalGatewayDiscovery, "port" | "pid" | "hasToken">;
|
|
7
8
|
health(): Promise<Pick<LocalGatewayHealth, "ok" | "isBusy">>;
|
|
@@ -47,6 +48,10 @@ type Writer = {
|
|
|
47
48
|
};
|
|
48
49
|
type CliDependencies = {
|
|
49
50
|
createClient?: () => BridgeClient;
|
|
51
|
+
environment?: NodeJS.ProcessEnv;
|
|
52
|
+
lifecycle?: {
|
|
53
|
+
run(command: LifecycleCommand): Promise<LifecycleResult>;
|
|
54
|
+
};
|
|
50
55
|
readPairCode?: () => Promise<string>;
|
|
51
56
|
runBridge?: (config: PairingConfig, client: BridgeClient) => Promise<void>;
|
|
52
57
|
configPath?: string;
|
|
@@ -56,6 +61,6 @@ type CliDependencies = {
|
|
|
56
61
|
export declare function createBridgeProbeClient(): BridgeClient;
|
|
57
62
|
export declare function probeBridge(client: BridgeProbeClient): Promise<BridgeProbeResult>;
|
|
58
63
|
export declare function handleBridgeRequest(client: BridgeClient, request: BridgeRequest): Promise<BridgeResponse>;
|
|
59
|
-
export declare function runBridge(config: PairingConfig, client?: BridgeClient, signal?: AbortSignal, replayRoot?: string): Promise<void>;
|
|
64
|
+
export declare function runBridge(config: PairingConfig, client?: BridgeClient, signal?: AbortSignal, replayRoot?: string, onReady?: () => Promise<void>): Promise<void>;
|
|
60
65
|
export declare function runBridgeCompanion(argv: string[], dependencies?: CliDependencies): Promise<number>;
|
|
61
66
|
export {};
|