machine-bridge-mcp 1.2.7 → 1.2.9
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 +23 -0
- package/CONTRIBUTING.md +37 -19
- package/README.md +120 -410
- package/SECURITY.md +2 -0
- package/browser-extension/manifest.json +2 -2
- package/docs/ARCHITECTURE.md +13 -4
- package/docs/AUDIT.md +22 -0
- package/docs/ENGINEERING.md +2 -2
- package/docs/OVERVIEW.md +113 -0
- package/docs/PROJECT_STANDARDS.md +9 -5
- package/docs/RELEASING.md +78 -33
- package/docs/TESTING.md +14 -7
- package/docs/THREAT_MODEL.md +142 -0
- package/package.json +18 -6
- package/scripts/check-plan.mjs +91 -0
- package/scripts/coverage-check.mjs +22 -0
- package/scripts/github-push.mjs +49 -0
- package/scripts/github-release.mjs +15 -8
- package/scripts/local-release-acceptance.mjs +186 -0
- package/scripts/release-acceptance.mjs +181 -0
- package/scripts/release-impact-check.mjs +19 -3
- package/scripts/release-state.mjs +1 -1
- package/scripts/run-checks.mjs +29 -0
- package/scripts/start-release-candidate.mjs +113 -0
- package/src/local/agent-context-projection.mjs +158 -0
- package/src/local/agent-context.mjs +23 -332
- package/src/local/agent-skill-discovery.mjs +230 -0
- package/src/local/agent-text-file.mjs +41 -0
- package/src/local/browser-bridge-http.mjs +48 -0
- package/src/local/browser-bridge.mjs +48 -222
- package/src/local/browser-broker-routes.mjs +136 -0
- package/src/local/browser-broker-server.mjs +59 -0
- package/src/local/browser-request-registry.mjs +67 -0
- package/src/local/managed-job-lock.mjs +99 -0
- package/src/local/managed-job-projection.mjs +68 -0
- package/src/local/managed-job-runner.mjs +73 -0
- package/src/local/managed-job-storage.mjs +93 -0
- package/src/local/managed-jobs.mjs +12 -297
- package/src/local/runtime-paths.mjs +107 -0
- package/src/local/runtime-relay.mjs +73 -0
- package/src/local/runtime-tool-handlers.mjs +66 -0
- package/src/local/runtime.mjs +22 -204
- package/src/local/windows-launcher.mjs +57 -0
- package/src/local/windows-service.mjs +7 -56
- package/src/worker/index.ts +9 -118
- package/src/worker/mcp-jsonrpc.ts +94 -0
- package/src/worker/oauth-authorization-page.ts +70 -0
- package/src/worker/oauth-controller.ts +9 -58
- package/src/worker/websocket-protocol.ts +24 -0
- package/tsconfig.local.json +6 -1
package/SECURITY.md
CHANGED
|
@@ -27,6 +27,8 @@ CodeQL and OpenSSF Scorecard are enforced as gates, not merely uploaded as advis
|
|
|
27
27
|
|
|
28
28
|
## Core trust model
|
|
29
29
|
|
|
30
|
+
The concise security model is in [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md), including assets, attacker classes, explicit non-goals, and residual risks.
|
|
31
|
+
|
|
30
32
|
Trusted components are:
|
|
31
33
|
|
|
32
34
|
1. the local OS user running the runtime;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Machine Bridge Browser",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.9",
|
|
5
5
|
"description": "Connects the current Chromium browser profile to the local Machine Bridge runtime for user-authorized automation.",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"tabs",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"action": {
|
|
31
31
|
"default_title": "Machine Bridge Browser"
|
|
32
32
|
},
|
|
33
|
-
"version_name": "1.2.
|
|
33
|
+
"version_name": "1.2.9"
|
|
34
34
|
}
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
+
For a compact component map, read [System overview](OVERVIEW.md). Security assumptions, attacker models, non-goals, and residual risks are defined in [Threat model](THREAT_MODEL.md).
|
|
4
|
+
|
|
3
5
|
## Design goal
|
|
4
6
|
|
|
5
7
|
The system separates three questions that are often conflated:
|
|
@@ -32,6 +34,11 @@ A canonical workspace receives an independent profile, Worker name, secret set,
|
|
|
32
34
|
- `runtime-reporting.mjs` builds privacy-aware runtime and project snapshots;
|
|
33
35
|
- `runtime-diagnostics.mjs` owns fixed local probes and their stable interpretation;
|
|
34
36
|
- `runtime-capabilities.mjs` composes agent, application, and browser capability results;
|
|
37
|
+
- `runtime-tool-handlers.mjs` owns catalog-to-handler registration;
|
|
38
|
+
- `runtime-relay.mjs` owns relay construction and inbound envelope normalization;
|
|
39
|
+
- `runtime-paths.mjs` owns runtime-directory creation, containment checks, and error-path redaction;
|
|
40
|
+
- `managed-job-lock.mjs`, `managed-job-runner.mjs`, `managed-job-storage.mjs`, and `managed-job-projection.mjs` separate transition ownership, detached runner identity, private persistence/diagnostics, and public result shaping from the managed-job lifecycle;
|
|
41
|
+
- `browser-request-registry.mjs`, `browser-broker-routes.mjs`, `browser-broker-server.mjs`, and `browser-bridge-http.mjs` separate direct request ownership, runtime-client proxy routing, authenticated loopback WebSocket upgrades/listening, and loopback HTTP handling from broker startup and extension handover;
|
|
35
42
|
- managed jobs, local resources, application automation, and browser automation remain separate managers.
|
|
36
43
|
|
|
37
44
|
Architecture tests cap the orchestration module and each extracted service independently and reject a return of low-level process, patch, diagnostic, or capability-scoring logic to `LocalRuntime`. `RelayConnection` owns remote WebSocket transport, `hello_ack` authentication, end-to-end `relay_probe`/`ready_ack` readiness, heartbeat liveness, reconnect backoff, outage logging, and a monotonically increasing in-memory session generation. Every relayed tool result is bound to the generation that delivered its call; a disconnected generation cannot send a late result over its replacement socket. Inbound WebSocket dispatch captures that generation at receive time and passes it to the runtime handler, so a successful local tool execution can publish only on the same generation. Stdio mode invokes `LocalRuntime` directly without that adapter.
|
|
@@ -40,7 +47,7 @@ Architecture tests cap the orchestration module and each extracted service indep
|
|
|
40
47
|
|
|
41
48
|
### Agent context and capability resolver
|
|
42
49
|
|
|
43
|
-
`AgentContextManager` discovers the nearest Git/workspace scope, applies the user configuration and hierarchical `.machine-bridge/agent.json` files, selects built-in/user/root-to-target instructions, discovers bounded filesystem skills, and resolves registered commands. `agent-contract.mjs` is the strict checked-JavaScript boundary for configuration shape, registered-command normalization, encoded-size limits, and configured-path containment; the manager does not maintain a second parser. `project-package.mjs` owns no-follow package metadata parsing, package-manager selection (including fail-closed conflicting-lockfile handling), script-name normalization, bounded workflow-intent aliases, and automatic `package.*` command construction so instruction rendering and command execution do not duplicate package parsing. `default-instructions.mjs` supplies a versioned in-package working-agreement block and derives a small virtual project-context block from root filenames and bounded metadata. It reads package script names but not bodies, does not inspect dependency values or source contents, executes nothing, and writes no user/repository files. A global `model_instructions_file` is a separate user-designated session source and cannot be overridden by a project.
|
|
50
|
+
`AgentContextManager` discovers the nearest Git/workspace scope, applies the user configuration and hierarchical `.machine-bridge/agent.json` files, selects built-in/user/root-to-target instructions, discovers bounded filesystem skills, and resolves registered commands. `agent-context-projection.mjs` owns capability fingerprints, privacy-aware public projections, bounded skill summaries, command rendering, and effective-instruction rendering. `agent-skill-discovery.mjs` owns bounded skill-root traversal, symlink containment, metadata parsing, warnings, and file inventory; `agent-text-file.mjs` owns no-follow bounded UTF-8 reads. Filesystem/config discovery no longer maintains those output and skill-scanning mechanics inline. `agent-contract.mjs` is the strict checked-JavaScript boundary for configuration shape, registered-command normalization, encoded-size limits, and configured-path containment; the manager does not maintain a second parser. `project-package.mjs` owns no-follow package metadata parsing, package-manager selection (including fail-closed conflicting-lockfile handling), script-name normalization, bounded workflow-intent aliases, and automatic `package.*` command construction so instruction rendering and command execution do not duplicate package parsing. `default-instructions.mjs` supplies a versioned in-package working-agreement block and derives a small virtual project-context block from root filenames and bounded metadata. It reads package script names but not bodies, does not inspect dependency values or source contents, executes nothing, and writes no user/repository files. A global `model_instructions_file` is a separate user-designated session source and cannot be overridden by a project.
|
|
44
51
|
|
|
45
52
|
`session_bootstrap` is requested during both stdio and remote MCP initialization. The Worker delegates this read to the connected daemon with a short bounded timeout; failure falls back to static server instructions rather than blocking initialization indefinitely. `resolve_task_capabilities` performs a fresh deterministic scan, rebuilds automatic project facts, and ranks skill/command metadata for the current task. Application and browser capability metadata is added by `LocalRuntime`; installed application inventory uses a short bounded cache. `CapabilityObserver` records only counts, timestamps, source flags, selected metadata, match counts, recommended tool names, and a runtime-keyed task fingerprint so operators can verify routing without creating a task-content log.
|
|
46
53
|
|
|
@@ -103,7 +110,7 @@ All requests for a deployed Worker route to one named Durable Object. It owns:
|
|
|
103
110
|
- policy/tool metadata attached to the active socket;
|
|
104
111
|
- a bounded in-memory map of pending daemon calls.
|
|
105
112
|
|
|
106
|
-
`BridgeRoom` owns Durable Object routing, MCP dispatch, daemon WebSocket lifecycle, and pending relay calls. `OAuthController` owns OAuth-store pruning, registration throttling, authorization
|
|
113
|
+
`BridgeRoom` owns Durable Object routing, MCP dispatch, daemon WebSocket lifecycle, and pending relay calls. `mcp-jsonrpc.ts` owns JSON-RPC shape validation, result/error framing, MCP tool-result projection, session-instruction bounds, and protocol-header validation. `websocket-protocol.ts` owns record validation plus best-effort send/close/rejection helpers. `OAuthController` owns OAuth-store pruning, registration throttling, authorization submission, account-admin routing, token exchange, access-token verification, and the serialization queue for OAuth mutations. `oauth-authorization-page.ts` owns escaped authorization-page rendering and redirect-origin CSP input. Worker-internal TypeScript imports use explicit `.ts` specifiers and JSON import attributes, so the same modules are directly executable under the pinned Node runtime for focused state-machine tests as well as bundled by Wrangler.
|
|
107
114
|
|
|
108
115
|
The Worker verifies OAuth, validates MCP envelopes and optional protocol headers, converts `tools/call` into WebSocket messages, correlates cancellation by access-token hash and JSON-RPC ID, and formats text/structured/image results. Pending calls also bind the incoming request `AbortSignal`: an HTTP client disconnect removes the pending indexes and sends a best-effort daemon cancellation. The deployment contract explicitly enables Cloudflare `enable_request_signal` and `request_signal_passthrough` so the signal reaches the named Durable Object. It has no local filesystem or process API.
|
|
109
116
|
|
|
@@ -255,9 +262,11 @@ Cloudflare sampling is size control rather than an audit log. The project intent
|
|
|
255
262
|
|
|
256
263
|
## Release integrity
|
|
257
264
|
|
|
258
|
-
Repository-local checks are necessary but cannot prove
|
|
265
|
+
Repository-local automated checks are necessary but cannot prove that the maintainer's ordinary installation path works. `scripts/local-release-acceptance.mjs` builds the exact npm tarball, while `scripts/start-release-candidate.mjs` installs that tarball into an ignored isolated prefix and starts it in the foreground. The helper requires `--allow-worker-deploy` because normal startup may update the configured same-name Worker before relay verification. The repository owner starts the candidate; the coding agent verifies its live Worker version/hash, health, relay connection, local version, readiness, and representative behavior through Machine Bridge before recording both npm hashes outside the package. `scripts/github-push.mjs`, pull-request CI, and `scripts/github-release.mjs` rebuild the package and reject any mismatch. The release helper also requires `HEAD === origin/main`; it cannot silently push `main`.
|
|
266
|
+
|
|
267
|
+
Cross-platform evidence remains independent. `scripts/github-release.mjs` queries CI, CodeQL, Governance, and Scorecard for the exact `origin/main` commit and requires the newest push-triggered run for each workflow to be completed with `success` before it creates or verifies a version tag, GitHub Release, or package asset. Pull-request runs, older successful runs, pending runs, and successful runs for another SHA do not satisfy the gate. The workflow selection policy is isolated in `scripts/release-ci.mjs` and tested independently.
|
|
259
268
|
|
|
260
|
-
Third-party workflow actions are pinned to immutable commit SHAs. Dependabot
|
|
269
|
+
Third-party workflow actions are pinned to immutable commit SHAs. Dependabot groups GitHub Action updates into one reviewed PR so coupled action families cannot drift across versions. `architecture:test` rejects movable action tags, split update policy, loss of local acceptance verification, or removal of the reachable-history package-audit step.
|
|
261
270
|
|
|
262
271
|
## Explicit non-goals
|
|
263
272
|
|
package/docs/AUDIT.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Security and privacy audit notes
|
|
2
2
|
|
|
3
|
+
## 2026-07-18 version 1.2.9 interactive release-handoff correction
|
|
4
|
+
|
|
5
|
+
The release-integrity mechanism correctly bound acceptance to exact package bytes, but the operational role split was wrong. Documentation and repository guards required the owner to run the acceptance command personally and prohibited the coding agent from recording it. That contradicted the established working process: the owner should perform the one action the agent cannot perform honestly—start the exact candidate on the maintainer machine—while the agent should connect to that candidate, verify its version, readiness, and representative functionality, then record acceptance and complete source release operations.
|
|
6
|
+
|
|
7
|
+
Version 1.2.9 codifies that flow. `npm run release:candidate:start -- --allow-worker-deploy` verifies and installs the pending tarball into an ignored isolated prefix and launches it in the foreground without replacing the normal global installation. The explicit flag acknowledges that normal candidate startup may update the configured same-name Worker in place. The owner runs that command and leaves the process active. The coding agent must observe the live candidate through Machine Bridge; automated checks or an unobserved process are insufficient. After successful observation, the agent records the new `owner-started-agent-verified-local-candidate` marker, commits, pushes through the guarded command, completes the pull request, and runs `npm run release` to create or verify the annotated tag and GitHub Release. The old 1.2.8 owner-recorded marker remains accepted only for historical compatibility.
|
|
8
|
+
|
|
9
|
+
npm publication and Worker deployment remain owner-operated live release actions. The coding agent does not perform either as part of `npm run release`. Any packaged-byte change after candidate preparation invalidates the pending or recorded acceptance and requires another owner-started, agent-observed candidate run.
|
|
10
|
+
|
|
11
|
+
The first PR run exposed two release-infrastructure defects that local macOS validation could not certify. The layered runner spawned `npm.cmd` directly and failed with `EINVAL` under Node 26 on Windows; it now executes the integrity-pinned npm CLI through the current Node binary on every platform. The acceptance recorder also omitted the portable Git-content digest required by CI. It now constructs a temporary Git index from `HEAD` plus the complete working tree, computes the same canonical package digest used by CI, deletes the temporary index without changing the maintainer staging area, and makes local acceptance verification reject a missing digest. Both failures invalidate the earlier candidate and require a regenerated, re-observed candidate before release.
|
|
12
|
+
|
|
13
|
+
## 2026-07-17 version 1.2.8 release-integrity and dependency-automation audit
|
|
14
|
+
|
|
15
|
+
The core failure was procedural rather than a missing unit test: the repository treated a green automated suite as sufficient evidence for source publication, and `release:publish` could push a locally tested commit directly to `main`. That model cannot satisfy the reported history of formally released builds failing on the maintainer's real installation. It also assigned the coding agent authority to infer release acceptance, even though only the repository owner can observe the ordinary local environment and decide whether the product is usable.
|
|
16
|
+
|
|
17
|
+
Version 1.2.8 separates automated verification from owner acceptance. The candidate command runs the full suite and packs the exact artifact. The owner tests that tarball and records a fixed confirmation; a second pack must have identical npm SHA-1 and SHA-512 integrity before the tracked record is written. The record is outside the package manifest, so adding it and squash-merging do not alter the accepted bytes. Any packaged source, script, metadata, browser-extension, or shipped-documentation change invalidates the record. The guarded push command checks cleanliness, branch safety, tracking, and package hashes. CI repeats the hash check. Final release creation requires the same acceptance plus exact-commit CI, CodeQL, Governance, and Scorecard success, and it no longer contains a path that pushes `main`. The acceptance record is a reviewed process assertion, not a cryptographic identity signature; automation is explicitly prohibited from creating it on the owner's behalf.
|
|
18
|
+
|
|
19
|
+
The five open Dependabot PRs exposed a second design defect. The three CodeQL sub-actions were proposed independently even though CodeQL rejects mixed action versions, while every Action-only PR was forced through an npm release-impact gate that considered all repository files package changes. The combined update now keeps all CodeQL components on 4.37.1, updates setup-node to 7.0.0 and upload-artifact to 7.0.1, groups future GitHub Action updates, and derives npm release relevance from the package manifest. GitHub-only workflow maintenance can therefore be reviewed without inventing an npm version, while package content remains fail-closed. Official tag objects were resolved through GitHub and match every pinned SHA. The setup-node and upload-artifact majors move their action runtimes to Node 24/ESM without changing the inputs used here; CodeQL 4.37.1 advances the default bundle to 2.26.1. Architecture tests now require all three CodeQL action roles to share one immutable commit even if dependency automation regresses.
|
|
20
|
+
|
|
21
|
+
The broader pass rechecked dependency health, install-script policy, package contents, release scripts, workflow permissions, immutable Action pinning, source and test size guardrails, process/network boundary inventory, privacy scanning, documentation ownership, and existing architecture limits. Both complete and production npm audits report zero vulnerabilities, the dependency tree reports no structural problems, and Wrangler's only available patch was advanced to 4.112.0 with the exact new workerd install script reviewed and allowlisted. No credential-like tracked artifact beyond the deliberate non-secret repository `.npmrc` was found. Existing execution, relay, browser, state, ACL, logging, and lifecycle behavior remains covered by the prior risk-directed suites; this change does not claim OS CPU/memory/network isolation that the runtime does not implement.
|
|
22
|
+
|
|
23
|
+
No branch, tag, GitHub Release, npm package, Worker deployment, global installation, daemon/service replacement, credential change, or live state mutation is performed before the repository owner tests and accepts the 1.2.8 candidate.
|
|
24
|
+
|
|
3
25
|
## 2026-07-17 version 1.2.7 process-supervision and lifecycle audit
|
|
4
26
|
|
|
5
27
|
The core question in this review was not whether the existing green suite covered many paths; it was whether failure and ownership boundaries remained truthful when processes resist termination, startup is interrupted, proxy state is hostile, or the operating system refuses a spawn. The audit found that generic argv validation and process-tree termination had drifted into the interactive-session module, while shell and managed-job paths maintained adjacent termination branches. This created a dependency inversion: one-shot execution and process accounting depended on an adapter whose responsibility should have been only interactive session state.
|
package/docs/ENGINEERING.md
CHANGED
|
@@ -9,7 +9,7 @@ This document records project-wide decisions that must survive individual fixes,
|
|
|
9
9
|
3. **Machine Bridge authority and host authority are separate.** `full` removes Machine Bridge's own policy, path, shell, and environment restrictions. It cannot override an MCP host, connector gateway, operating system, endpoint-security product, cloud IAM, remote authentication, or `sudo`.
|
|
10
10
|
4. **Publication surfaces contain no real environment metadata.** Source, tests, fixtures, examples, release notes, filenames, package contents, tags, and release assets use synthetic identifiers and reserved example domains.
|
|
11
11
|
5. **Secrets are never operational log data.** Tool arguments, command text, stdin, stdout, stderr, file content, OAuth bodies, credentials, and local resource values are not logged.
|
|
12
|
-
6. **A release is one
|
|
12
|
+
6. **A release is one owner-started, agent-verified package with successful cross-platform evidence.** The repository owner starts the exact npm candidate on the maintainer machine; the coding agent verifies the connected candidate version, readiness, and representative functionality through Machine Bridge and then records the package hashes before the first GitHub push. Package metadata, Worker version, browser-extension version/name, acceptance record, Git tag, GitHub Release, npm version, documentation, and deployed health version must agree, and the exact `origin/main` commit must have completed successful push-triggered CI, CodeQL, Governance, and OpenSSF Scorecard runs before a tag or release is created.
|
|
13
13
|
7. **Generic local automation is structured, not arbitrary evaluation.** Browser/application features may expose broad user authority under canonical `full`, but must not accept caller-provided JavaScript, AppleScript, JXA, or extension code.
|
|
14
14
|
8. **Daily-browser integration uses the existing profile.** The supported primary browser path is the packaged authenticated extension and machine-level loopback broker, preserving current tabs/login state; a separate automation profile is not an equivalent replacement.
|
|
15
15
|
9. **Pairing and resource secrets are not conversation or log data.** Tokens and injected local-resource values must not be returned, embedded in URLs, or written to operational logs.
|
|
@@ -24,7 +24,7 @@ A proposed change that conflicts with an invariant requires an explicit owner de
|
|
|
24
24
|
|
|
25
25
|
## Change and release-operation ownership
|
|
26
26
|
|
|
27
|
-
Repository source release completion and live release operations are separate responsibilities. Under
|
|
27
|
+
Repository implementation, interactive candidate acceptance, source release completion, and live release operations are separate responsibilities. Under `AGENTS.md`, coding automation may edit, test, and commit locally, generate an exact candidate tarball, and give the owner `npm run release:candidate:start -- --allow-worker-deploy`. The owner explicitly authorizes the in-place update of the configured same-name Worker, starts that candidate, and leaves it running. The agent verifies the deployed Worker version/hash, remote health, relay readiness, and connected local candidate through Machine Bridge and may then record `release-acceptance/v<version>.json`, push only through `npm run github:push`, complete the pull request through local `git`/`gh`, and create the annotated version tag plus final GitHub Release with `npm run release` after the accepted package hash and exact `main` checks pass. Automated checks without an observed live candidate do not authorize acceptance. `npm run release` never pushes `main`. Automation must not publish or alter npm packages, install globally outside the isolated candidate prefix, deploy or reconfigure a Worker as a release operation, rotate credentials, mutate live deployment state, or replace daemon/service state without explicit user authorization.
|
|
28
28
|
|
|
29
29
|
The normal handoff is: the repository owner publishes the reviewed npm version, then runs `npm install -g --omit=optional --allow-scripts=esbuild,workerd,sharp,fsevents machine-bridge-mcp@latest && machine-mcp`. The npm command updates the global CLI but cannot hot-reload an existing Node process. The subsequent normal foreground startup validates the Worker deployment hash, expected version, and health, requests shutdown of an active autostart daemon, waits a bounded interval for its lock, redeploys when necessary, and then takes over with the installed version. Live operations require explicit authorization even when they appear to be the obvious next release step.
|
|
30
30
|
|
package/docs/OVERVIEW.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# System overview
|
|
2
|
+
|
|
3
|
+
Machine Bridge is one local authority surface with two MCP transports. The architecture is organized around three independent questions:
|
|
4
|
+
|
|
5
|
+
1. **Who may request an operation?** Remote OAuth account identity and role, or the local process identity that launched stdio.
|
|
6
|
+
2. **Which tools are exposed?** The shared tool catalog, policy profile, and account-role intersection.
|
|
7
|
+
3. **What can an exposed tool actually do?** The local runtime, workspace/path rules, operating-system user authority, and platform security controls.
|
|
8
|
+
|
|
9
|
+
Transport authentication does not create an operating-system sandbox. The local daemon executes with the authority of its OS user.
|
|
10
|
+
|
|
11
|
+
## Components
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart LR
|
|
15
|
+
HC[Hosted MCP client] -->|HTTPS + OAuth 2.1 / PKCE| W[Cloudflare Worker]
|
|
16
|
+
W --> DO[Durable Object room]
|
|
17
|
+
DO -->|Authenticated outbound WebSocket| R[LocalRuntime]
|
|
18
|
+
|
|
19
|
+
LC[Local MCP client] -->|stdio| S[stdio adapter]
|
|
20
|
+
S --> R
|
|
21
|
+
|
|
22
|
+
R --> PG[PolicyGate + account access]
|
|
23
|
+
PG --> TE[ToolExecutor]
|
|
24
|
+
TE --> FS[Workspace file service]
|
|
25
|
+
TE --> PS[Process services]
|
|
26
|
+
TE --> MJ[Managed jobs]
|
|
27
|
+
TE --> AC[Agent context]
|
|
28
|
+
TE --> BA[Browser/app automation]
|
|
29
|
+
|
|
30
|
+
BA --> BB[Loopback browser broker]
|
|
31
|
+
BB --> EX[Packaged Chromium extension]
|
|
32
|
+
|
|
33
|
+
R --> OS[Local OS user authority]
|
|
34
|
+
MJ --> ST[Owner-only local state]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Authority flow
|
|
38
|
+
|
|
39
|
+
### Remote transport
|
|
40
|
+
|
|
41
|
+
1. The Worker validates OAuth client, token, account state, role, resource binding, and MCP session state.
|
|
42
|
+
2. The Worker filters advertised tools by account role and the daemon-reported capability ceiling.
|
|
43
|
+
3. The Durable Object relays a bounded tool envelope over the authenticated daemon socket.
|
|
44
|
+
4. The local runtime revalidates account authorization, policy, call lifecycle, timeout, and cancellation.
|
|
45
|
+
5. The selected local service executes with the daemon OS user's authority.
|
|
46
|
+
|
|
47
|
+
The Worker never receives ambient filesystem or process authority. It receives only explicit request/result messages.
|
|
48
|
+
|
|
49
|
+
### Local stdio transport
|
|
50
|
+
|
|
51
|
+
The MCP host launches the package as a subprocess. There is no remote OAuth layer. The selected local policy still controls catalog exposure and execution, while the OS process identity supplies the underlying filesystem and process authority.
|
|
52
|
+
|
|
53
|
+
## Shared contracts
|
|
54
|
+
|
|
55
|
+
The main protocol and policy single sources of truth are:
|
|
56
|
+
|
|
57
|
+
- `src/shared/tool-catalog.json` — tool names, schemas, policy requirements, and annotations;
|
|
58
|
+
- `src/shared/policy-contract.json` — canonical profiles and capability composition;
|
|
59
|
+
- `src/shared/server-metadata.json` — server identity and protocol metadata.
|
|
60
|
+
|
|
61
|
+
Local and Worker code consume these contracts. Generated references and drift tests prevent documentation and implementation from silently diverging.
|
|
62
|
+
|
|
63
|
+
## Local runtime boundaries
|
|
64
|
+
|
|
65
|
+
`LocalRuntime` is an orchestrator, not a low-level implementation module. It composes:
|
|
66
|
+
|
|
67
|
+
- policy and account authorization;
|
|
68
|
+
- call registration, timeout, cancellation, and observability;
|
|
69
|
+
- workspace and path services;
|
|
70
|
+
- direct and shell process execution;
|
|
71
|
+
- Git operations;
|
|
72
|
+
- managed jobs and local resources;
|
|
73
|
+
- Agent context and capability resolution;
|
|
74
|
+
- application and browser automation;
|
|
75
|
+
- remote relay adaptation.
|
|
76
|
+
|
|
77
|
+
Low-level responsibilities remain in focused modules. Architecture tests enforce an acyclic local import graph, domain/adapter direction, and module-size budgets. Behavior and fault-injection tests remain authoritative; source-shape checks are supplementary.
|
|
78
|
+
|
|
79
|
+
## State and lifecycle
|
|
80
|
+
|
|
81
|
+
Each canonical workspace has independent profile state, Worker identity, credentials, locks, service metadata, and managed jobs. State mutations use owner-only files where supported, bounded reads, atomic replacement, and process-identity-aware locks.
|
|
82
|
+
|
|
83
|
+
The relay distinguishes connectivity, authentication, readiness probing, and active service. A candidate daemon must complete an end-to-end probe before replacing an incumbent. Disconnect cancels relay-owned calls and terminates associated local processes.
|
|
84
|
+
|
|
85
|
+
Managed jobs use a separate durable lifecycle. Their plans are integrity-bound, runners are process-identity checked, transitions are lock-protected, terminal plans are scrubbed, and recovery is bounded.
|
|
86
|
+
|
|
87
|
+
## Browser execution model
|
|
88
|
+
|
|
89
|
+
The local browser broker binds only to loopback and authenticates the packaged extension with local pairing state and a versioned capability handshake. Additional runtime processes may proxy through the machine-level broker rather than opening competing extension connections.
|
|
90
|
+
|
|
91
|
+
The extension controls the Chromium profile into which it is loaded. Machine Bridge does not launch, isolate, or prove the identity of that profile. Browser cookies, sessions, tabs, and page content therefore remain part of the local user's browser authority.
|
|
92
|
+
|
|
93
|
+
## Verification layers
|
|
94
|
+
|
|
95
|
+
The repository uses several complementary layers:
|
|
96
|
+
|
|
97
|
+
- unit and behavior tests for policy, parsing, state, lifecycle, and services;
|
|
98
|
+
- fault injection and property tests for security-sensitive boundaries;
|
|
99
|
+
- live stdio and Worker/OAuth/MCP integration tests;
|
|
100
|
+
- cross-platform service and installation tests;
|
|
101
|
+
- per-module critical coverage thresholds;
|
|
102
|
+
- architecture/import/line-budget checks;
|
|
103
|
+
- privacy, package, release-impact, interactive-candidate-acceptance, CodeQL, dependency, and Scorecard gates.
|
|
104
|
+
|
|
105
|
+
`npm run check:fast` is the development feedback loop. `npm run check` runs the complete release-relevant suite.
|
|
106
|
+
|
|
107
|
+
## Read next
|
|
108
|
+
|
|
109
|
+
- [Architecture](ARCHITECTURE.md) for detailed invariants and protocol flow
|
|
110
|
+
- [Threat model](THREAT_MODEL.md) for assets, attackers, non-goals, and residual risks
|
|
111
|
+
- [Security policy](../SECURITY.md) for reporting and supported security boundaries
|
|
112
|
+
- [Engineering](ENGINEERING.md) for implementation rules
|
|
113
|
+
- [Testing](TESTING.md) for verification design
|
|
@@ -18,11 +18,15 @@ Branch names use a short category and purpose, for example `feat/browser-downloa
|
|
|
18
18
|
|
|
19
19
|
Direct pushes to `main`, force pushes, and branch deletion are blocked by repository protection. An exception requires an incident record and an explicit owner decision.
|
|
20
20
|
|
|
21
|
-
### Completion ownership
|
|
21
|
+
### Completion ownership and local acceptance
|
|
22
22
|
|
|
23
|
-
Repository automation owns
|
|
23
|
+
Repository automation owns implementation, local validation, observed candidate verification, acceptance recording, and pull-request completion. For every npm-package change, automation generates the exact candidate tarball with `npm run release:candidate` and stops before the first GitHub push. The repository owner explicitly authorizes the live candidate Worker update and runs `npm run release:candidate:start -- --allow-worker-deploy` on the maintainer machine and leaves the candidate running. The coding agent verifies the deployed Worker version/hash, remote health, relay readiness, connected local version, and representative functionality through Machine Bridge, then records a passing decision with `npm run release:accept -- --confirm "I VERIFIED machine-bridge-mcp <version> CANDIDATE ON THE OWNER MACHINE AND IT WORKS"`. Automated checks or an unobserved process are not sufficient evidence.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
The tracked `release-acceptance/v<version>.json` record binds the observed result to the npm tarball SHA-1 and SHA-512 integrity value. The record is excluded from the package, so a content-preserving squash merge does not invalidate it; any source, executable script, package metadata, or packaged-documentation change produces a different package hash and requires a regenerated candidate and another observed live verification. `npm run github:push`, pull-request CI, and `npm run release` verify the record. Raw direct pushes of release-relevant branches are prohibited.
|
|
26
|
+
|
|
27
|
+
After interactive acceptance, repository automation may push only through `npm run github:push`, open and complete the pull request, verify the resulting `main` commit, remove the merged branch, and run `npm run release`. Every npm-package change advances the package version and is completed by an annotated `v<version>` tag plus a final GitHub Release for the exact successful `main` commit. GitHub-only repository infrastructure changes that do not alter npm package contents do not require a synthetic npm version or local runtime acceptance, but they still require review and their applicable CI/security checks.
|
|
28
|
+
|
|
29
|
+
The coding agent performs the acceptance-record, tag, and GitHub Release work only after observed live verification and exact-commit checks succeed. npm publication, Worker deployment, credential mutation, non-isolated global installation, and daemon/service replacement remain separate live operations performed by the repository owner.
|
|
26
30
|
|
|
27
31
|
### Local GitHub control plane
|
|
28
32
|
|
|
@@ -115,10 +119,10 @@ Flaky tests are defects. A retry may diagnose environmental instability but may
|
|
|
115
119
|
## 7. Security and software supply chain
|
|
116
120
|
|
|
117
121
|
- GitHub workflow permissions default to read-only and are expanded per job only when required.
|
|
118
|
-
- Third-party Actions are pinned to immutable commit SHAs and reviewed when Dependabot updates them.
|
|
122
|
+
- Third-party Actions are pinned to immutable commit SHAs and reviewed when Dependabot updates them. GitHub Action updates are grouped into one atomic pull request so coupled suites such as CodeQL cannot be split across incompatible versions.
|
|
119
123
|
- npm dependencies use exact versions and a committed lockfile. Source bootstrap uses `npm ci`; the CI npm baseline itself is downloaded from an exact URL and verified against a pinned SHA-512 SRI before use. Registry signatures and attestations are verified in CI.
|
|
120
124
|
- Dependency review blocks newly introduced vulnerable dependencies. CodeQL performs JavaScript/TypeScript and workflow analysis. OpenSSF Scorecard audits supply-chain posture, and both SARIF streams are failing gates with exact, expiring exceptions rather than advisory-only uploads.
|
|
121
|
-
- CI generates and validates a CycloneDX SBOM. Release artifacts must be reproducible from a reviewed commit and tied to successful exact-commit CI, CodeQL, Governance, and Scorecard evidence.
|
|
125
|
+
- CI generates and validates a CycloneDX SBOM. Release artifacts must match the repository-owner-tested tarball hash, be reproducible from a reviewed commit, and be tied to successful exact-commit CI, CodeQL, Governance, and Scorecard evidence.
|
|
122
126
|
- Secret scanning and push protection are enabled. Repository examples use synthetic identities and reserved domains; reachable history is scanned before release.
|
|
123
127
|
- Long-lived publication tokens should be replaced by npm trusted publishing with GitHub OIDC. Until that external registry configuration is completed, release credentials remain an explicit operator responsibility and must never be stored in the repository.
|
|
124
128
|
- Security reports follow [SECURITY.md](../SECURITY.md), not public issue templates.
|
package/docs/RELEASING.md
CHANGED
|
@@ -2,58 +2,105 @@
|
|
|
2
2
|
|
|
3
3
|
The release invariant is:
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
5
|
+
- the repository owner started the exact npm tarball represented by `release-acceptance/v<version>.json` on the maintainer machine, and the coding agent observed the live candidate through Machine Bridge before recording a passing result;
|
|
6
|
+
- the current package produces the same SHA-1 and SHA-512 integrity values as that accepted tarball;
|
|
7
|
+
- `main` points to the release commit, and that exact commit has completed successful push-triggered CI, CodeQL, Governance, and OpenSSF Scorecard runs;
|
|
8
|
+
- `v<package version>` points to that same commit locally and on GitHub;
|
|
9
|
+
- a final GitHub Release exists for the tag and contains the accepted npm tarball;
|
|
10
|
+
- `package.json`, `package-lock.json`, the Worker-reported version, and `browser-extension/manifest.json` (`version`/`version_name`) agree;
|
|
11
|
+
- every npm-package change since the prior version tag has a higher package version and matching CHANGELOG section;
|
|
12
|
+
- the same accepted package content is present on GitHub and in a new npm version.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
A green automated suite is necessary but is not evidence that the maintainer's ordinary installation path works. The repository therefore separates automated validation from observed live candidate verification and binds both to the final package bytes.
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
+
## Change classification
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
A change is **npm-package relevant** when it alters `package.json`, `package-lock.json`, or a path included by the package `files` manifest. Source, runtime scripts, browser extension files, shared contracts, shipped documentation, and package metadata therefore require a new version and local acceptance.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
A repository-only change under paths such as `.github/` may be merged without a synthetic npm version when the package bytes are unchanged. It still requires review and all applicable GitHub checks. `scripts/release-impact-check.mjs` implements this distinction from the package manifest rather than from a duplicated path list.
|
|
20
21
|
|
|
21
|
-
## Prepare
|
|
22
|
+
## Prepare the candidate locally
|
|
22
23
|
|
|
23
|
-
1. Set the new version without creating
|
|
24
|
+
1. Set the new version without creating a tag. The npm version hook synchronizes the Worker and browser-extension versions:
|
|
24
25
|
|
|
25
26
|
```sh
|
|
26
27
|
npm version <version> --no-git-tag-version
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
2. Add the matching dated `CHANGELOG.md` section.
|
|
30
|
-
3. Run
|
|
31
|
-
4. Inspect the complete diff
|
|
30
|
+
2. Add the matching dated `CHANGELOG.md` section and update affected documentation and audit notes.
|
|
31
|
+
3. Run the required dependency, privacy, Worker, and package checks while iterating.
|
|
32
|
+
4. Inspect the complete diff.
|
|
33
|
+
5. Generate the final candidate:
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
```sh
|
|
36
|
+
npm run release:candidate
|
|
37
|
+
```
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
`release:candidate` runs the complete repository suite and then writes the exact npm tarball plus a bounded pending manifest under ignored `.release-candidate/`. Do not modify a packaged file after generating the candidate without regenerating and retesting it.
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
## Interactive local candidate acceptance
|
|
42
|
+
|
|
43
|
+
The repository owner starts the exact `.release-candidate/*.tgz` artifact on the maintainer machine with:
|
|
38
44
|
|
|
39
45
|
```sh
|
|
40
|
-
npm run release:
|
|
46
|
+
npm run release:candidate:start -- --allow-worker-deploy
|
|
41
47
|
```
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
This command verifies the pending tarball hashes, installs it into the ignored `.release-candidate/runtime/` prefix without replacing the normal global installation, explicitly authorizes startup to update the configured same-name Worker when its version or deployment hash differs, and starts the installed candidate in the foreground. This is an in-place live candidate deployment, not an isolated staging Worker. The owner leaves that process running. The coding agent then connects through Machine Bridge and verifies at minimum:
|
|
50
|
+
|
|
51
|
+
- the remote Worker reports the candidate version and the persisted deployment hash matches the candidate Worker bundle;
|
|
52
|
+
- the remote health route succeeds without redirect;
|
|
53
|
+
- the connected runtime reports the candidate package version;
|
|
54
|
+
- relay readiness is healthy through the deployed Worker for the intended transport;
|
|
55
|
+
- one representative read-only operation succeeds;
|
|
56
|
+
- representative changed functionality succeeds, including browser, application, service, proxy, credential, or platform-specific behavior when relevant.
|
|
44
57
|
|
|
45
|
-
|
|
58
|
+
The owner does not run the acceptance command. After the coding agent has observed the live candidate passing those checks, the agent records the decision using the exact phrase printed by `release:candidate`, for example:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
npm run release:accept -- --confirm "I VERIFIED machine-bridge-mcp 1.2.9 CANDIDATE ON THE OWNER MACHINE AND IT WORKS"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This creates `release-acceptance/v<version>.json` containing package identity, npm tarball hashes, a portable Git-content digest, timestamp, result, and a fixed observed-verification marker. The portable digest is computed with a temporary Git index containing `HEAD` plus the complete working tree; the real staging area is not modified. The record does not store a personal name, machine path, command output, credential, or user content. It is intentionally excluded from the npm package, so adding it does not change the tested tarball.
|
|
65
|
+
|
|
66
|
+
The command repacks the current tree and refuses to record acceptance if any packaged byte changed after candidate preparation. Automated tests alone, a prepared tarball, a process the agent did not observe, or an ambiguous owner response do not authorize acceptance. Version 1.2.8 owner-recorded acceptance remains supported as a historical marker; version 1.2.9 and later require the owner-started, agent-observed workflow.
|
|
67
|
+
|
|
68
|
+
## Push and review
|
|
69
|
+
|
|
70
|
+
Commit the candidate changes and acceptance record, then push the branch only through:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
npm run github:push
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The command requires a clean non-`main` branch, verifies that the acceptance record is tracked, rebuilds the npm package, compares both hashes, and only then executes a non-force push of the current branch. Direct pushes to `main` remain prohibited. Any packaged-file change after acceptance invalidates the hash and blocks the next push until the owner retests a regenerated candidate.
|
|
77
|
+
|
|
78
|
+
Open a pull request, satisfy the required checks, and squash-merge. Pull-request CI repeats the acceptance verification. A content-preserving squash changes the Git commit but not the package bytes, so the accepted hash remains valid.
|
|
79
|
+
|
|
80
|
+
## Complete the GitHub source release
|
|
81
|
+
|
|
82
|
+
From a clean, fast-forwarded `main` worktree whose `HEAD` exactly equals `origin/main`:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npm run release
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`npm run release` never pushes `main`. `release:publish` remains a compatibility alias. It verifies the interactive candidate acceptance, runs the complete project and version checks, requires successful exact-commit push runs for CI, CodeQL, Governance, and Scorecard, creates or verifies the annotated version tag, pushes only the version tag when absent, builds the npm tarball, creates or updates the final GitHub Release, uploads the tarball, and verifies the resulting state.
|
|
89
|
+
|
|
90
|
+
To verify an already completed source release without changing anything:
|
|
46
91
|
|
|
47
92
|
```sh
|
|
48
93
|
npm run release:check
|
|
49
94
|
```
|
|
50
95
|
|
|
51
|
-
To create GitHub Release records for
|
|
96
|
+
To create GitHub Release records for historical remote tags that lack releases:
|
|
52
97
|
|
|
53
98
|
```sh
|
|
54
99
|
npm run release:backfill
|
|
55
100
|
```
|
|
56
101
|
|
|
102
|
+
Backfill is historical metadata repair. It does not retroactively claim that releases predating the 1.2.8 acceptance policy had a recorded local acceptance.
|
|
103
|
+
|
|
57
104
|
## Publish npm
|
|
58
105
|
|
|
59
106
|
Only after `release:check` succeeds:
|
|
@@ -62,18 +109,16 @@ Only after `release:check` succeeds:
|
|
|
62
109
|
npm publish --access public
|
|
63
110
|
```
|
|
64
111
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
## Authentication requirements
|
|
112
|
+
`prepublishOnly` repeats the complete checks and GitHub synchronization check. npm publication remains a deliberate release-operator action and is not authorized by an ordinary source change.
|
|
68
113
|
|
|
69
|
-
|
|
70
|
-
- An authenticated GitHub CLI session with repository release permission.
|
|
71
|
-
- An npm account that owns the package or has maintainer permission.
|
|
114
|
+
## Authentication and external controls
|
|
72
115
|
|
|
73
|
-
|
|
116
|
+
Required local access:
|
|
74
117
|
|
|
75
|
-
|
|
118
|
+
- Git push access to `origin` for the accepted branch and version tag;
|
|
119
|
+
- an authenticated GitHub CLI session with pull-request and release permission;
|
|
120
|
+
- an npm account that owns the package or has maintainer permission for the separate registry publication step.
|
|
76
121
|
|
|
77
|
-
|
|
122
|
+
GitHub Actions remains a required cross-platform boundary. Missing, pending, cancelled, skipped, failed, pull-request-only, stale, or wrong-commit runs do not satisfy release publication. Observed local candidate acceptance and successful GitHub checks are complementary evidence; neither substitutes for the other.
|
|
78
123
|
|
|
79
|
-
|
|
124
|
+
The preferred registry target remains npm trusted publishing from a narrowly scoped GitHub Actions workflow using OIDC and a protected GitHub environment. Enabling it requires package-owner configuration in npm and a reviewed workflow change. Until then, never place an npm token in repository files, workflow YAML, logs, local acceptance records, or project notes.
|
package/docs/TESTING.md
CHANGED
|
@@ -2,16 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
The project treats transport, authorization, local authority, and state removal as separate failure domains.
|
|
4
4
|
|
|
5
|
-
## Required
|
|
5
|
+
## Required suites
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npm run check
|
|
8
|
+
npm run check:fast # static, unit, contract, and architecture feedback
|
|
9
|
+
npm run check:platform # fast plan plus cross-platform behavior and real-machine tests
|
|
10
|
+
npm run check # complete suite; equivalent to check:full
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
The explicit task lists live in `scripts/check-plan.mjs`. The fast plan retains static analysis, policy, architecture, contracts, and focused unit behavior. The platform plan adds process, service, browser/application, state, managed-job, cryptographic, and real-machine behavior tests needed on macOS and Windows. The full-only plan adds coverage, browser-broker integration, package/install, stdio, Worker/OAuth, and real-browser navigation suites. `npm run check` remains the authoritative complete gate.
|
|
14
|
+
|
|
11
15
|
The repository requires Node.js 26 and npm 12. `.node-version`, `.nvmrc`, `packageManager`, `devEngines`, and strict engine checks keep local and CI execution on the same baseline.
|
|
12
16
|
|
|
13
17
|
The suite includes:
|
|
14
18
|
|
|
19
|
+
- package-impact classification derived from the npm package manifest, allowing repository-only GitHub workflow maintenance without weakening version requirements for shipped content;
|
|
20
|
+
- interactive candidate acceptance hashing, including owner-authorized in-place Worker deployment plus owner-started candidate verification, exact tarball SHA-1/SHA-512 matching, acceptance-record exclusion from the package, legacy 1.2.8 marker compatibility, and invalidation after any packaged-byte change;
|
|
15
21
|
- release-impact enforcement requiring a new package version and CHANGELOG section for release-relevant changes;
|
|
16
22
|
- release-state diagnostics distinguishing missing local/remote version tags from tags that point to the wrong commit, plus a release-CI gate that rejects missing, pending, failed, pull-request-only, stale, or wrong-commit runs;
|
|
17
23
|
- generated Cloudflare Worker types under ignored `.wrangler/` state and strict TypeScript checking, including unused-local and unused-parameter rejection; packaging rejects generated declarations;
|
|
@@ -79,11 +85,11 @@ For deterministic release validation, perform an isolated-profile smoke test wit
|
|
|
79
85
|
|
|
80
86
|
## Critical-module coverage gate
|
|
81
87
|
|
|
82
|
-
`npm run coverage:test` runs selected in-process and lightweight entrypoint fixtures under V8 coverage and enforces per-module function and branch baselines. The measured set
|
|
88
|
+
`npm run coverage:test` runs selected in-process and lightweight entrypoint fixtures under V8 coverage and enforces per-module function and branch baselines. The measured set includes policy, typed errors, call registration, execution middleware, lifecycle/observability, logging, Runtime/CLI orchestration, state persistence, relay lifecycle, managed-job lifecycle/runner/storage/projection, browser broker/direct-request/runtime-client routing and loopback upgrade handling, the independently injected service CLI adapter, Agent configuration/projection/skill discovery and bounded text reads, capability ranking, runtime path redaction, browser protocol/operation boundaries, runtime reporting/diagnostics/capability composition, and Worker OAuth state/authorization-page/pending/policy/error/JSON-RPC/WebSocket protocol modules. The full stdio and workerd OAuth/MCP integration still runs separately.
|
|
83
89
|
|
|
84
90
|
The gate deliberately reports each module rather than one aggregate percentage. New extracted pure/domain modules carry explicit branch floors, while the broad CLI entrypoint remains reported and locked independently. Worker pending calls and policy now have branch minima instead of function-only gates. A refactor may raise a threshold, but must not lower one merely to make CI green without an explicit audit explanation.
|
|
85
91
|
|
|
86
|
-
`npm run typecheck` combines strict Worker TypeScript with a focused `tsconfig.local.json` gate. High-risk JavaScript contracts opt in with `// @ts-check` and JSDoc types; the gate currently covers policy, call lifecycle, Agent configuration/path resolution, browser handshake parsing, capability ranking, monotonic deadlines, number/record normalization, and bounded metadata reads. `@ts-ignore`, implicit `any`, or unchecked parallel contract shapes are not accepted as migration shortcuts.
|
|
92
|
+
`npm run typecheck` combines strict Worker TypeScript with a focused `tsconfig.local.json` gate. High-risk JavaScript contracts opt in with `// @ts-check` and JSDoc types; the gate currently covers policy, call lifecycle, Agent configuration/path resolution, public projection, skill discovery, bounded Agent text reads, runtime path redaction, browser handshake parsing, capability ranking, monotonic deadlines, number/record normalization, and bounded metadata reads. `@ts-ignore`, implicit `any`, or unchecked parallel contract shapes are not accepted as migration shortcuts.
|
|
87
93
|
|
|
88
94
|
## Additional release checks
|
|
89
95
|
|
|
@@ -97,9 +103,10 @@ npm sbom --sbom-format cyclonedx
|
|
|
97
103
|
npm pack --dry-run
|
|
98
104
|
npm run version:check
|
|
99
105
|
npm run release-impact:check
|
|
106
|
+
npm run release:acceptance:verify
|
|
100
107
|
```
|
|
101
108
|
|
|
102
|
-
GitHub Actions
|
|
109
|
+
GitHub Actions uses the pinned Node 26/npm 12 baseline in three execution paths. Ubuntu runs `check:full` and verifies interactive candidate acceptance. macOS and Windows run `check:platform` plus the installed-package smoke test, preserving platform coverage without repeating every Worker, browser, and package integration fixture three times. A separate package-audit job scans reachable Git history, audits complete and production dependency graphs, verifies registry signatures and attestations, validates a CycloneDX SBOM under the runner temporary directory, repeats the isolated installation test, and performs a package dry run. Because Node 26 currently bundles npm 11, every npm execution job downloads the exact npm 12.0.1 tarball, rejects redirects, verifies its recorded SHA-512 SRI, and exposes that verified CLI through `GITHUB_PATH`. Separate pinned workflows validate governance titles, dependency changes, CodeQL, and OpenSSF Scorecard. Third-party Actions remain pinned to immutable commits, SARIF findings fail closed unless exactly reviewed, and source release creation requires successful push-triggered CI, CodeQL, Governance, and Scorecard runs for the exact `main` commit.
|
|
103
110
|
|
|
104
111
|
## Test design rules
|
|
105
112
|
|
|
@@ -120,7 +127,7 @@ Run `npm run privacy:check` before committing and before packaging. Run and revi
|
|
|
120
127
|
|
|
121
128
|
## Package manifest
|
|
122
129
|
|
|
123
|
-
`npm run package:test` executes a real silent `npm pack --dry-run --json`, requires clean parseable JSON, rejects sensitive local artifacts, credential-like file classes, and generated Worker type declarations, validates every packaged mode as `0644` or `0755`, and verifies that
|
|
130
|
+
`npm run package:test` executes a real silent `npm pack --dry-run --json`, requires clean parseable JSON, rejects sensitive local artifacts, credential-like file classes, and generated Worker type declarations, validates every packaged mode as `0644` or `0755`, and verifies that required runtime, script, browser-extension, privacy, governance, and release files are present. `npm run install:test` requires npm 12, installs the real tarball from a package-free directory into an isolated global prefix with the documented options, verifies the packaged npm engine requirement, rejects blocked-script warnings, confirms optional `fsevents` is absent, verifies `--version`, then runs the installed CLI with zero arguments from an isolated workspace/state root. A fake Wrangler JavaScript entrypoint terminates at a controlled deployment boundary, so the probe exercises startup without mutating a live account. Package testing is full-plan-only; installation smoke runs in the Ubuntu full plan, the macOS/Windows platform plan, and package audit.
|
|
124
131
|
|
|
125
132
|
`npm run lint` uses ESLint as a semantic JavaScript correctness gate rather than a style formatter. It covers the Node CLI/runtime, repository scripts, tests, and packaged browser extension and rejects undefined identifiers in function bodies that `node --check` cannot detect. A dedicated lint-gate self-test proves that both Node and browser configurations reject a synthetic undefined binding while accepting the service-worker `importScripts` global. A focused `shell:test` requires Wrangler to run through the current Node executable and its package JavaScript entrypoint rather than a `.cmd` or shell shim. Architecture tests require `shell:test`, `lint:test`, `lint`, and `install:test` to remain in the complete check pipeline and reject non-exact direct dependency ranges.
|
|
126
133
|
|
|
@@ -128,4 +135,4 @@ The stdio integration test also sends an oversized line, verifies bounded reject
|
|
|
128
135
|
|
|
129
136
|
## Architecture and documentation regression checks
|
|
130
137
|
|
|
131
|
-
`npm run architecture:test` runs independent module-boundary, repository-hygiene, browser/security-structure, and release/documentation-contract checks. It
|
|
138
|
+
`npm run architecture:test` runs independent module-boundary, repository-hygiene, browser/security-structure, and release/documentation-contract checks. It validates the explicit fast/full check plans, local import graph, domain/adapter direction, module headroom budgets, immutable workflow references, package-script targets, documentation links, publication inventory, and selected security-shape invariants. These source-shape checks are deliberately supplementary: behavior, denial, race, and fault-injection tests remain authoritative for semantic guarantees. Tests must not depend on a fixed CI job count when the actual invariant is that every npm job uses the same verified bootstrap.
|