machine-bridge-mcp 2.0.0 → 3.0.0-beta.102
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 +1142 -0
- package/CONTRIBUTING.md +23 -25
- package/GOVERNANCE.md +2 -2
- package/README.md +58 -20
- package/SECURITY.md +161 -120
- package/SUPPORT.md +1 -1
- package/browser-extension/broker-auth.js +83 -0
- package/browser-extension/broker-liveness.js +35 -0
- package/browser-extension/browser-error-boundary.js +96 -0
- package/browser-extension/browser-operations.js +1456 -101
- package/browser-extension/devtools-input.js +195 -34
- package/browser-extension/devtools-observation.js +429 -0
- package/browser-extension/devtools-session.js +48 -0
- package/browser-extension/manifest.json +4 -3
- package/browser-extension/page-automation.js +578 -118
- package/browser-extension/pairing-bootstrap.js +42 -0
- package/browser-extension/pairing.js +28 -12
- package/browser-extension/service-worker.js +126 -106
- package/docs/AGENT_CONTEXT.md +13 -10
- package/docs/ARCHITECTURE.md +159 -67
- package/docs/AUDIT.md +1302 -4
- package/docs/CLIENTS.md +19 -6
- package/docs/COMPUTER_USE.md +297 -0
- package/docs/ENGINEERING.md +72 -13
- package/docs/GETTING_STARTED.md +18 -20
- package/docs/LOCAL_AUTHORIZATION.md +115 -72
- package/docs/LOCAL_AUTOMATION.md +27 -21
- package/docs/LOGGING.md +40 -19
- package/docs/MANAGED_JOBS.md +37 -34
- package/docs/MULTI_ACCOUNT.md +98 -37
- package/docs/OPERATIONS.md +145 -51
- package/docs/OVERVIEW.md +14 -11
- package/docs/POLICY_REFERENCE.md +71 -3
- package/docs/PRIVACY.md +41 -2
- package/docs/PROJECT_STANDARDS.md +29 -6
- package/docs/RELEASING.md +238 -64
- package/docs/TESTING.md +150 -39
- package/docs/THREAT_MODEL.md +164 -67
- package/docs/TOOL_REFERENCE.md +653 -60
- package/docs/UPGRADING.md +78 -18
- package/native/macos/MachineBridgeBackgroundInput.swift +1051 -0
- package/native/macos/MachineBridgeBackgroundInputSmokeFixture.swift +295 -0
- package/native/macos/MachineBridgeTrustBroker.swift +233 -0
- package/package.json +94 -16
- package/scripts/accepted-candidate-tarball.mjs +77 -0
- package/scripts/candidate-runtime-store.mjs +93 -0
- package/scripts/check-plan.mjs +73 -3
- package/scripts/check-runner.mjs +129 -17
- package/scripts/commit-message-check.mjs +5 -2
- package/scripts/consumer-package-security.mjs +293 -0
- package/scripts/coverage-check.mjs +251 -15
- package/scripts/coverage-generation.mjs +41 -0
- package/scripts/coverage-range-merge.mjs +41 -0
- package/scripts/foreground-daemon-recovery.mjs +88 -0
- package/scripts/generate-policy-reference.mjs +28 -5
- package/scripts/generate-tool-reference.mjs +1 -1
- package/scripts/generate-worker-types.mjs +21 -11
- package/scripts/github-backlog.mjs +11 -10
- package/scripts/github-push.mjs +62 -16
- package/scripts/github-release-asset.mjs +58 -0
- package/scripts/github-release.mjs +241 -132
- package/scripts/global-package-installation.mjs +68 -0
- package/scripts/hardened-npm-session.mjs +42 -0
- package/scripts/install-published-prerelease.mjs +198 -0
- package/scripts/local-release-acceptance.mjs +103 -45
- package/scripts/macos-background-input-smoke.mjs +515 -0
- package/scripts/network-retry.mjs +8 -1
- package/scripts/npm-global-prefix.mjs +27 -0
- package/scripts/npm-publication-policy.mjs +17 -0
- package/scripts/official-mcp-conformance.mjs +267 -0
- package/scripts/persistent-activation-process.mjs +101 -0
- package/scripts/prepare-pinned-npm.mjs +12 -69
- package/scripts/prerelease-activation.mjs +160 -0
- package/scripts/privacy-check.mjs +14 -6
- package/scripts/promotion-digest.mjs +128 -0
- package/scripts/publish-npm.mjs +260 -0
- package/scripts/published-release.mjs +132 -0
- package/scripts/release-acceptance.mjs +62 -54
- package/scripts/release-browser-extension-store.mjs +172 -0
- package/scripts/release-candidate-manifest.mjs +52 -0
- package/scripts/release-channel.mjs +106 -0
- package/scripts/release-diagnostic.mjs +41 -0
- package/scripts/release-impact-check.mjs +12 -22
- package/scripts/release-oauth-canary-core.mjs +325 -0
- package/scripts/release-oauth-canary-evidence.mjs +100 -0
- package/scripts/release-oauth-canary.mjs +127 -0
- package/scripts/release-publication-guard.mjs +67 -0
- package/scripts/release-soak.mjs +284 -0
- package/scripts/release-state.mjs +1 -1
- package/scripts/run-checks.mjs +44 -7
- package/scripts/run-worker-dry-run.mjs +21 -0
- package/scripts/sarif-security-gate.mjs +2 -1
- package/scripts/sbom-check.mjs +106 -0
- package/scripts/start-release-candidate.mjs +267 -44
- package/scripts/syntax-check.mjs +36 -14
- package/scripts/verification-generation-guard.mjs +15 -0
- package/scripts/verification-idle-sleep-guard.mjs +37 -0
- package/scripts/verification-state.mjs +108 -0
- package/scripts/wrangler-command-lifecycle.mjs +115 -0
- package/src/local/account-access.mjs +13 -1
- package/src/local/account-admin-response.mjs +92 -0
- package/src/local/account-admin.mjs +52 -19
- package/src/local/agent-context-projection.mjs +26 -7
- package/src/local/agent-context.mjs +88 -49
- package/src/local/agent-skill-discovery.mjs +16 -5
- package/src/local/app-automation-macos-jxa.mjs +350 -0
- package/src/local/app-automation.mjs +873 -163
- package/src/local/application-capability-projection.mjs +24 -0
- package/src/local/authority-context.mjs +106 -0
- package/src/local/autostart-log-maintenance.mjs +36 -0
- package/src/local/browser-bridge-http.mjs +5 -3
- package/src/local/browser-bridge.mjs +109 -31
- package/src/local/browser-broker-auth-http.mjs +67 -0
- package/src/local/browser-broker-auth.mjs +98 -0
- package/src/local/browser-broker-routes.mjs +63 -20
- package/src/local/browser-broker-server.mjs +17 -7
- package/src/local/browser-command.mjs +79 -30
- package/src/local/browser-computer-observation-service.mjs +266 -0
- package/src/local/browser-extension-identity.mjs +50 -0
- package/src/local/browser-extension-path.mjs +22 -0
- package/src/local/browser-extension-protocol.mjs +50 -11
- package/src/local/browser-operation-service.mjs +147 -117
- package/src/local/browser-pairing-grant.mjs +109 -0
- package/src/local/browser-pairing-http.mjs +36 -0
- package/src/local/browser-pairing-launch.mjs +58 -0
- package/src/local/browser-pairing-store.mjs +85 -48
- package/src/local/browser-request-registry.mjs +40 -14
- package/src/local/browser-request-settlement.mjs +78 -0
- package/src/local/browser-resource-input.mjs +74 -0
- package/src/local/browser-trusted-input-health.mjs +63 -0
- package/src/local/call-authority.mjs +21 -0
- package/src/local/call-capacity.mjs +45 -0
- package/src/local/call-registry-drain.mjs +54 -0
- package/src/local/call-registry.mjs +30 -15
- package/src/local/capability-observer.mjs +5 -0
- package/src/local/capability-ranking.mjs +3 -2
- package/src/local/child-process-settlement.mjs +132 -0
- package/src/local/cli-account-admin.mjs +40 -6
- package/src/local/cli-activate.mjs +162 -0
- package/src/local/cli-local-admin.mjs +20 -45
- package/src/local/cli-options.mjs +12 -13
- package/src/local/cli-ready-output.mjs +52 -0
- package/src/local/cli-service.mjs +91 -11
- package/src/local/cli.mjs +232 -150
- package/src/local/computer-use-application-observation.mjs +224 -0
- package/src/local/computer-use-arguments.mjs +270 -0
- package/src/local/computer-use-deadline.mjs +50 -0
- package/src/local/computer-use-dispatch-settlement.mjs +40 -0
- package/src/local/computer-use-expectation.mjs +171 -0
- package/src/local/computer-use-observation.mjs +769 -0
- package/src/local/computer-use-recovery.mjs +82 -0
- package/src/local/computer-use-result-budget.mjs +145 -0
- package/src/local/computer-use-snapshot-store.mjs +67 -0
- package/src/local/computer-use.mjs +2255 -0
- package/src/local/daemon-http-relay-auth.mjs +26 -0
- package/src/local/daemon-http-relay-connection.mjs +298 -0
- package/src/local/daemon-http-relay-request.mjs +64 -0
- package/src/local/daemon-http-relay-sequence.mjs +49 -0
- package/src/local/daemon-process.mjs +40 -7
- package/src/local/delegated-process-sandbox.mjs +148 -0
- package/src/local/device-identity.mjs +156 -49
- package/src/local/device-root-provider.mjs +81 -0
- package/src/local/directory-metadata.mjs +47 -0
- package/src/local/doctor-reporting.mjs +23 -0
- package/src/local/durable-process-spec.mjs +80 -0
- package/src/local/errors.mjs +25 -15
- package/src/local/exclusive-file.mjs +74 -26
- package/src/local/execution-limits.mjs +9 -0
- package/src/local/execution-routing.mjs +276 -0
- package/src/local/execution-surface.mjs +23 -0
- package/src/local/file-mutation-coordinator.mjs +47 -0
- package/src/local/file-snapshot-preservation.mjs +24 -0
- package/src/local/filesystem-identity.mjs +54 -0
- package/src/local/fixed-process-environment.mjs +21 -0
- package/src/local/full-access-test.mjs +31 -13
- package/src/local/git-commit.mjs +69 -0
- package/src/local/git-config-safety.mjs +55 -0
- package/src/local/git-log-parser.mjs +41 -0
- package/src/local/git-metadata-boundary.mjs +77 -0
- package/src/local/git-metadata-tree-safety.mjs +59 -0
- package/src/local/git-operation-state.mjs +19 -0
- package/src/local/git-service.mjs +165 -30
- package/src/local/hardened-npm-download-timeout.mjs +46 -0
- package/src/local/hardened-npm-download.mjs +109 -0
- package/src/local/hardened-npm-extract.mjs +20 -0
- package/src/local/hardened-npm-verification.mjs +104 -0
- package/src/local/hardened-npm.mjs +199 -0
- package/src/local/job-runner.mjs +244 -89
- package/src/local/lifecycle.mjs +6 -0
- package/src/local/log.mjs +19 -45
- package/src/local/macos-background-input.mjs +398 -0
- package/src/local/macos-idle-sleep-assertion.mjs +65 -0
- package/src/local/macos-trust-broker.mjs +404 -0
- package/src/local/managed-job-cancellation.mjs +42 -0
- package/src/local/managed-job-capacity.mjs +16 -0
- package/src/local/managed-job-directory-generation.mjs +60 -0
- package/src/local/managed-job-directory.mjs +75 -0
- package/src/local/managed-job-durable-process.mjs +49 -0
- package/src/local/managed-job-lock.mjs +46 -14
- package/src/local/managed-job-plan.mjs +38 -14
- package/src/local/managed-job-projection.mjs +23 -15
- package/src/local/managed-job-retention.mjs +128 -0
- package/src/local/managed-job-runner-claim.mjs +70 -0
- package/src/local/managed-job-runner.mjs +35 -10
- package/src/local/managed-job-storage.mjs +22 -6
- package/src/local/managed-job-terminal-maintenance.mjs +40 -0
- package/src/local/managed-job-terminal.mjs +150 -0
- package/src/local/managed-jobs.mjs +424 -287
- package/src/local/npm-cli.mjs +42 -0
- package/src/local/npm-environment.mjs +37 -0
- package/src/local/operation-authorization.mjs +68 -324
- package/src/local/operation-risk.mjs +51 -4
- package/src/local/owner-state-lock.mjs +118 -0
- package/src/local/package-identity.mjs +9 -0
- package/src/local/patch.mjs +20 -18
- package/src/local/path-inspection.mjs +23 -0
- package/src/local/policy.mjs +19 -0
- package/src/local/private-toolchain-integrity.mjs +54 -0
- package/src/local/process-execution.mjs +87 -75
- package/src/local/process-foreground-timeout.mjs +50 -0
- package/src/local/process-identity.mjs +41 -7
- package/src/local/process-nonreplayable-settlement.mjs +50 -0
- package/src/local/process-result-projection.mjs +22 -0
- package/src/local/process-session-events.mjs +47 -0
- package/src/local/process-session-remote-activity.mjs +10 -0
- package/src/local/process-session-termination.mjs +73 -0
- package/src/local/process-sessions.mjs +144 -112
- package/src/local/process-tracker.mjs +140 -13
- package/src/local/process-tree-ownership-types.d.ts +37 -0
- package/src/local/process-tree-ownership.mjs +57 -0
- package/src/local/process-tree-signal.mjs +34 -0
- package/src/local/process-tree-snapshot.mjs +77 -0
- package/src/local/process-tree-supervisor.mjs +69 -0
- package/src/local/process-tree.mjs +11 -53
- package/src/local/project-metadata.mjs +19 -6
- package/src/local/relay-call-recovery.mjs +58 -38
- package/src/local/relay-connection-classification.mjs +131 -0
- package/src/local/relay-connection-support.mjs +91 -0
- package/src/local/relay-connection.mjs +179 -272
- package/src/local/relay-diagnostics.mjs +91 -0
- package/src/local/relay-heartbeat.mjs +119 -0
- package/src/local/relay-liveness.mjs +109 -0
- package/src/local/relay-peer-diagnostics.mjs +29 -0
- package/src/local/release-runtime-lock.mjs +18 -0
- package/src/local/remote-activity-idle-sleep-guard.mjs +77 -0
- package/src/local/remote-configuration.mjs +48 -0
- package/src/local/resilient-relay-connection.mjs +178 -0
- package/src/local/resource-admission-diagnostics.mjs +52 -0
- package/src/local/resource-admission-policy.mjs +115 -0
- package/src/local/resource-admission.mjs +339 -0
- package/src/local/resource-build-root.mjs +83 -0
- package/src/local/resource-cargo-concurrency.mjs +38 -0
- package/src/local/resource-cmake-concurrency.mjs +42 -0
- package/src/local/resource-command-concurrency.mjs +37 -0
- package/src/local/resource-command-profile.mjs +176 -0
- package/src/local/resource-coordinator-accounting.mjs +21 -0
- package/src/local/resource-cpu-window.mjs +20 -0
- package/src/local/resource-disk-headroom.mjs +13 -0
- package/src/local/resource-elastic-memory.mjs +19 -0
- package/src/local/resource-elastic-request.mjs +36 -0
- package/src/local/resource-foreground-wait.mjs +29 -0
- package/src/local/resource-go-concurrency.mjs +43 -0
- package/src/local/resource-gradle-concurrency.mjs +57 -0
- package/src/local/resource-host-cache.mjs +39 -0
- package/src/local/resource-host-darwin.mjs +54 -0
- package/src/local/resource-host-linux.mjs +35 -0
- package/src/local/resource-host-sample-file.mjs +23 -0
- package/src/local/resource-host-snapshot.mjs +99 -0
- package/src/local/resource-lease-accounting.mjs +119 -0
- package/src/local/resource-light-command.mjs +6 -0
- package/src/local/resource-make-concurrency.mjs +42 -0
- package/src/local/resource-maven-concurrency.mjs +38 -0
- package/src/local/resource-ninja-command-concurrency.mjs +20 -0
- package/src/local/resource-ninja-concurrency.mjs +28 -0
- package/src/local/resource-operations.mjs +26 -10
- package/src/local/resource-pressure.mjs +67 -0
- package/src/local/resource-probe-command.mjs +35 -0
- package/src/local/resource-process-admission.mjs +59 -0
- package/src/local/resource-process-ancestry-cache.mjs +43 -0
- package/src/local/resource-process-ancestry.mjs +32 -0
- package/src/local/resource-process-priority.mjs +15 -0
- package/src/local/resource-project-key.mjs +53 -0
- package/src/local/resource-pytest-concurrency.mjs +33 -0
- package/src/local/resource-release-control-classification.mjs +14 -0
- package/src/local/resource-release-control-executable.mjs +70 -0
- package/src/local/resource-release-control-workspace.mjs +41 -0
- package/src/local/resource-request-contract.mjs +30 -0
- package/src/local/resource-script-classification.mjs +44 -0
- package/src/local/resource-shell-analysis.mjs +58 -0
- package/src/local/resource-staging-recovery.mjs +97 -0
- package/src/local/resource-swift-concurrency.mjs +31 -0
- package/src/local/resource-transaction-lock.mjs +189 -0
- package/src/local/resource-wait.mjs +48 -0
- package/src/local/resource-waiters.mjs +139 -0
- package/src/local/resource-xcode-command.mjs +7 -0
- package/src/local/resource-xcode-concurrency.mjs +34 -0
- package/src/local/resource-xcode-non-build.mjs +19 -0
- package/src/local/runtime-activation.mjs +700 -0
- package/src/local/runtime-activity-projection.mjs +48 -0
- package/src/local/runtime-capabilities.mjs +48 -15
- package/src/local/runtime-diagnostic-state.mjs +14 -0
- package/src/local/runtime-diagnostics.mjs +40 -13
- package/src/local/runtime-info-projection.mjs +60 -0
- package/src/local/runtime-info-relay-projection.mjs +21 -0
- package/src/local/runtime-paths.mjs +2 -1
- package/src/local/runtime-process-routing.mjs +33 -0
- package/src/local/runtime-relay-connection-options.mjs +44 -0
- package/src/local/runtime-relay-control.mjs +98 -0
- package/src/local/runtime-relay.mjs +26 -50
- package/src/local/runtime-reporting.mjs +37 -21
- package/src/local/runtime-resource-service.mjs +77 -0
- package/src/local/runtime-tool-handlers.mjs +13 -10
- package/src/local/runtime.mjs +244 -208
- package/src/local/secure-file.mjs +73 -20
- package/src/local/security-audit-dispatch.mjs +35 -0
- package/src/local/security-audit-log.mjs +215 -0
- package/src/local/security-audit-state.mjs +139 -0
- package/src/local/security-audit-storage.mjs +135 -0
- package/src/local/security-audit-warning.mjs +31 -0
- package/src/local/security-audit-worker.mjs +87 -0
- package/src/local/service-convergence.mjs +42 -1
- package/src/local/service-definition.mjs +24 -0
- package/src/local/service-environment.mjs +18 -10
- package/src/local/service-owner.mjs +146 -0
- package/src/local/service-ownership.mjs +17 -0
- package/src/local/service-restart-handoff.mjs +64 -0
- package/src/local/service-restart-scheduler.mjs +49 -0
- package/src/local/service-runtime-convergence.mjs +52 -0
- package/src/local/service-runtime.mjs +105 -0
- package/src/local/service-status.mjs +60 -0
- package/src/local/service.mjs +385 -92
- package/src/local/shell.mjs +39 -19
- package/src/local/ssh-key.mjs +158 -42
- package/src/local/state-inventory.mjs +50 -24
- package/src/local/state-owner-lock-inventory.mjs +23 -0
- package/src/local/state-root-owned-namespaces.mjs +83 -0
- package/src/local/state-root-retirement.mjs +89 -0
- package/src/local/state.mjs +386 -96
- package/src/local/stdio.mjs +96 -66
- package/src/local/support-state-projection.mjs +30 -0
- package/src/local/system-network-route.mjs +76 -0
- package/src/local/systemd-removal.mjs +20 -0
- package/src/local/tool-executor.mjs +85 -20
- package/src/local/tool-result-boundary.mjs +51 -0
- package/src/local/toolchain-operation-lock.mjs +41 -0
- package/src/local/tools.mjs +7 -5
- package/src/local/trusted-executable.mjs +53 -0
- package/src/local/trusted-git-executable.mjs +34 -0
- package/src/local/trusted-github-cli.mjs +24 -0
- package/src/local/windows-service-convergence.mjs +49 -0
- package/src/local/windows-service.mjs +52 -45
- package/src/local/worker-deployment-fingerprint.mjs +102 -0
- package/src/local/worker-deployment.mjs +48 -60
- package/src/local/worker-health.mjs +12 -4
- package/src/local/worker-secret-file.mjs +37 -17
- package/src/local/workspace-file-service.mjs +156 -239
- package/src/local/workspace-file-transaction.mjs +189 -0
- package/src/local/workspace-search.mjs +55 -0
- package/src/local/wrangler-toolchain/package-lock.json +1505 -0
- package/src/local/wrangler-toolchain/package.json +23 -0
- package/src/local/wrangler-toolchain-verification.mjs +135 -0
- package/src/local/wrangler-toolchain.mjs +188 -0
- package/src/shared/access-contract.json +7 -1
- package/src/shared/activation-recovery.mjs +49 -0
- package/src/shared/admin-auth.d.mts +2 -1
- package/src/shared/admin-auth.mjs +3 -3
- package/src/shared/authority-revocation.d.mts +9 -0
- package/src/shared/authority-revocation.mjs +28 -0
- package/src/shared/daemon-auth.d.mts +11 -0
- package/src/shared/daemon-auth.mjs +17 -0
- package/src/shared/device-session-auth.d.mts +20 -0
- package/src/shared/device-session-auth.mjs +51 -0
- package/src/shared/foreground-timeout.d.mts +15 -0
- package/src/shared/foreground-timeout.mjs +70 -0
- package/src/shared/log-redaction.d.mts +9 -0
- package/src/shared/log-redaction.mjs +51 -0
- package/src/shared/mcp-protocol.d.mts +27 -0
- package/src/shared/mcp-protocol.mjs +275 -0
- package/src/shared/project-overview-projection.d.mts +4 -0
- package/src/shared/project-overview-projection.mjs +96 -0
- package/src/shared/relay-contract.json +28 -0
- package/src/shared/result-projection.d.mts +2 -1
- package/src/shared/result-projection.mjs +13 -2
- package/src/shared/server-metadata.json +15 -9
- package/src/shared/tool-argument-validation.d.mts +17 -0
- package/src/shared/tool-argument-validation.mjs +325 -0
- package/src/shared/tool-call-capacity.d.mts +41 -0
- package/src/shared/tool-call-capacity.mjs +59 -0
- package/src/shared/tool-catalog.json +626 -57
- package/src/worker/access.ts +12 -0
- package/src/worker/account-admin.ts +55 -33
- package/src/worker/authority-revocations.ts +174 -0
- package/src/worker/authority.ts +52 -6
- package/src/worker/daemon-auth.ts +49 -68
- package/src/worker/daemon-channel.ts +36 -0
- package/src/worker/daemon-http-auth.ts +63 -0
- package/src/worker/daemon-http-channel.ts +120 -0
- package/src/worker/daemon-http-controller.ts +163 -0
- package/src/worker/daemon-http-protocol.ts +62 -0
- package/src/worker/daemon-http-registry.ts +82 -0
- package/src/worker/daemon-last-observation.ts +30 -0
- package/src/worker/daemon-liveness.ts +8 -6
- package/src/worker/daemon-ready-dispatch.ts +17 -0
- package/src/worker/daemon-ready-messages.ts +73 -0
- package/src/worker/daemon-ready-waiters.ts +79 -0
- package/src/worker/daemon-recovery-budget.ts +13 -0
- package/src/worker/daemon-registry.ts +58 -0
- package/src/worker/daemon-relay-diagnostics.ts +127 -0
- package/src/worker/daemon-socket-attachment.ts +55 -0
- package/src/worker/daemon-sockets.ts +72 -62
- package/src/worker/daemon-status.ts +38 -0
- package/src/worker/device-session-verifier.ts +129 -0
- package/src/worker/dpop.ts +157 -0
- package/src/worker/durable-process-timeout.ts +29 -0
- package/src/worker/errors.ts +57 -0
- package/src/worker/http.ts +112 -26
- package/src/worker/index.ts +446 -440
- package/src/worker/mcp-access.ts +57 -0
- package/src/worker/mcp-controller.ts +188 -0
- package/src/worker/mcp-http-accept.ts +11 -0
- package/src/worker/mcp-http-contract.ts +322 -0
- package/src/worker/mcp-initialization-compat.ts +141 -0
- package/src/worker/mcp-jsonrpc.ts +11 -29
- package/src/worker/mcp-removed-protocol.ts +17 -0
- package/src/worker/mcp-response-proxy.ts +135 -0
- package/src/worker/mcp-response-stream.ts +65 -0
- package/src/worker/mcp-stale-schema-compat.ts +57 -0
- package/src/worker/mcp-stream-proxy-contract.ts +48 -0
- package/src/worker/mcp-tool-call-input.ts +23 -0
- package/src/worker/nonce-store.ts +33 -35
- package/src/worker/oauth-authorization-page.ts +21 -1
- package/src/worker/oauth-client-admin.ts +52 -0
- package/src/worker/oauth-client-contract.ts +38 -0
- package/src/worker/oauth-controller.ts +107 -47
- package/src/worker/oauth-field-contract.ts +31 -0
- package/src/worker/oauth-record-contract.ts +7 -0
- package/src/worker/oauth-refresh-authority.ts +27 -0
- package/src/worker/oauth-refresh-exchange.ts +162 -0
- package/src/worker/oauth-refresh-families.ts +130 -27
- package/src/worker/oauth-refresh-persistence.ts +116 -0
- package/src/worker/oauth-state.ts +33 -18
- package/src/worker/oauth-store-validation.ts +131 -0
- package/src/worker/oauth-token-derivation.ts +33 -0
- package/src/worker/oauth-token-issuance.ts +119 -0
- package/src/worker/oauth-tokens.ts +56 -190
- package/src/worker/observability.ts +38 -5
- package/src/worker/pending-admission.ts +15 -0
- package/src/worker/pending-call-capacity.ts +108 -0
- package/src/worker/pending-call-contract.ts +42 -5
- package/src/worker/pending-call-deadlines.ts +75 -0
- package/src/worker/pending-calls.ts +131 -125
- package/src/worker/runtime-alarm-storage.ts +37 -0
- package/src/worker/runtime-alarm.ts +136 -0
- package/src/worker/server-info-activity.ts +36 -0
- package/src/worker/server-info-tool-delivery.ts +15 -0
- package/src/worker/server-info.ts +168 -0
- package/src/worker/tool-catalog.ts +47 -1
- package/src/worker/tool-timeout.ts +75 -14
- package/src/worker/websocket-protocol.ts +26 -2
- package/src/worker/worker-edge-guard.ts +90 -0
- package/src/worker/worker-edge-log.ts +65 -0
- package/src/worker/worker-entry.ts +52 -0
- package/src/worker/worker-mcp-config.ts +23 -0
- package/src/worker/worker-metadata.ts +48 -0
- package/src/worker/worker-rate-limit-key.ts +30 -0
- package/src/worker/worker-runtime-config.ts +20 -0
- package/src/worker/worker-static-routes.ts +54 -0
- package/src/worker/worker-task-lifetime.ts +18 -0
- package/tsconfig.local.json +17 -1
- package/wrangler.jsonc +13 -0
- package/src/local/cli-approval.mjs +0 -117
- package/src/local/operation-state-lock.mjs +0 -92
- package/src/worker/mcp-session.ts +0 -72
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,1147 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.0.0-beta.102 - 2026-08-18
|
|
4
|
+
|
|
5
|
+
- Supersede beta.101 after a fresh live interruption disproved the assumption that faster WebSocket half-open detection was sufficient recovery. The activated beta.101 launchd daemon remained the same PID with `runs=1` and no exit or matching Sleep/Wake event, yet the daemon-to-Worker relay disappeared at `2026-08-18T04:00:07.944Z` and required about 323.8 seconds plus 13 reconnect attempts before recovery; the final retained classification was `relay_connect_timeout`, with 9,830 ms of inbound silence before the ready socket closed. During the incident Worker-local HTTP/MCP remained responsive while no authenticated/ready/candidate daemon socket existed. The host's default route was carried by `utun5`, and same-window system logs showed multi-second TLS/read stalls in other applications even while Network.framework considered the route satisfied, but the available evidence cannot identify a particular VPN/TUN/provider, Wi-Fi component, Cloudflare edge, ISP, or upstream device as the physical trigger.
|
|
6
|
+
- Remove the WebSocket-only recovery single point. WebSocket remains the preferred daemon transport with its five-second native Ping, ten-second inbound-silence timeout, independent 25/75-second application heartbeat, and background reconnect. If verified WSS readiness is absent, the same root-certified ephemeral P-256 device identity can establish a bounded signed `POST /daemon/http` fallback that reuses the same daemon instance, pending-call registry, account/tool authority, cancellation rules, `RelayCallRecovery`, and same-instance `resume_calls` ownership proof. Each HTTP request signature binds the fixed route, Worker origin, server/version, nonce, issue time, and exact body SHA-256; the replay window is 30 seconds with bounded nonce storage. After an established WSS disappears, the daemon may explicitly request same-instance takeover so the signed fallback can retire a Worker-side zombie WSS that has not observed the close; stale/new-session preconditions are checked before any incumbent is retired, so a malformed signed request cannot knock down a healthy channel. This is transport redundancy only: it does not restore `Mcp-Session-Id`, recovery GET, `Last-Event-ID`, a second MCP state model, alternate account authority, or durable public tool-result replay.
|
|
7
|
+
- Make fallback delivery explicitly at-most-once at the business side-effect boundary. Both directions use contiguous in-memory transport sequences; unacknowledged envelopes retain the same sequence across an HTTP response loss, duplicates are discarded before business handling, sequence gaps fail closed, queue item/count/byte limits are fixed, and a daemon `tool_call` is transport-acknowledged only after successful synchronous ownership handoff to the existing local handler. Old HTTP responses cannot commit a transport sequence after that handler resets/replaces the session. Control messages remain strictly ordered. HTTPS handover has candidate, probing, and verified-ready states. The daemon first reconciles `resume_calls`, then processes Worker `ready_ack`, commits local readiness, emits sequenced `https_ready`, and only afterward emits `resume_calls_ack`; a non-empty `missing_ids` list therefore proves both replacement readiness and that the same daemon has neither active-call nor retained-result ownership for those IDs. For that proof only, the Worker may transparently retransmit the exact same call ID, arguments, authority, and a reduced timeout while at least one second remains inside the original execution deadline. If redelivery cannot be accepted or the budget is too small, the call retains beta.101's retryable `unavailable`/`side_effects_started=false` fallback. Active calls, retained terminal results, different-daemon calls, and any ambiguous mutation are never automatically replayed. Real Wrangler regressions exercise WSS → HTTPS takeover with an in-flight call, invalid takeover fail-closed behavior, lost/replayed HTTP terminal transport, safe same-ID proven-non-delivery redelivery, exactly one MCP settlement, and verified WSS reclaim.
|
|
8
|
+
- Repair recovery timing rather than only shortening detection. Relay elapsed time, heartbeat silence, outage duration, ready duration, connection-attempt duration, and reconnect deadlines now use monotonic `performance.now()` while persisted/operator timestamps remain wall clock; forward/backward wall-clock jumps therefore cannot manufacture or suppress a timeout. Direct WSS attempts record only coarse DNS/TCP/TLS/HTTP-Upgrade/Open stage, duration, and bounded HTTP status diagnostics without addresses, headers, arguments, or credentials. A connection attempt that already consumed most of its 15-second connection budget no longer pays another full exponential idle delay. New calls may wait up to 15 seconds for verified daemon recovery—long enough to cover two bounded seven-second HTTPS fallback exchanges and the measured multi-second degraded TLS path—but that measured recovery interval is still deducted from the original tool execution budget rather than extending the hosted foreground envelope.
|
|
9
|
+
- Bound fallback load and failure state. HTTPS requests have a seven-second deadline, 12-second liveness window, one-second ordinary poll cadence, and a hard 750 ms minimum start interval, keeping the fallback below 80 requests/minute and leaving headroom under the existing 120/minute daemon route limiter. Request/response bodies and retained queues are independently bounded; HTTP(S) proxy/NO_PROXY selection reuses the existing network-proxy policy. Query-only status code never silently closes a channel that owns pending calls: expiration, protocol failure, replacement, and WSS handback all flow through the same pending detach/reconnect-grace lifecycle first.
|
|
10
|
+
- Close two additional interruption amplifiers found during the all-path review. Chromium MV3 extension keepalive now negotiates a broker Pong watchdog: new brokers echo a bounded ping sequence, the extension closes/reconnects after ten seconds without the matching Pong, and old brokers remain compatible without the negotiated watchdog. Daemon-lifetime in-memory process-session retention/eviction now ages sessions with a monotonic clock while preserving wall-clock `started_at`/`closed_at` metadata, so NTP or manual clock changes cannot prematurely destroy `read_process` recovery state.
|
|
11
|
+
- Preserve privacy-bounded outage evidence while no daemon channel is ready. `DaemonRegistry` retains one in-memory `server_info.daemon.previous_connection` observation for the last verified channel with only transport, connected/last-seen/disconnected timestamps, and already-sanitized relay diagnostics. It omits policy, tool membership, account/client identity, daemon instance/connection identity, call IDs, arguments, and results, and is never consulted for authorization, routing, reconnect ownership, or persistence. A live all-channel outage therefore no longer erases the immediately preceding transport evidence into only `relay_transport:null` before the daemon returns.
|
|
12
|
+
- The independent pass re-audited Computer Use dispatch/effect settlement, idle-sleep guards, managed-job claim/finally/restart behavior, resource-admission cancellation/leases, launchd service handoff/rollback, browser mutation ambiguity, and logging/privacy boundaries. No second concrete interruption defect was found in those subsystems. New operational events remain aggregate-only, and the HTTPS transport store is in-memory transport state rather than a content log. These packaged bytes invalidate all beta.101 candidate/activation/acceptance evidence; beta.102 requires fresh frozen fast/full verification, candidate/install-only preparation, new explicit owner authorization before activation, activated-package OAuth canary, live WSS/HTTPS/browser verification, and only then release acceptance.
|
|
13
|
+
|
|
14
|
+
## 3.0.0-beta.101 - 2026-08-18
|
|
15
|
+
|
|
16
|
+
- Supersede beta.100 after its exact candidate had been activated and its activated-package canary had passed, but before browser-extension acceptance completed. The follow-up interruption investigation changed packaged runtime/tool/documentation bytes, so beta.100 remains operational evidence for its exact bytes only and cannot be reused as beta.101 release evidence.
|
|
17
|
+
- Repair a compound Computer Use deadline mismatch that could surface as apparently interrupted GUI work even when the lower macOS Accessibility operation itself was healthy. Hosted configurable foreground work normally defaulted to 20 seconds while local `computer_act` defaulted to 30 seconds, and preflight, mutation dispatch, verification, and post-observation could each receive nearly the original timeout. `computer_act` now owns one monotonic end-to-end action deadline and gives every stage only the remaining budget; verification capture is capped by both the verification window and the overall action deadline. `computer_observe` applies the same rule across application screenshot, Accessibility inspection, and fallback window revalidation. The remaining millisecond execution budget is projected to integer child seconds with `floor`, not `ceil`, so an internal stage can never receive a longer timeout than the end-to-end deadline actually has left. No extra local settlement reserve is deducted because the hosted Worker already owns a separate five-second reply-settlement margin outside the daemon execution budget. Final pre-dispatch budget exhaustion is checked before the snapshot is claimed, preserving one-shot mutation authority on a definite no-side-effect failure. The Worker now defaults both compound Computer Use tools to 30 seconds while retaining the shared 45-second explicit maximum; ordinary configurable foreground tools remain at 20 seconds. Deadline exhaustion during browser/application preflight is no longer swallowed and reclassified as stale/unavailable.
|
|
18
|
+
- Diagnose the separate whole-control-plane interruption with host evidence instead of attributing it to a daemon crash. The launchd daemon remained the same PID with one lifetime run, while `pmset` recorded consecutive Idle/Maintenance Sleep intervals at 06:50–06:58, 06:58–07:15, and 07:15–07:27 local time; daemon `runtime.event_loop.stall` values of roughly 505/718 seconds and a 981-second relay outage align with those suspension windows. On macOS, one `macos-idle-sleep-assertion.mjs` adapter now owns the fixed non-shell `/usr/bin/caffeinate -i -w <owner-pid>` primitive. Authorized, schema-valid relay handlers share a daemon-bound assertion only after policy/account/operation authorization and argument validation succeed; concurrent handlers hold it for their full execution lifetime, and the fixed five-minute inactivity grace begins only after the last daemon-side activity settles. A remote `start_process` extends the same daemon assertion only after resource admission succeeds and releases it when the child settles, including startup failure. Remote account managed-job runners independently acquire a runner-PID-bound assertion only after their runner claim is confirmed and persisted ownership identifies an account-backed job, then retain it across recovery handoff, resource admission, steps, cleanup, and terminal persistence; local managed jobs do not acquire this remote-continuity assertion, so daemon reconnect or service replacement does not own remote runner sleep protection. Runtime shutdown terminates process sessions before releasing the daemon assertion. The relay grace is deliberately fixed rather than depending on shell-only environment inheritance that launchd does not persist as service configuration. Rejected relay traffic cannot keep the host awake, auxiliary guard failures/logging remain fail-open, and no guard claims to prevent explicit sleep or lid-close sleep. Owner diagnostics expose only coarse supported/enabled/active/grace/error-class state, and guard failure logs only a coarse error class without session/job identity.
|
|
19
|
+
- Close the distinct awake relay-interruption path reproduced after beta.100. At 09:12:30 local time macOS reported the network path reachable again while the launchd daemon remained the same process and there was no Sleep/Wake event; the previously ready relay did not close with WebSocket `1006` until about 09:13:39 and returned ready about two seconds later. Beta.100's twenty-five-second application heartbeat and seventy-five/ninety-second local/Worker silence windows therefore allowed an apparently OPEN but black-holed transport to outlive ordinary twenty-second and compound thirty-second foreground budgets. Beta.101 separates transport from application liveness: `RelayLiveness` sends protocol-level WebSocket Ping every five seconds and terminates a transport after ten seconds without inbound proof, while preserving the twenty-five-second JSON application heartbeat and its independent seventy-five-second application-silence timeout; the Worker keeps its wider ninety-second liveness fallback. Protocol Pong therefore cannot mask a Worker application path that has stopped replying. For a scheduling-responsive daemon, the executable contract guards the full probe-plus-silence detection horizon—fifteen seconds—below the ordinary twenty-second hosted execution default, leaving reconnect/result-settlement headroom; a diagnosed local event-loop stall follows the separate recovery-grace path. `relay_transport_timeout` distinguishes that local half-open decision while `relay_heartbeat_timeout` remains the application-silence classification, and authenticated relay diagnostics retain `previous_ready_inbound_silence_ms` so the pre-close black-hole interval is not hidden behind a short close-to-ready recovery duration. The existing five-second new-call readiness wait remains unchanged because the defect was delayed stale-transport detection, not slow reconnect after detection.
|
|
20
|
+
- Close the post-reconnect lost-dispatch hole found during the second independent pass. A Worker call could be registered and written to an apparently OPEN old WebSocket immediately before a half-open transport was rebuilt; if that frame never reached the local dispatcher, same-instance reconnect rebound the Worker pending record but the existing one-way `resume_calls` reconciliation gave the Worker no proof that the daemon had never owned that call, so the request could still wait until its original deadline after the relay itself had recovered. Reconnect reconciliation now snapshots the daemon's active-call and unacknowledged-result ledgers, returns only Worker-resumed IDs absent from both, and sends those bounded IDs as pre-ready `resume_calls_ack.missing_ids` on the same authenticated relay generation. The Worker rejects exactly those still-owned pending records immediately as retryable `unavailable` with `side_effects_started=false` and `reason=daemon_call_not_received_after_reconnect`; active calls and retained terminal results remain rebound, and no mutation is replayed automatically. If the acknowledgement itself cannot be sent, that relay generation is interrupted instead of claiming successful reconciliation. New logs expose only aggregate missing-call counts, never raw resumed IDs, tool arguments, account identity, or results.
|
|
21
|
+
- Close documentation and executable-contract drift found during the independent pass. README no longer claims a blanket 60-second remote foreground process/browser/application envelope; Computer Use documentation no longer claims the first application verifier capture can restart the full action timeout. Architecture, operations, testing, logging, shared server guidance, generated tool reference, Worker timeout tests, and release-contract guards now encode the compound 30-second/default single-deadline contract and the bounded runtime sleep guard.
|
|
22
|
+
- These packaged changes invalidate beta.100's candidate/activation evidence for release purposes. Beta.101 requires fresh frozen fast/full verification, exact candidate preparation and install-only preflight, then a new explicit owner authorization before live activation, activated-package canary, live verification, and acceptance. No commit, push, npm publication, tag, or GitHub Release is authorized by this repair alone.
|
|
23
|
+
|
|
24
|
+
## 3.0.0-beta.100 - 2026-08-17
|
|
25
|
+
|
|
26
|
+
- Supersede the prepared but never activated/accepted beta.99 candidate after a fresh maintainer-level review challenged architecture, state/timeout boundaries, logging, tests, package impact, privacy, and current documentation instead of treating the previous green suite as sufficient evidence. The live owner runtime remains beta.98; beta.99 produced only local fast/full/candidate/install-only evidence and therefore has no live acceptance to preserve.
|
|
27
|
+
- Remove the obsolete internal `LocalRuntime.execCommand(command, timeout)` compatibility branch. The MCP handler has long passed the validated argument record `{ command, timeout_seconds }`; only self-test/full-access fixtures still exercised the second shape. Runtime routing and those fixtures now use the same object contract, and an architecture guard rejects reintroduction of `legacyCall`/`timeoutOrContext` branching. This reduces one parallel parameter/state path without changing the public `exec_command` schema or durable relay routing.
|
|
28
|
+
- Close two audit/hygiene edge cases. `SecurityAuditLog.close()` now normalizes invalid or oversized shutdown delays before `setTimeout` and never extends its existing five-second bounded close window; a control experiment on the previous source produced Node's `TimeoutOverflowWarning` because `Infinity` was converted to a 1 ms timer. Regressions prove both non-finite and `Number.MAX_SAFE_INTEGER` inputs remain pending until a synthetic worker acknowledgement rather than collapsing into timer-overflow behavior. The asynchronous worker-failure termination catch now documents its best-effort semantics, while repository hygiene also recognizes optional-chained empty Promise catches (`.catch?.(() => {})`) so that syntax cannot bypass the existing catch-and-continue rule.
|
|
29
|
+
- Remove duplicated deterministic-host fixtures by sharing one `tests/fixtures/healthy-resource-host.mjs` source across agent-context, full-access, and runtime self-test. Separately, correct package-impact terminology: current `package.json.files` does not ship `tests/`, the beta.99 tarball contains no `package/tests/**`, and `release-impact:check` intentionally ignores a test-only repository change. Contributor/testing guidance, release-impact regression coverage, and architecture contracts now distinguish verification evidence from npm package bytes; recent beta.98 wording is corrected without rewriting historical audit records wholesale.
|
|
30
|
+
- Correct verification-runner concurrency documentation. The default is `min(4, os.availableParallelism())`, not an unconditional four workers; this explains observed beta.99 runs reporting two or three available workers. The release contract now binds that implementation and the documentation states the capped/dynamic rule. Independent tracing of the persistent `activate --json` path found no second stdout-contamination mechanism after beta.97: the inner activation remains captured, JSON mode keeps service loggers quiet/stderr-only, and the remaining inherited-stdio branch belongs to the separate non-persistent foreground path. Targeted sensitive-data scans likewise found no concrete home path, account ID, Worker endpoint, private-key header, bearer header, or client secret in tracked source/docs. Large Computer Use/browser/runtime modules remain close to their executable line ceilings, but no threshold was raised and no speculative refactor was added without a concrete ownership boundary.
|
|
31
|
+
- Diagnose a recurrent owner-visible “message send timed out” symptom without collapsing it into the relay. During the symptom window the live beta.98 relay was ready, Worker call telemetry reported zero tool timeouts, and the only recent transport interruption was a recovered close-1006 episode of about 4.5 seconds. Independently, machine-user resource diagnostics showed Green sampled pressure alongside one active heavy lease, nine queued waiters, and six aged protected waiters; one durable lightweight process query later terminated after the full 30-minute admission ceiling with `resource_error` and no executed step, proving it had never spawned. This is concrete pre-spawn queueing evidence but not proof that the ChatGPT client message timeout had the same direct cause. Beta.100 keeps the existing fairness policy and instead makes the boundary observable: managed jobs publish `current_phase=resource_admission` before spawn and retain `resource_admission_ms` internally within their existing total `duration_ms`; local/owner reads expose that queue timing for diagnosis while delegated non-owner reads omit it, diagnostics expose privacy-safe `waiters.drain_active`, the 1,800,000 ms admission ceiling joins the shared durable-delivery contract and `server_info.tool_delivery`, and remote process tool descriptions distinguish admission time from the 1–600-second child execution budget.
|
|
32
|
+
- Close two additional review races rather than relying on timeout-only mitigation. The local daemon-fixture exit waiter now registers its `exit` listener before a second child-state check, so an exit between the original pre-check and listener installation cannot become a false 30-second hang; settlement is single-shot and architecture-guarded. Promise catch hygiene now also rejects whitespace-, parameter-, and `async`-equivalent empty catches in addition to direct and optional-chained zero-argument forms. The managed-job admission-phase status write is also failure-aware: if restoring the post-admission phase cannot be persisted after a lease is acquired but before spawn, the runner explicitly releases the lease before propagating the status error; if that cleanup itself fails, both failures are surfaced together rather than hiding the lease-cleanup fault.
|
|
33
|
+
- These source/script/documentation changes invalidate beta.99's local receipt and candidate. Beta.100 must complete fresh frozen verification, exact candidate preparation and install-only preflight, then obtain new explicit owner authorization before any live activation/canary/acceptance. No commit, guarded push, npm publication, tag, or GitHub Release is authorized by this review alone.
|
|
34
|
+
|
|
35
|
+
## 3.0.0-beta.99 - 2026-08-17
|
|
36
|
+
|
|
37
|
+
- Supersede beta.98 after its exact candidate was owner-authorized and persistently activated successfully, the activated-package OAuth canary passed authorization-code exchange, authenticated MCP, refresh rotation, refreshed MCP, and cleanup, and live Machine Bridge diagnostics reported `3.0.0-beta.98`, relay readiness, zero pending calls, and a healthy verified security-audit chain with `content_logged=false`. No beta.98 acceptance was recorded: the pre-acceptance source/runtime/documentation cross-check found a shipped testing-contract defect before the candidate could be accepted or guarded-pushed.
|
|
38
|
+
- Correct `docs/TESTING.md`, which still described `full-access:test`, `local-self-test`, and `agent-context-test` as using five-minute real-host-pressure resource-admission waits. The current fixtures are intentionally isolated from shared-host pressure: full-access and agent-context use synthetic healthy-host sampling with ten-second process-admission budgets, and beta.98's runtime self-test uses the same synthetic healthy-host isolation with ten-second one-shot/session admission plus bounded daemon child-exit waits and per-phase progress markers. The separate five-minute managed-job/stdio background-settlement observation windows remain unchanged.
|
|
39
|
+
- Make that documentation boundary executable. Architecture release contracts now reject the obsolete five-minute fixture guidance and require the isolated/synthetic ten-second descriptions to remain present. Because `docs/` is part of `package.json.files`, this documentation repair changes npm-package bytes; beta.98's successful live activation and canary remain operational evidence only and cannot authorize beta.99. Beta.99 requires a fresh frozen fast/full receipt, exact candidate, install-only preflight, new explicit owner activation authorization, activated-package canary, observed live verification, and acceptance before the PR branch can be updated again.
|
|
40
|
+
|
|
41
|
+
## 3.0.0-beta.98 - 2026-08-17
|
|
42
|
+
|
|
43
|
+
- Supersede beta.97 after its accepted branch was committed, passed the guarded GitHub push, and reached PR #85 exact-head hosted validation. Dependency Review, Governance, Workflow Policy, CodeQL Actions, package-audit, Ubuntu full verification, and Windows platform/install all passed on exact commit `e7bf465790961db203ad751e8d876a60db880f98`. Two hosted-only gates did not: JavaScript/TypeScript CodeQL rejected five `js/superfluous-trailing-arguments` findings, while the macOS platform job reached its 20-minute workflow ceiling with task 118/122 (`self-test`) still in progress and was cancelled before the documented global-install step. Neither result is treated as a provider flake or waived.
|
|
44
|
+
- Restore the declared one-parameter runtime API as `remoteForegroundMaximumSeconds(_name)` without changing the calculation or any hosted timeout. Add a direct runtime-arity regression requiring `Function.length === 1`, so future declaration/implementation drift fails locally before GitHub CodeQL. The regression was first demonstrated red against beta.97 and then passed after the repair; lint, typecheck, architecture, and whitespace gates also pass with the behavior-neutral fix.
|
|
45
|
+
- Make the broad runtime/local self-test deterministic on shared macOS CI instead of inheriting machine-pressure behavior that belongs to the dedicated resource-admission suites. The old runtime fixture used a private coordinator namespace but still sampled the real host and allowed each process admission to wait up to five minutes; the local daemon fixture also had an unbounded child-`exit` wait, and the old test emitted no phase markers. The cancelled provider log cannot identify which of those latent paths directly held beta.97, so beta.98 fixes both structural hazards without inventing a single observed cause: runtime fixtures use the existing synthetic-healthy host sampler and a ten-second resource wait, daemon child exit is bounded by the 30-second fixture budget, and each self-test phase reports start/completion. The hardened owner-machine self-test completes all phases in about 30 seconds.
|
|
46
|
+
- Move host-cache coverage back to the resource-admission suite after deterministic self-test isolation removed its accidental real-host coverage. The first beta.98 full run correctly failed only the critical coverage gate because `resource-host-cache.mjs` function coverage dropped to 75%; explicit regressions now prove both non-I/O and fresh-I/O quick CPU refreshes preserve valid scope-local throughput/IOPS hints. The dedicated coverage gate then reports `resource-host-cache.mjs` at 100% function coverage (4/4) without reintroducing shared-host sampling into the broad self-test.
|
|
47
|
+
- Beta.97 acceptance remains valid evidence for the exact beta.97 bytes that were live-tested, but it cannot authorize beta.98 because the packaged shared timeout module, synchronized version metadata, and release notes changed afterward; the accompanying regression test also changed as repository verification evidence but is not part of the npm tarball. Beta.98 therefore requires a fresh frozen fast/full receipt, candidate and install-only preflight, explicit owner authorization for a new live activation, activated-package OAuth canary, observed live verification, and a new acceptance before the PR branch may be guarded-pushed again.
|
|
48
|
+
|
|
49
|
+
## 3.0.0-beta.97 - 2026-08-17
|
|
50
|
+
|
|
51
|
+
- Supersede beta.96 after its exact candidate was owner-activated, passed the activated-package OAuth canary, live Worker/daemon/browser checks, and local acceptance, but recovery of the earlier agent-launched activation job exposed a blocking release-carrier defect. That detached managed-job activation had run for 793.6 seconds and then failed with `persistent candidate activation did not return valid JSON`; the same guarded command subsequently succeeded from an ordinary owner terminal. `pmset` records no sleep/wake event during the failed interval, so the previously repaired idle-sleep mechanism is falsified for this incident.
|
|
52
|
+
- Close the unsafe Wrangler-auth branch that can explain that outcome and independently violates the release contract even when it is not taken. Persistent activation previously stopped the verified login service before `ensureWorkerDeployment()` checked `wrangler whoami`; a failed probe could then start an uncaptured, inherited-stdio `wrangler login` with a ten-minute budget while the inner `machine-mcp activate --json` process was required to emit a single JSON document on stdout. Beta.97 preflights Wrangler authentication in the outer release wrapper before any service handoff. A detached managed job fails before live mutation if authentication is unavailable; an ordinary owner terminal may complete interactive login at that preflight boundary and must pass a second captured `whoami` before activation starts.
|
|
53
|
+
- Make machine-readable Worker deployment non-interactive as defense in depth against authentication expiry between preflight and handoff. `ensureWorkerDeployment(..., { json: true })` now returns `worker_authentication_required` without launching Wrangler login, so an authentication race enters the existing activation rollback instead of holding the service offline or contaminating the activation JSON channel. Ordinary non-JSON startup retains interactive login but now rechecks `whoami` before Worker deploy. Behavior tests cover managed-job fail-closed, terminal login/recheck, JSON no-login, and deploy ordering; architecture guards bind the preflight ahead of the release-runtime lock and forbid JSON-mode login drift.
|
|
54
|
+
|
|
55
|
+
## 3.0.0-beta.96 - 2026-08-17
|
|
56
|
+
|
|
57
|
+
- Adjudicate a second independent reliability/security review against the current source instead of accepting its beta.94-era claims verbatim. The relay already cleared readiness/outage/heartbeat timers on stop, close, fatal, and generation replacement; its first-start resolver was already single-settlement guarded, pending calls and daemon-ready waiters already shared bounded capacity and expiry, JWT/JWS-shaped values were already redacted, and WebSocket 1002/1008/1009/1012 classifications were already explicit. No speculative timer manager, queue LRU, universal IP regex, close-code rewrite, or large-module refactor was added for claims not supported by current behavior.
|
|
58
|
+
- Fix the real lifecycle defect uncovered while testing the timer claim: stopping `RelayConnection` before the first end-to-end readiness acknowledgement now settles the pending `start()` Promise instead of leaving it unresolved forever. `LocalRuntime.start()` also treats a concurrently stopping/stopped lifecycle as authoritative, so a late relay success or failure cannot overwrite shutdown with `running` or `failed`. Deterministic regression coverage binds both sides of the race.
|
|
59
|
+
- Harden internal deadline and relay-envelope boundaries without widening any public timeout. Worker pending-call operation/reconnect delays must now be finite positive safe integers within their shared contract before a timer or alarm is armed; `Infinity`, `NaN`, non-positive, and over-contract values fail before pending state mutates. Local relay tool calls now require the same `call_...` identifier shape used by resume state, a bounded lowercase tool-name shape, strictly typed authorization version/role fields, and an explicit 1–50-second integer `timeout_ms` instead of coercing malformed values.
|
|
60
|
+
- Make catch-and-continue intent executable. Previously silent cleanup/fail-closed catches in browser, application, release, audit, diagnostics, and macOS helper paths now state why the error is intentionally irrelevant to the primary settlement; repository hygiene rejects newly introduced empty synchronous or Promise catch bodies in production/script/extension sources. Browser WebSocket `onerror` also documents that `onclose` owns settlement/reconnect classification rather than pretending the error callback is an independent terminal signal.
|
|
61
|
+
- Remove two post-beta.93 guidance drifts missed by the previous review. `docs/TESTING.md` and shared `server-metadata.json` no longer advertise 30-second ordinary/process foreground behavior: ordinary hosted tools default to 20 seconds plus the separate Worker settlement margin, configurable browser/application work defaults to 20 seconds with a 45-second explicit maximum, `start_process` has a 10-second execution budget, and remote process one-shots are durable-first with 10-second acceptance plus independently bounded 1–600-second execution. Shared instructions now direct ordinary one-step durable process work to its returned `job_id`/`read_job`, reserving owner-only `start_job` for multi-step/resource/finally plans. Privacy guidance also states the actual boundary: compact JWT/JWS/DPoP-shaped values are redacted, while network identity is omitted at source rather than relying on a broad IPv4/IPv6 anonymizer.
|
|
62
|
+
- Keep release verification from inheriting the 600-second remote process-step ceiling. An otherwise green beta.96 full run completed all 130 tasks in 596.0 seconds because `install:test` alone took 229.7 seconds, proving that the process carrier can become the narrower deadline than the suite. Active server guidance, testing/releasing docs, and the agent contract now direct owner-authorized remote `check:full` runs that may exceed 600 seconds through detached `start_job` with a larger explicit step timeout; ordinary one-step durable process work within 600 seconds still uses `run_process`/`run_local_command`/`exec_command` plus `read_job`.
|
|
63
|
+
|
|
64
|
+
## 3.0.0-beta.95 - 2026-08-17
|
|
65
|
+
|
|
66
|
+
- Complete an independent post-incident architecture review of the beta.94 reply-safety repair. The Worker new-call readiness fallback now derives from the shared five-second relay contract instead of retaining a stale ten-second local default, and `start_process` derives its ten-second request-owned execution budget from the same contract rather than a private literal. The obsolete 30-second remote-process foreground budget has been removed from the shared/public delivery contract: remote process one-shots are durable jobs with a ten-second acceptance window and up to 600 seconds of detached execution, while request-owned `start_process` has its own explicit ten-second session-start budget. The lower process service retains a private 30-second defense ceiling only if an internal caller incorrectly bypasses durable relay routing.
|
|
67
|
+
- Make resource-pressure failures more diagnosable without increasing default log noise or exposing user activity. Debug-only `tool.call.failed` events may now include enumerated `resource_admission_reason` and coarse `resource_pressure_state` when cooperative admission rejects before spawn; command text, argv, cwd, project/lease identity, host process names, and probe output remain excluded. Regression coverage binds the safe field set.
|
|
68
|
+
- Stop structurally impossible fixed CPU fan-out from masquerading as transient pressure. A fixed request whose CPU reservation exceeds the machine's best-case priority-specific launch window now fails immediately with non-retryable `cpu_request_exceeds_launch_window` instead of occupying a waiter until its long admission deadline or entering starvation drain. Explicit concurrency is never silently rewritten and the existing host headroom is not relaxed; callers must lower explicit parallelism or resource demand. Elastic/unbounded requests keep their pressure-aware fitting behavior, and genuinely transient `cpu_pressure_window` remains retryable.
|
|
69
|
+
- Keep macOS release verification from fabricating timeout failures during ordinary Idle Sleep. `scripts/run-checks.mjs` now re-executes fast/platform/full checks under a verification-only `/usr/bin/caffeinate -i` guard on macOS, with a private recursion marker and no platform dependency elsewhere. This was added after a frozen-tree fast run entered Idle Sleep six seconds after launch, slept for 594 seconds, and then misclassified a two-second Wrangler lifecycle fixture as timed out immediately after DarkWake. Explicit/lid-close sleep remains outside this guard and still invalidates a live-machine verification run.
|
|
70
|
+
- Repair current-state documentation drift found during the independent review: README, architecture, testing, and logging guidance now agree on the 20+5-second ordinary hosted envelope, five-second new-call recovery, zero-queue relay `start_process` admission, ten-second process-session startup envelope, durable-process timing, and the 500 ms host-snapshot freshness window. Architecture gates reject the stale timing claims and the removed `server_info.remote_process_foreground_execution_max_ms` field so these values cannot silently diverge again.
|
|
71
|
+
|
|
72
|
+
## 3.0.0-beta.94 - 2026-08-17
|
|
73
|
+
|
|
74
|
+
- Close the host-pressure reply-stall path left after beta.93. A live owner-machine incident reproduced `host_pressure_red` and `coordinator_busy` while heavy Xcode/Simulator work kept the machine explicitly awake; remote `start_process` could spend its previous 10-second cooperative resource-admission wait before it even attempted a spawn, consuming a material fraction of the request-owned MCP response lifetime. Relay-origin process sessions now perform one resource-admission attempt without queueing and return the existing retryable `unavailable` error immediately when the host cannot safely admit the process. Owner-local process sessions retain their 10-second cooperative wait, and an explicitly configured resource wait is still honored.
|
|
75
|
+
- Increase hosted reply headroom without reducing explicit long-operation capability. Ordinary daemon-backed tools now default to 20 seconds of remote execution plus the separate five-second Worker settlement margin, configurable browser/application tools also default to 20 seconds while retaining their existing 45-second explicit maximum, and `start_process` receives a 10-second execution / 15-second settlement envelope. A new tool call waits at most five seconds for a temporarily disconnected daemon before returning retryable `unavailable`; already-dispatched calls retain the existing same-instance reconnect/rebind path and their original absolute deadline.
|
|
76
|
+
- Preserve the transport/task durability boundaries that already survived close-1006 relay interruptions in beta.93. Remote process one-shots remain durable managed jobs with caller-held idempotency keys, daemon results remain retained until Worker acknowledgement, and same-daemon reconnect still uses `resume_calls`. The repair does not add MCP replay/session storage or treat response-stream closure as durable delivery; it removes avoidable queueing and default deadline consumption so the Host receives a structured terminal result before its own interaction budget is exhausted whenever the request channel remains available.
|
|
77
|
+
|
|
78
|
+
## 3.0.0-beta.93 - 2026-08-16
|
|
79
|
+
|
|
80
|
+
- Decouple remote process-task lifetime from one MCP response. Hosted `exec_command`, `run_process`, and `run_local_command` now require a caller-held `idempotency_key`, validate their existing authority/cwd/argv contract, commit the operation as a principal-bound one-step managed job, and return a `job_id` with `read_job` recovery metadata before the detached step runs. The MCP acceptance budget is 10 seconds plus the separate five-second Worker settlement margin, while the durable execution budget is independently capped at 600 seconds. Because the recovery key exists before dispatch, an ambiguous acceptance response can be retried against the same durable job instead of creating duplicate work. Worker settlement timeout, response-stream cancellation, and relay reconnect expiry preserve that key plus an explicit same-key replay action in the public error instead of collapsing the call to an unactionable `effect_settlement=pending/unknown`. This makes normal code/build/test commands recoverable across MCP disconnect, relay reconnect, daemon restart, or service replacement instead of terminating or losing their final result with the request stream.
|
|
81
|
+
- Preserve the original security boundary while adding durability. Automatic process persistence authorizes the source tool rather than the owner-only `start_job` capability, keeps managed-job principal ownership/revocation semantics, uses interactive resource-admission priority, and carries non-owner delegated-process isolation into the detached runner. The runner reconstructs the verified workspace sandbox at step spawn using the job's persistent runtime directory; sandbox unavailability still fails closed. The required remote `idempotency_key` reuses the managed-job deduplication contract for ambiguous acceptance responses without making owner-only multi-step job submission available to operators.
|
|
82
|
+
- Separate diagnostic process health from resource queueing. `diagnose_runtime` fixed spawn/shell probes now use the implementation-owned fixed-process path and bypass cooperative resource admission, while resource pressure and waiters remain a separate check. This prevents a healthy OS spawn boundary from being reported unavailable merely because a foreground process was waiting for heavy-resource admission.
|
|
83
|
+
- Keep the daemon's defense-in-depth argument validation aligned with the Worker's durable-process projection. The canonical local MCP schema remains capped at 60 seconds for request-scoped process calls, while relay-origin `exec_command`, `run_process`, and `run_local_command` may carry the Worker's separately validated 1–600 second detached execution budget through daemon validation. A 600-second cross-layer regression proves the widened durable execution field no longer gets rejected by the local 60-second foreground schema before job acceptance.
|
|
84
|
+
- Make persistent activation ownership commit follow verified handoff rather than service-definition installation. Activation now installs the candidate with `service_owner=pending`, starts the candidate against that pending identity, verifies the exact service daemon and Worker version, and only then commits ownership while the machine-service lock is still held. A failed initial start may recover the same pending candidate and commit only after recovery convergence; failed convergence stops an uncommitted candidate, and an owner-commit failure stops the already-verified candidate while retaining pending state for explicit recovery. This removes the `committed` + `loaded=false/active=false` intermediate state without creating the inverse old-owner/new-definition mismatch.
|
|
85
|
+
- Correct the architecture documentation for beta.91's reconnect semantics: pending calls retain one absolute operation deadline across detach/rebind; reconnect consumes that remaining budget rather than pausing it. Regression coverage now proves durable acceptance/recovery after MCP call settlement, strict 1–600 second remote execution validation, delegated sandbox preservation without operator access to `start_job`, and the distinct 10-second acceptance versus 600-second execution budgets. Bounded task-capability routing now also retains an authorized direct-shell fallback even when browser/workspace route scoring fills the route budget, rather than silently evicting the escape hatch it advertises. During targeted verification the live beta.92 relay also experienced and recovered from a close-1006 interruption while the detached test job continued, directly exercising the transport/task-lifecycle separation.
|
|
86
|
+
|
|
87
|
+
## 3.0.0-beta.92 - 2026-08-16
|
|
88
|
+
|
|
89
|
+
- Harden persistent activation against an ambiguous macOS `launchctl bootout` settlement discovered during the beta.91 live candidate run. The activation job failed after 9.1 seconds because the existing launchd service could not be verified stopped, yet the previously ready beta.90 daemon then remained unavailable until launchd recovered it roughly 17 minutes later. `stopLaunchdService()` now keeps observing the bootout for up to about ten seconds and, once a bootout mutation has been dispatched against an initially active service, reports `restore_required=true` even when the stop result remains inconclusive.
|
|
90
|
+
- Make previous-service rollback retryable instead of single-shot. A failed activation that had a verified prior service runtime now repeatedly invokes the idempotent provider start/bootstrap operation and rechecks the exact previous daemon version/entrypoint identity for up to 30 bounded attempts. This specifically closes the race where an immediate recovery `bootstrap`/`kickstart` collides with a still-settling launchd `bootout`; transient start failures no longer abandon the machine with its login daemon offline. The original activation error is still returned after verified rollback, while rollback failure is aggregated with the primary failure.
|
|
91
|
+
- Give autostart-stop failure a stable `autostart_stop_failed` activation reason and add regression coverage for delayed/ambiguous launchd stop rollback obligation plus multi-attempt previous-service recovery. Beta.91's reply-safe hosted execution ceilings, five-second process polling, five-second SSE heartbeat, and absolute pending-call deadline across daemon reconnect remain unchanged.
|
|
92
|
+
|
|
93
|
+
## 3.0.0-beta.91 - 2026-08-16
|
|
94
|
+
|
|
95
|
+
- Close the remaining blank-response timeout path in hosted MCP calls. Beta.90 narrowed process one-shots, but non-configurable daemon tools still received a 60-second execution budget and an in-flight daemon disconnect paused that operation deadline while the Worker waited up to the 120-second reconnect grace. A short call could therefore outlive its original host-visible deadline after relay/service interruption. Pending calls now keep their original absolute operation deadline across detach/rebind: reconnect grace is capped by the remaining operation budget and reconnect time consumes that budget instead of extending it.
|
|
96
|
+
- Make remote synchronous work reply-safe by default without reducing local administrator capability. Ordinary daemon-backed tools now receive at most 30 seconds of remote execution, configurable browser/application foreground tools are capped at 45 seconds, and remote `exec_command`, `run_process`, and `run_local_command` default to 20 seconds with a 30-second maximum. Local stdio/CLI schemas and owner-local command budgets remain unchanged. Long work keeps its full capability through process sessions or durable managed jobs rather than one blocking hosted response.
|
|
97
|
+
- Turn process-session progress reads into short polling. The remote `read_process.wait_ms` schema is capped at 5 seconds and its Worker execution budget is only 5–10 seconds plus the separate five-second settlement margin; the underlying process may continue for its normal session lifetime. `start_process` receives a 20-second remote startup envelope. This prevents repeated process observation from monopolizing a host reply window while preserving retained output and resumability.
|
|
98
|
+
- Increase response-stream liveness and rolling-upgrade clarity. Public MCP SSE heartbeats now arrive every five seconds. Cached hosts that still permit the former process timeout or 30-second `read_process` wait receive a normal pre-dispatch MCP `invalid_request` tool result with `schema_refresh_recommended=true`; malformed types and unrelated schema failures remain JSON-RPC protocol errors. `server_info.tool_delivery` now reports the ordinary remote tool ceiling and process-poll wait ceiling alongside foreground/process maxima and settlement overhead.
|
|
99
|
+
|
|
100
|
+
## 3.0.0-beta.90 - 2026-08-16
|
|
101
|
+
|
|
102
|
+
- Make the new 45-second remote process ceiling compatible with hosts that still cache the previous 60-second `tools/list` schema. A live beta.89 probe from the current ChatGPT connector accepted `run_process(timeout_seconds=46)` at the stale host-schema layer, while the updated Worker correctly rejected it before daemon dispatch; the connector surfaced that JSON-RPC `-32602` as a generic `UNKNOWN/ExceptionGroup`, recreating the class of unhelpful/no-actionable reply the timeout hardening was intended to avoid. Timeout-maximum schema mismatches now return a normal MCP tool `isError` result with `invalid_request`, `side_effects_started=false`, `schema_refresh_recommended=true`, validation detail, and explicit session/job guidance. Fresh hosts still reject from the advertised 45-second schema, while stale hosts receive a structured pre-dispatch error instead of a transport-looking failure.
|
|
103
|
+
- Preserve protocol errors for genuinely malformed calls. Only validation failures consisting exclusively of `/timeout_seconds` `maximum` issues take the stale-schema compatibility path; type errors, unknown fields, missing/unknown tools, and other invalid arguments remain JSON-RPC `-32602`. Unit and full Worker integration coverage assert both sides of that boundary.
|
|
104
|
+
- Supersede beta.89 after its durable managed-job activation successfully crossed the daemon handoff, the exact beta.89 Worker/login daemon became ready, and the activated-package OAuth canary passed. The stale-host compatibility defect was found by a subsequent live over-limit probe, so beta.89 is not accepted and beta.90 requires a fresh exact-tree receipt/candidate/canary cycle.
|
|
105
|
+
|
|
106
|
+
## 3.0.0-beta.89 - 2026-08-16
|
|
107
|
+
|
|
108
|
+
- Fix a live candidate-activation self-termination defect. A release activation launched through Machine Bridge `run_process`, `exec_command`, `run_local_command`, or `start_process` was owned by the current daemon's process tracker; activation intentionally stops that daemon during the service handoff, and daemon shutdown drains tracked process groups with `SIGKILL`. The activation could therefore kill its own parent operation after installing/committing the candidate service definition but before relaunching it, leaving the exact observed state: candidate Worker and committed service owner, but launchd unloaded/inactive. Execution surfaces are now runtime-marked, persistent activation fails before live mutation on daemon-lifetime foreground/process-session surfaces, and durable managed jobs or an ordinary local terminal are the supported activation carriers.
|
|
109
|
+
- Reduce reply-timeout and task-interruption risk for remote process work. `exec_command`, `run_process`, and `run_local_command` now default to 30 seconds remotely and have a 45-second remote ceiling, leaving explicit Worker/host settlement margin instead of consuming the full 60-second interactive envelope. Longer or restart-sensitive work must use `start_process`/`read_process` or, when it must survive daemon replacement or MCP disconnect, `start_job`/`read_job`; browser/application foreground tools retain their existing tool-specific 30/60-second contract.
|
|
110
|
+
- Make execution-surface identity non-spoofable at the runtime boundary. Foreground one-shot processes, process sessions, and detached managed-job runners receive distinct internal surface markers after policy/environment construction; full-env managed jobs overwrite any inherited marker. Release activation accepts only the durable managed-job marker or an unmarked ordinary local terminal, and rejects unknown non-empty markers fail-closed.
|
|
111
|
+
- Keep runtime-scoped resource coordination consistent across detached jobs. A `LocalRuntime` configured with a private `resourceCoordinatorRoot` previously applied it to foreground/process-session execution but not to managed-job runners; a full-access test running under an outer verification-plan lease could therefore wait five minutes for its inner background job behind unrelated machine-global waiters. Managed-job launch and recovery now inherit the runtime's coordinator-root override, eliminating that split-brain while production runtimes with the default root remain machine-user coordinated.
|
|
112
|
+
- Fix a latent no-coordinator process-admission boundary: `acquireProcessResources(null, ...)` now preserves the original command/argv instead of returning only environment metadata, so a standalone `ProcessSessionManager` remains executable without a resource coordinator. Targeted activation, process-session, managed-job, timeout, architecture, lint, and typecheck regressions cover the new contracts.
|
|
113
|
+
- Supersede beta.88 after its exact candidate passed local verification and updated the Worker, but its activation process was terminated by the old daemon during handoff and left the committed beta.88 service definition inactive until manual `machine-mcp service start`. Because this repair changes packaged runtime, release tooling, tests, documentation, and synchronized version metadata after live beta.88 mutation, none of beta.88's candidate evidence is reusable for beta.89.
|
|
114
|
+
|
|
115
|
+
## 3.0.0-beta.88 - 2026-08-16
|
|
116
|
+
|
|
117
|
+
- Clarify execution-layer diagnosis after a real nested-SSH incident exposed an attribution trap: a returned child exit code/stdout/stderr proves the local process was spawned, while an SSH forced-command allowlist refusal is downstream target evidence. Shared MCP instructions, `diagnose_runtime`, README, and operations guidance now direct maintainers to change the narrowest failing authorization layer instead of widening canonical `full` unnecessarily.
|
|
118
|
+
- Reduce Computer Use responsibility concentration by extracting expectation normalization and application state-action validation from the 2.4k-line orchestration module into `computer-use-expectation.mjs`. The public behavior is unchanged, while the architecture gate now budgets the extracted boundary separately and lowers the `computer-use.mjs` ceiling instead of spending its former headroom.
|
|
119
|
+
- Reduce CLI responsibility pressure by moving ready/start presentation into `cli-ready-output.mjs`. The start JSON, human connection banner, initial-owner one-time credential output, and policy summary retain the same behavior; `cli.mjs` drops below 900 lines and its architecture ceiling is lowered from 950 to 900 while the new presentation module receives its own 80-line budget.
|
|
120
|
+
- Make cross-process resource host-sample reads generation-safe without weakening secure-file identity checks. The host sample is intentionally published by atomic replacement; readers now reopen at most four times when that exact cache changes identity during `open`/path verification, while symlink/hard-link violations, malformed JSON, and persistent generation churn still fail closed. This closes a real `agent-context:test` race found under concurrent resource-admission load.
|
|
121
|
+
- Close a filesystem generation race in structured mutations. Patch update/move/delete now re-read and hash the exact source generation after it has been renamed into the transaction backup, before any replacement is published or deletion is finalized; a concurrent change between preflight and rename is restored and rejected instead of being mistaken for the observed source. `edit_file` and `write_file` with `expected_sha256` now reuse that same quarantine/no-overwrite transaction path rather than maintaining a weaker check-then-overwrite sequence. Deterministic fault injection covers both patch deletion and optimistic atomic writes.
|
|
122
|
+
- Remove the release workflow's duplicate full-suite run without weakening the frozen-tree gate. A successful `check:full` now writes an ignored owner-local receipt bound to the exact verification generation, package identity, Node/platform identity, and a six-hour freshness window; starting another full run clears the old receipt before tests begin, so a failed or interrupted rerun cannot leave reusable success evidence. `release:candidate` requires that exact-tree receipt before packing and fails with explicit `check:full` guidance when source, runtime, version, or freshness drifts. The receipt contract has direct behavior tests, architecture assertions, and critical coverage.
|
|
123
|
+
- Isolate `agent-context:test` from the machine-user resource-admission namespace. Its registered-command fixture previously inherited the production cross-process coordinator and allowed a five-minute fairness wait inside a full-plan task whose own timeout was also five minutes, so unrelated heavy jobs on the same Mac could turn an otherwise healthy verification into a deterministic timeout. The fixture now uses a private temporary coordinator root and a ten-second internal wait; cross-process fairness remains covered by the dedicated resource-admission suites instead of leaking into an unrelated capability-discovery test.
|
|
124
|
+
- Apply the same isolation rule to the full-access diagnostic. Its purpose is to prove canonical `full` file, process, shell, environment, SSH-key, client, sudo-probe, and managed-job capabilities; machine-user admission fairness is independently covered by resource-admission tests. The diagnostic's `LocalRuntime` now uses a private temporary resource coordinator and a ten-second process wait instead of allowing unrelated host workloads to consume five minutes. This removes an observed 299-second release-gate stall without weakening any full-access assertion.
|
|
125
|
+
- Make capability-test resource admission deterministic under real host load. `LocalRuntime` now accepts internal `resourceCoordinatorOptions` dependency injection while production callers retain the default real host sampler. The agent-context and full-access test fixtures inject a healthy synthetic host snapshot in addition to private coordinator roots, so host red-pressure cannot turn unrelated capability assertions into admission failures; dedicated resource-admission tests remain the authority for real/synthetic pressure, fairness, aging, and denial behavior.
|
|
126
|
+
- Supersede beta.87 after its exact candidate completed local fast/full/frozen-candidate verification, owner-authorized activation, exact deployed OAuth canary, live runtime/application verification, acceptance, guarded push, all exact-PR-head CI/CodeQL/platform checks, and squash merge to `main`. The first exact-main CI display then exposed a final current-control-plane terminology leak: Ubuntu/package-audit steps were still named `Verify interactive candidate acceptance`.
|
|
127
|
+
- Close the terminology boundary across the whole current CI path rather than patching only the visible step names. `.github/workflows/ci.yml` now labels both portable acceptance steps `Verify local candidate acceptance`; the portable verifier's success message, workflow-policy contract description, TESTING guide, and release-contract diagnostics use the same term. Historical changelog/audit references remain untouched.
|
|
128
|
+
- Strengthen architecture verification so CI workflow YAML, the portable verifier, the workflow-policy contract, and TESTING all reject the obsolete `interactive candidate acceptance` phrase and positively require the new local-acceptance wording. Because workflow/docs/tests and versioned package metadata change after beta.87 acceptance, beta.88 requires a fresh candidate/live/acceptance/exact-head cycle.
|
|
129
|
+
|
|
130
|
+
## 3.0.0-beta.87 - 2026-08-15
|
|
131
|
+
|
|
132
|
+
- Supersede the live-verified, accepted, committed, and guarded-pushed beta.86 after its own guarded-push output exposed a remaining documentation/diagnostic consistency defect: `scripts/github-push.mjs` still printed "Verified interactive local candidate acceptance", the portable CI acceptance verifier used the same obsolete adjective in failure messages, and current ENGINEERING/RELEASING/OPERATIONS guidance still contained fragments of the retired owner-terminal/real-TTY activation and publication contract. The executable beta.86 authorization behavior was already correct; these stale current-contract surfaces could still mislead operators and future maintainers back toward the policy the owner explicitly removed.
|
|
133
|
+
- Remove the remaining current `interactive`/`owner-terminal` release wording without rewriting historical changelog/audit records. Guarded push and portable CI now refer simply to local candidate acceptance. ENGINEERING requires explicit current-task owner authorization plus `--owner-confirm` and the publication lock, while making TTY presence explicitly optional. RELEASING now states that, after explicit owner authorization, either the owner or an authorized agent may run exact candidate activation; conversational authorization is sufficient, and an agent must not race an operation the owner says they will perform themselves. OPERATIONS now classifies a failed activation command by outcome rather than terminal shape.
|
|
134
|
+
- Add executable architecture regressions that reject the obsolete current-contract phrases in GitHub push/portable acceptance verification and operational documentation. This closes the review gap that allowed beta.85's audit to state that current operational TTY wording had been removed while several current surfaces still retained it. Because these scripts, docs, and regression tests are release-relevant/package-shipped bytes, beta.86 acceptance cannot be reused; beta.87 requires a fresh candidate/live/acceptance cycle.
|
|
135
|
+
|
|
136
|
+
## 3.0.0-beta.86 - 2026-08-15
|
|
137
|
+
|
|
138
|
+
- Supersede beta.85 after its frozen candidate passed the final 102-task fast plan, two independent 129-task full/candidate gates, direct-Node install-only verification, owner-authorized live activation, exact activated-package OAuth canary, Worker/service/relay diagnostics, and live application inventory. The live inventory exposed one remaining authority-projection defect before acceptance: an authenticated owner correctly had 54 effective tools at the Worker/account layer, but the local runtime projected application capabilities as if the owner lacked `open_local_application`, Accessibility automation, and Computer Use.
|
|
139
|
+
- Fix effective tool derivation at its real authorization boundary. Relay authority intersection intentionally produces a synthetic `effectivePolicy.profile="custom"`; `runtime.effectiveToolNames()` incorrectly passed that synthetic profile back through `toolNamesForPolicy()`, where tools with `availability="full"` require the literal canonical `full` profile. A full owner therefore collapsed to 37 projected tools even though the actual ToolExecutor authorization chain (`daemon PolicyGate` followed by the account-role gate) allowed all 54. The runtime now derives projected effective tools from that same executable gate intersection instead of reinterpreting the synthetic policy profile.
|
|
140
|
+
- Add a direct relay-owner application-inventory regression requiring discovery, launch, Accessibility inspection/actions, and window-observation capabilities to remain visible under a full daemon, while the existing reviewer regression still requires read-only discovery with projected paths and no launch/UI capabilities. This preserves custom-daemon restrictions because the daemon PolicyGate remains the first operand; no synthetic custom policy is promoted to full.
|
|
141
|
+
- beta.85 was deliberately not accepted, committed, or pushed after this live mismatch. beta.86 therefore requires a fresh fast/full/candidate/install-only cycle, live activation, exact packaged OAuth canary, live capability verification, acceptance, guarded push, and exact-head hosted validation.
|
|
142
|
+
|
|
143
|
+
## 3.0.0-beta.85 - 2026-08-15
|
|
144
|
+
|
|
145
|
+
- Supersede beta.84 before source publication. beta.84 was activated, canary/live-verified, accepted, merged to `main`, and passed exact-head Ubuntu/macOS/Windows/package-audit/governance/CodeQL checks, but it was not tagged, published to npm, or installed from the registry. The owner then explicitly rejected two unnecessarily restrictive workflow contracts before publication: GitHub source release required a real TTY even after explicit owner authorization, and delegated capability resolution suppressed installed-application discovery entirely. Because this change affects shipped release tooling, policy metadata, runtime routing, tests, and documentation, beta.84 acceptance is not reused for beta.85.
|
|
146
|
+
- Replace the GitHub publication TTY ceremony with explicit owner authorization. Source publication/backfill now use `--owner-confirm`; the guarded script accepts either a TTY or an explicitly authorized local automation/Machine Bridge invocation. The flag remains mandatory and is checked before fetch or remote mutation. No integrity gate is removed: clean `main`, exact `origin/main`, current candidate acceptance, required soak for stable, full verification, exact-head CI, accepted-tarball staging, local/remote tag conflict checks, GitHub asset SHA-256 reconciliation, release metadata convergence, trusted local `git`/`gh`, and the common-Git-dir publication lock all remain fail-closed. npm publication and registry/global activation remain separate operations that require their own explicit owner request.
|
|
147
|
+
- Make installed-application inventory a baseline read-only capability. `list_local_applications` moves from `full` to `always`, and the account-access contract revision advances from 3 to 4 so remote authority metadata truthfully reflects the wider reviewer/editor/operator tool set. Restricted roles still receive projected external paths rather than raw absolute paths and still cannot open applications, inspect Accessibility/window contents, operate UI, control the browser, or gain shell/write authority.
|
|
148
|
+
- Fix a path-projection privacy bug exposed by that widening. `AppAutomationManager.listApplications()` accepted the request context for cancellation/discovery but previously called its injected `displayPath()` without forwarding that context for application and warning paths; on a full daemon, a delegated account could therefore fall back to the local owner/full absolute-path display policy. Application inventory and discovery warnings now project paths with the originating request context, and the launch result uses the same context-aware projection. A real reviewer relay fixture requires both application and warning paths to omit the private temporary root.
|
|
149
|
+
- Separate application inventory from desktop automation in both capability projection and routing. A new `application-capability-projection.mjs` projects backend support through the effective tool set so reviewer bootstrap **and direct inventory results** can report `discovery=true` without falsely advertising launch/inspection/action/screenshot capabilities. Routing gains an `application-discovery` set containing only `list_local_applications`; the existing `application` route contains only actionable desktop tools. Behavior tests pin both the discovery-only and full projections and prevent delegated routing from recommending unusable mutation surfaces. The extracted authority boundary is also an explicit package-inventory item, architecture boundary module with a 50-line ceiling, strict-JS typecheck root, and 100% function/branch critical-coverage target rather than relying on transitive import reachability.
|
|
150
|
+
- Independent review rechecked multi-account authorization order, path projection, structured logging, current/reachable-history privacy, release-evidence boundaries, generated policy/tool documentation, source-module ceilings, package modes, consumer security, and SBOM closure. The new source module was initially created as `0600`; the existing package-mode contract correctly caught that drift and the file was normalized to `0644` instead of weakening the gate. Read-only surfaces that expose window/page contents remain `full` because they are privacy-sensitive reads rather than harmless inventory. No additional confirmed credential leak, swallowed-success branch, or authorization bypass was found.
|
|
151
|
+
|
|
152
|
+
## 3.0.0-beta.84 - 2026-08-15
|
|
153
|
+
|
|
154
|
+
- Supersede beta.83 before owner activation. beta.83 passed its focused matrix, 102-task fast plan, two independent 129-task full/candidate gates, privacy-history review, and direct-Node install-only verification, but was never activated, accepted, committed, or pushed. A subsequent host-routing investigation found additional shipped diagnostic/documentation/privacy-contract improvements, so none of beta.83's candidate evidence is reused; its Windows state-root canonical-path fix carries forward unchanged.
|
|
155
|
+
- Correct the remaining host-routing diagnosis gap. Live `server_info` and `diagnose_runtime` proved beta.82 owner/full authority, 54 effective tools, daemon readiness, relay readiness, and healthy local probes while explicitly reporting that final host exposure is unknown. The ChatGPT workspace custom app was independently observed as enabled, and two fresh Work conversations successfully invoked `machine-mcp server_info`, while the user's quoted historical statements that Machine Bridge was "directly disabled by the platform" were both found in one older conversation. A pre-response failure is therefore still not observable by Machine Bridge and now explicitly names conversation/surface app routing plus stale host action/tool snapshots alongside filtering/gateway/client/platform possibilities. A fresh-conversation success is documented as evidence against a blanket server/platform outage, not as proof of the exact host-internal cause of an older conversation failure.
|
|
156
|
+
- Harden browser-source privacy guidance. During the host investigation, bounded raw DOM serialization of an authenticated web application demonstrated that source markup can contain hidden bootstrap/session/account/authentication data that is absent from the rendered page. No such live data is retained in repository evidence. `browser_get_source` now advertises itself as a high-disclosure raw-markup read and directs routine semantic work to `browser_inspect_page`; privacy, security, local-automation, generated tool-reference, and routing regressions enforce the same boundary. Machine Bridge deliberately does not claim to redact arbitrary site-controlled HTML.
|
|
157
|
+
- Refresh ChatGPT client guidance to current workspace-app semantics: workspace-level enablement, per-surface host routing, cached action/tool snapshots, and app refresh/review after MCP action/schema changes are separate from Machine Bridge daemon authority. Independent review also rechecked empty catches, destructive-path canonicalization, Windows tail fixtures, logging/privacy boundaries, debt markers, and large-module ceilings; no additional confirmed swallowed-success branch, destructive containment flaw, tracked secret, or portable-host regression was found.
|
|
158
|
+
|
|
159
|
+
## 3.0.0-beta.83 - 2026-08-15
|
|
160
|
+
|
|
161
|
+
- Supersede the accepted and guarded-pushed beta.82 exact head after hosted Windows independently validated the beta.81 launchd repair and then exposed the next production safety defect. Windows `check:platform` passed `service-platform:test` plus tasks 112-116 (`delegated-sandbox`, macOS trust/native-build synthetic boundaries, agent context, and browser page automation) before failing task 117 `self-test`. The state phase expected removal validation to reject a state root containing the currently executing Machine Bridge CLI, but that guard did not trigger on Windows.
|
|
162
|
+
- Fix the current-entrypoint state-root removal guard instead of weakening the fixture. `assertSafeStateRootForRemoval()` passes an existing root canonicalized with ordinary `realpathSync`, while `currentEntrypointInsideStateRoot()` canonicalized only the entrypoint through the potential-path helper backed by `realpathSync.native`. Windows can represent the same drive through different path namespaces (for example ordinary `D:\\...` versus native `\\\\?\\D:\\...`); `path.relative()` then sees different roots and can return an absolute path, incorrectly classifying the live CLI as outside the state root. The guard now canonicalizes both the root and entrypoint through the same potential-path path family before containment, and falls back to `path.resolve()` for both together rather than mixing representations.
|
|
163
|
+
- Add deterministic `node:path.win32` regression evidence for the ordinary/native namespace mismatch and same-namespace containment, plus an architecture guard requiring both operands to pass through the same canonicalizer. Marker validation, allowed namespaces, workspace/source exclusions, maintenance locking, generation-bound quarantine/removal, and all other uninstall semantics remain unchanged. Because packaged runtime/test/documentation bytes changed after beta.82 activation and acceptance, beta.83 requires a fresh candidate, owner activation, activated-package canary, live verification, acceptance, guarded push, and exact-head hosted validation.
|
|
164
|
+
|
|
165
|
+
## 3.0.0-beta.82 - 2026-08-15
|
|
166
|
+
|
|
167
|
+
- Supersede beta.81 before owner activation. The beta.81 launchd target-resolution repair passed its targeted checks, the 102-task fast plan, two independent 129-task full/candidate gates, and direct-Node install-only validation, but its exact tarball was never owner-activated, accepted, committed, or pushed. A fresh independent review then found additional packaged privacy and verification-boundary defects, so none of beta.81's candidate evidence is reused. The launchd repair carries forward unchanged.
|
|
168
|
+
- Make recovered activation evidence synthetic rather than exception-derived. Verified post-readiness recovery previously copied the lower-layer `error.message` into `recoveryDetail`, which then flowed through CLI JSON/owner output and could be persisted in schema-2 activation records. Recovery now has one shared allowlisted reason-to-canonical-detail contract. Runtime recovery, persistent child-result validation, activation-record validation, and the activation writer all use that boundary. Historical bounded schema-2 detail remains readable but is normalized in memory; current writers never republish the historical raw text. Fault-injection tests place private-looking paths, reserved test URLs, and credential-shaped placeholders in lower-layer errors and require them to stay absent from returned and persisted recovery evidence.
|
|
169
|
+
- Harden the generic non-replayable process pre-spawn boundary. A raw child/spawn exception before mutation no longer becomes an exposed `BridgeError` message; callers receive the fixed `process failed before spawn` result while the original exception remains available only as a local `cause`. Already-classified policy/cancellation errors retain their explicit public contracts, and post-spawn mutation uncertainty remains unchanged.
|
|
170
|
+
- Close a verification blind spot around `src/shared`. Shared JavaScript runtime contracts are now included in the dynamic syntax scanner and in the correctness ESLint configuration/CLI, with self-tests proving `no-undef` and unused-import enforcement on the shared surface. The new activation-recovery contract is also an explicit strict-JS typecheck root, npm-package inventory requirement, architecture line-budget target, and critical-coverage module; measured coverage is 100% functions and 100% branches. The package gate also caught the newly created source file at owner-only `0600`; it was normalized to the existing `0644` source-file contract rather than weakening package-mode validation.
|
|
171
|
+
- Correct current release documentation that still claimed schema-1 prerelease activation records were accepted and normalized. The executable release contract has intentionally been schema-2-only since the beta.62 hardening; schema-1 `previous` records are historical evidence rather than supported input to current release commands. Privacy/testing documentation now records the canonical recovery-evidence rule and the broader cross-platform fixture rule: injecting a logical platform must not silently reuse incompatible UID, mode-bit, signal, path, or service-manager evidence from the physical CI host.
|
|
172
|
+
- Independent review also rechecked structured logging/audit output, empty-catch cleanup sites, package contents/modes, source-module reachability, later Windows platform tasks, tracked/reachable-history privacy, generated policy/tool references, consumer package security, and CycloneDX structure. No additional confirmed credential leak, swallowed-success branch, orphan source module, or stale current operational compatibility path was found. Because these packaged runtime/test/documentation bytes change after beta.81 candidate preparation, beta.82 requires a completely fresh candidate, owner activation, activated-package canary, live verification, acceptance, guarded push, and exact-head hosted validation.
|
|
173
|
+
|
|
174
|
+
## 3.0.0-beta.81 - 2026-08-15
|
|
175
|
+
|
|
176
|
+
- Supersede beta.80 after its exact candidate completed local fast/full/candidate gates, direct-Node install-only validation, owner activation, activated-package OAuth canary, live Worker/service/relay/browser/privacy verification, acceptance, commit, and guarded push. Exact-head hosted Windows directly validated both preceding portability repairs: `resource-admission:test` passed in 3.5 seconds and `macos-background-input:test` passed in 0.3 seconds. The next independent failure was `service-platform:test`, which invoked the synthetic launchd stop contract on Windows and failed before its mocked status read because `stopLaunchdService()` eagerly resolved `gui/<uid>` targets from the host's nonexistent `process.getuid()`.
|
|
177
|
+
- Make launchd stop target resolution follow the mutation boundary. `stopLaunchdService()` now reads and classifies current status before resolving any launchd domain/service target; safely-unloaded and status-unavailable branches therefore require no UID and still perform no provider mutation. Only an actually loaded service resolves targets. The internal test dependency may supply an explicit UID for synthetic launchd mutation contracts, while the production default remains the current OS user's `process.getuid()`.
|
|
178
|
+
- Strengthen the platform-independent regression instead of skipping Windows. Status-only launchd cases deliberately provide an invalid test UID and must still return without target resolution; loaded-service cases inject UID 501 and assert the exact `launchctl bootout gui/501/dev.machine-bridge-mcp.daemon` command. No service-provider selection, launchd label, production UID source, stop verification, or fallback semantics are relaxed. Because packaged source and tests changed after beta.80 acceptance and guarded push, beta.81 requires a fresh candidate, activation, live verification, acceptance, guarded push, and exact-head hosted validation.
|
|
179
|
+
|
|
180
|
+
## 3.0.0-beta.80 - 2026-08-15
|
|
181
|
+
|
|
182
|
+
- Supersede beta.79 after its exact candidate passed the 102-task fast plan, two independent 129-task full gates, direct-Node install-only verification, owner activation, the activated-package OAuth canary, live Worker/service/relay/browser/privacy checks, acceptance, commit, and guarded push. Exact-head hosted Windows then proved the beta.78 resource-admission repair was effective: `resource-admission:test` completed successfully in 3.8 seconds. The next independent failure was `macos-background-input:test`, whose synthetic forced-darwin fixture required exactly one helper compilation from the real host filesystem.
|
|
183
|
+
- Keep production native-helper trust unchanged. `MacosBackgroundInputService` intentionally reuses a cached helper only when `executableRegularFile()` can prove a trusted regular file with POSIX executable bits and no group/other write bits. The cross-platform test forces `platform: "darwin"`, but on a real Windows host Node cannot use `chmod` to establish POSIX execute-bit evidence. The second synthetic helper call therefore recompiles instead of trusting that cache entry, even though real macOS reuse remains correct.
|
|
184
|
+
- Make only the non-portable cache assertion host-aware. The fixture still requires a compile, validates the hashed owner-local source copy, helper payloads, native-result projection, invalid-coordinate rejection, probe behavior, and mutation settlement on Windows; exact compile-once cache reuse is asserted only where the host filesystem can provide POSIX mode evidence. No production macOS helper build, ownership, permission, digest, cache, or input-dispatch rule is relaxed. Because the packaged regression changed after beta.79 acceptance and guarded push, beta.80 requires a fresh candidate, owner activation, activated-package OAuth canary, live verification, acceptance, guarded push, and exact-head hosted validation.
|
|
185
|
+
|
|
186
|
+
## 3.0.0-beta.79 - 2026-08-15
|
|
187
|
+
|
|
188
|
+
- Supersede beta.78 before owner activation. The beta.78 resource-admission portability repair passed targeted validation, the 102-task fast plan, two independent 129-task full gates, candidate packing, and direct-Node disposable installation, but its exact tarball was never activated, accepted, committed, or pushed. A separate review then found packaged diagnostic, privacy, architecture, and documentation improvements, so beta.78 evidence is intentionally not reused. The Windows cwd fixture repair remains unchanged: host-canonical `path.resolve()` results are the contract and no resource-admission production behavior is relaxed.
|
|
189
|
+
- Correct pre-runtime failure attribution. A successful `diagnose_runtime` now states only the fact it can prove—that the current request reached the local runtime—and explicitly says this evidence does not support a blanket current platform disable. A request rejected before Machine Bridge returns a structured response is marked **not observable by Machine Bridge**; host tool filtering, connector gateway, client routing, and platform policy remain possible causes that require host-side evidence rather than being collapsed into a platform diagnosis. Client guidance and regression coverage now encode the same distinction.
|
|
190
|
+
- Harden Computer Use public error projection. Ambiguous mutation and post-observation results no longer echo lower-layer exception text into successful MCP result fields, and browser preflight/verification details no longer embed raw backend messages in exposed `BridgeError.details`. Public settlement retains the stable reason plus a coarse `error_class`; original causes remain local-only debugging evidence. Regressions inject private filesystem paths into trusted-input, wait, cancellation, and document-preflight failures and require those paths to stay absent from public results.
|
|
191
|
+
- Reduce high-risk orchestration density without changing behavior. The fixed macOS Accessibility JXA implementation moved from `app-automation.mjs` into `app-automation-macos-jxa.mjs`; Computer Use request normalization/cross-field validation moved into `computer-use-arguments.mjs`. Architecture guards now inspect the extracted JXA secure-field and selector-index invariants directly, tighten the `app-automation.mjs` and `computer-use.mjs` line budgets, and add explicit growth ceilings for the largest browser-extension execution modules instead of allowing those boundaries to expand silently.
|
|
192
|
+
- Clean live documentation drift. `UPGRADING.md` no longer labels the beta.61/beta.60 transition or its old npm-channel snapshot as current; it preserves only the historical persisted-state invariant needed to explain bounded migration readers. Architecture, local-automation, Computer Use, and client diagnostics documentation now name the actual module/error-projection boundaries. Independent privacy/security review found no obvious tracked credentials; the repository privacy gate also passed over tracked files and reachable Git history. Because packaged bytes changed after the beta.78 candidate was prepared, beta.79 requires a completely fresh candidate, owner activation, activated-package OAuth canary, live verification, acceptance, guarded push, and exact-head hosted validation.
|
|
193
|
+
|
|
194
|
+
## 3.0.0-beta.78 - 2026-08-15
|
|
195
|
+
|
|
196
|
+
- Supersede beta.77 after its exact candidate passed local fast/full gates, owner activation, packaged OAuth canary, live Worker/service/relay/browser verification, acceptance, and guarded push. Exact-head Windows then ran well past the beta.76 Wrangler cleanup-race failure and exposed the next independent portability defect in `resource-admission:test`: `resourceCommandEffectiveCwd()` correctly returned the host-canonical Windows path `D:\\tmp\\project-a`, while the fixture required the POSIX input literal `/tmp/project-a`.
|
|
197
|
+
- Keep resource-admission production semantics unchanged. `resourceCommandEffectiveCwd()` deliberately canonicalizes both the base cwd and literal shell `cd` targets through Node `path.resolve()`, so contention keys use host-native absolute paths. The regression now compares both the narrowed literal cwd and the dynamic-cwd fallback against `resolve(...)`, preserving the same POSIX expectations while accepting the correct drive-qualified Windows result.
|
|
198
|
+
- Because `tests/resource-admission-test.mjs` is packaged and changed after beta.77 acceptance and guarded push, beta.78 requires a fresh exact candidate, owner activation, activated-package OAuth canary, live verification, acceptance, guarded push, and exact-head hosted validation from scratch.
|
|
199
|
+
|
|
200
|
+
## 3.0.0-beta.77 - 2026-08-15
|
|
201
|
+
|
|
202
|
+
- Supersede beta.76 after its exact candidate completed local fast/full gates, owner activation, activated-package OAuth canary, live Worker/service/relay/browser verification, acceptance, and guarded push. Exact-head Windows then proved both preceding repairs were effective: `process-output:test` passed in 1.3 seconds and `managed-job-boundary:test` passed in 0.2 seconds. The next independent failure was `worker-types-generator:test`, whose cleanup-race fixture required a child-installed `SIGTERM` listener to print a marker after the completion grace elapsed.
|
|
203
|
+
- Remove that host-signal assumption from the Wrangler lifecycle regression. Node's Windows signal model does not deliver `SIGTERM` to a JavaScript listener like POSIX; `subprocess.kill("SIGTERM")` uses Windows termination emulation instead. `runCompletedWranglerCommand()` now exposes its existing child-kill operation through an injectable internal `killChild` dependency whose default remains exactly `child.kill(signal)`. The cleanup-race fixture injects only the graceful cleanup request, records that the completion grace actually triggered `SIGTERM`, and lets the real child reach its existing 250 ms normal exit. This tests the lifecycle state-machine race directly without changing default production termination behavior or depending on OS signal delivery.
|
|
204
|
+
- Keep the real hanging-Wrangler cases on the default kill path, so bounded graceful cleanup and forced-cleanup behavior remain exercised against actual subprocesses. Because the packaged lifecycle script and regression changed after beta.76 acceptance and guarded push, beta.77 requires a fresh exact candidate, owner activation, activated-package OAuth canary, live verification, acceptance, guarded push, and exact-head hosted validation from scratch.
|
|
205
|
+
|
|
206
|
+
## 3.0.0-beta.76 - 2026-08-15
|
|
207
|
+
|
|
208
|
+
- Supersede beta.75 after its exact candidate passed the local 102-task fast plan, 129-task release-candidate gate, owner activation, activated-package OAuth canary, stable-path protocol-3 browser handshake, real background-tab DOM click/hover verification, one-shot snapshot rejection, runtime/privacy audit, local acceptance, and guarded push. Exact-head Windows then proved the beta.75 process-session repair itself was effective: `process-output:test` completed successfully in 1.2 seconds. The Windows platform job instead failed later in `managed-job-boundary:test` because that test unconditionally required an observed directory-descriptor mode of `0o700`, while the production resolver deliberately does not open managed-job directories with POSIX descriptor flags on Windows.
|
|
209
|
+
- Preserve the existing platform-specific managed-job boundary instead of changing runtime behavior to satisfy the fixture. POSIX continues to pin an already-existing directory with `O_RDONLY | O_NOFOLLOW | O_DIRECTORY` and an explicit private `0o700` mode argument. Windows continues to use its existing real-directory `lstat` plus canonical/path device-and-inode identity checks rather than a POSIX-only directory-descriptor open. The testing contract already documented the explicit mode requirement as POSIX-only; the hosted failure exposed that the executable fixture had not encoded the same boundary.
|
|
210
|
+
- Make `managed-job-boundary:test` platform-correct. The real-host `openSync` mode assertion now runs only off Windows, while a synthetic `platform: "win32"` case supplies an `openSync` implementation that would fail if called and proves the Windows root resolver returns the canonical directory without entering POSIX descriptor pinning. No managed-job production source or permission/identity rule is relaxed by this repair.
|
|
211
|
+
- Because `tests/managed-job-boundary-test.mjs` is part of the candidate package and changed after beta.75 acceptance and guarded push, beta.76 requires a fresh exact candidate, owner activation, activated-package OAuth canary, live verification, acceptance, guarded push, and exact-head hosted validation from scratch.
|
|
212
|
+
|
|
213
|
+
## 3.0.0-beta.75 - 2026-08-15
|
|
214
|
+
|
|
215
|
+
- Supersede beta.74 after its exact candidate passed the full 129-task gate, owner activation, packaged deployed OAuth canary, stable-path protocol-3 extension handshake, live background-tab DOM click/hover verification, one-shot replay rejection, runtime/privacy audit, local acceptance, guarded source push, and hosted Ubuntu/full, macOS/platform+install, package-audit, governance, dependency-review, workflow-policy, and both CodeQL jobs. The only exact-head failure was Windows `check:platform`, where `process-output:test` spent about 31 seconds and finally reported an incomplete process-session shutdown from `testSessionAuthorityRevocation`.
|
|
216
|
+
- The Windows failure was a test-portability defect, not evidence that the production five-second shutdown contract was too short. `terminateProcessTree()` on Windows returns true once `taskkill.exe` is successfully spawned, because target settlement is asynchronous; the synthetic failed-delivery fixtures instead assumed that a fake child's `kill() => false` would be consulted synchronously. The forced-kill assertion therefore failed on Windows, skipped deletion of its fake session, and the test's `finally` cleanup waited on that impossible synthetic session and replaced the original assertion with a teardown error. The earlier beta.72 fifteen-second fixture override merely stretched the same failure twice, matching the roughly 31-second hosted duration.
|
|
217
|
+
- Make the synthetic failure cases platform-independent by explicitly injecting `manager.terminateTree = () => false` only while testing definite delivery rejection, restoring the real tree terminator afterward, and deleting every synthetic session in its own `finally` block so a failed assertion cannot contaminate or mask final cleanup. The delivered-but-unsettled case keeps its explicit 100 ms synthetic deadline. Remove the test-only fifteen-second manager override so the real current-version session cleanup again exercises the unchanged production-default five-second settlement contract.
|
|
218
|
+
- No runtime process-tree or process-session implementation is relaxed by this repair. Because the packaged test bytes changed after beta.74 acceptance and guarded push, beta.75 must repeat candidate preparation, owner activation, candidate-bound deployed OAuth canary, live verification, acceptance, guarded push, and exact-head hosted checks from scratch.
|
|
219
|
+
|
|
220
|
+
## 3.0.0-beta.74 - 2026-08-14
|
|
221
|
+
|
|
222
|
+
- Supersede beta.73 after its exact candidate was owner-activated, its packaged deployed OAuth canary passed, the new stable release-channel extension path was loaded successfully, and the browser completed an exact `3.0.0-beta.73` protocol-3 handshake with Computer Use/CDP capabilities present. Real background-tab acceptance then exposed a separate blocker: ordinary `browser_inspect_page` could read a complete synthetic tab while `computer_observe` intermittently timed out, and a snapshot-bound click later hit the five-second browser preflight timeout before any safe replay decision could be made. Beta.73 therefore proves the stable extension-path migration but is not accepted or publishable.
|
|
223
|
+
- Bound the shared Chromium DevTools session lifecycle instead of letting raw `chrome.debugger` promises hold a tab queue indefinitely. Attach and each `sendCommand` now have five-second settlement deadlines, detach has a bounded cleanup deadline, and a late successful attach after timeout schedules best-effort detach. A timed-out command releases the per-tab session queue instead of waiting for the outer broker timeout while subsequent Computer Use requests accumulate behind it.
|
|
224
|
+
- Preserve failure semantics across that new deadline. DevTools observation treats the internal timeout marker as a fatal CDP-capture failure so `observe_computer` can use its existing semantic fallback rather than swallowing the timeout and issuing more CDP commands. Trusted Input already marks dispatch before invoking each Input command; a timed-out Input command therefore remains `dispatchStarted=true`, `safeToFallback=false`, and resolves through the existing unknown-mutation settlement instead of DOM fallback or automatic replay.
|
|
225
|
+
- Regression coverage makes a CDP command promise never settle, verifies that the observation rejects promptly, detaches, and a second observation on the same tab can run; a separate trusted-hover fixture verifies that an Input command timeout is not replay-safe. Focused trusted-input, DevTools-observation, and browser-Computer-observation checks pass. Because packaged bytes changed after beta.73 activation/canary, beta.74 must repeat exact candidate preparation, owner activation, candidate-bound canary, live background-tab verification, hosted exact-head checks, and acceptance from scratch.
|
|
226
|
+
|
|
227
|
+
## 3.0.0-beta.73 - 2026-08-14
|
|
228
|
+
|
|
229
|
+
- Supersede beta.72 after its exact candidate was owner-activated and passed the packaged deployed OAuth canary, but browser acceptance could not begin: the documented upgrade flow said to reload the unpacked extension while local-candidate `extension_path` pointed inside a versioned release runtime that activation later pruned. Chrome retains the original unpacked source directory, so reloading an extension loaded from a prior candidate could not switch it to the new candidate directory. The broker correctly rejected the resulting stale/no-hello candidate and kept `extension_reload_required=true`; beta.72 is therefore not accepted or publishable.
|
|
230
|
+
- Give local release candidates one stable owner-only `release-channels/browser-extension` source directory. A versioned candidate runtime reports that stable path, while ordinary checkout/global runtimes keep their own package path. After Worker/daemon convergence is verified, activation copies the exact installed candidate extension into the stable directory with bounded no-symlink reads, atomic per-file replacement, stale-file removal, and `manifest.json` committed last as the version marker; only then may inactive candidate runtimes be pruned or activation evidence be written.
|
|
231
|
+
- Existing users whose unpacked extension was loaded from a now-pruned beta.72-or-earlier candidate runtime need one migration: Load unpacked from the beta.73 `extension_path`. Subsequent local-candidate upgrades keep that path stable and require only Reload plus any newly requested browser permission. Pairing replacement still requires the existing explicit extension-icon gesture when browser-local pairing belongs to different local state.
|
|
232
|
+
- Candidate-runtime/store regression coverage now proves same-path cross-version publication, manifest-last ordering, stale-file cleanup, source-symlink rejection, candidate-runtime path routing, and release activation ordering. State-root removal recognizes the bounded real-file browser-extension namespace and still fails closed on unexpected entry types.
|
|
233
|
+
|
|
234
|
+
## 3.0.0-beta.72 - 2026-08-14
|
|
235
|
+
|
|
236
|
+
- Supersede beta.71 after its exact candidate was owner-activated, passed the packaged deployed OAuth canary, passed live background-tab Computer Use click/hover verification, and was locally accepted, but the first exact-head hosted PR checks found portability and static-analysis defects that the macOS release gate could not exercise. Ubuntu exposed a test-only assumption that the default Linux sampler could not read `/proc/pressure/*`; Windows exposed an authority-revocation fixture whose final cleanup reused the production five-second teardown deadline even though the test was not asserting that deadline; CodeQL 2.26.3 rejected nine newly introduced findings before merge. Beta.71 therefore remains historical live evidence but is not publishable.
|
|
237
|
+
- Make the Linux resource-admission fixture platform-correct while retaining the injected no-PSI regression, and give the authority-revocation fixture a bounded fifteen-second cleanup settlement budget without changing the runtime's fail-closed five-second process-session shutdown contract. The ordinary live-child cleanup test continues to exercise the default runtime deadline.
|
|
238
|
+
- Resolve the CodeQL findings rather than blanket-accepting them. Browser drag cleanup removes redundant press/release flags while preserving the same best-effort release after every attempted press; form and Computer Use validation remove provably unreachable branches; application window-box comparison relies on the already-normalized sole caller contract. macOS screenshot capture and the manual background-input smoke now perform size/type validation and content reads through the same open file handle, eliminating the reported path `stat`/`read` races.
|
|
239
|
+
- The first beta.72 complete candidate rerun exposed one more real teardown race in the packaged full-access self-test: `LocalRuntime.stop()` is asynchronous, but the fixture discarded its promise and immediately removed the temporary root while managed-job shutdown could still be writing below `jobs/`, producing `ENOTEMPTY`. The fixture now awaits complete runtime shutdown before deleting its sandbox, preserving the runtime's close-settled ownership contract instead of racing its own cleanup.
|
|
240
|
+
- Focused DevTools input, page automation, Computer Use, application automation/screenshot, macOS background-input, process-output, resource-admission, and syntax checks pass after the repair. Because packaged source changed after beta.71 activation and acceptance, beta.72 must repeat complete candidate preparation, owner-terminal activation, candidate-bound deployed OAuth canary, observed live browser verification, hosted exact-head checks, and acceptance from scratch.
|
|
241
|
+
|
|
242
|
+
## 3.0.0-beta.71 - 2026-08-14
|
|
243
|
+
|
|
244
|
+
- Supersede the owner-activated but unaccepted beta.70 candidate after real browser Computer Use smoke exposed a background-tab settlement defect. The beta.70 extension paired successfully at protocol 3 and `computer_observe` returned coherent DOM/Chromium-Accessibility snapshots, but DOM `click` and `hover` could time out at the broker after dispatch while a read-only inspection proved the click had actually changed the page. The existing non-replayable settlement correctly returned an unknown outcome and forbade same-action retry, so no duplicate mutation occurred, but a normal browser action could not reliably produce confirmed live evidence. Beta.70 is therefore not accepted or publishable for these bytes.
|
|
245
|
+
- Keep the existing pointer safety checks and remove their dependency on throttled page-renderer timers. Packaged page automation now requests its bounded 50/100 ms actionability waits from a same-extension service-worker timing endpoint; the endpoint accepts only the current extension identity and exact integer delays from 1 through 250 ms. If the extension timing service becomes unavailable, the action still fails through the existing definite/unknown side-effect boundary rather than bypassing stable-box or pointer-hit validation. The renderer `setTimeout` fallback remains only for non-extension/unit environments where `chrome.runtime.sendMessage` is absent.
|
|
246
|
+
- Add regressions that make the old failure deterministic by disabling renderer timers while retaining the extension timing service, and separately pin the service-worker sender/range boundary. Focused page-automation, service-worker, trusted-input, browser-request-settlement, Computer Use, browser-security, and module-boundary checks pass, followed by the frozen 102-task fast plan. Because this repair changes packaged extension bytes after beta.70 activation and deployed OAuth canary evidence, beta.71 must repeat exact candidate preparation, owner-terminal activation, candidate-bound deployed canary, observed live browser verification, and acceptance from scratch.
|
|
247
|
+
|
|
248
|
+
## 3.0.0-beta.70 - 2026-08-14
|
|
249
|
+
|
|
250
|
+
- Integrate the independently developed Computer Use vNext capability onto the current beta.69 codebase without merging its obsolete parallel MCP session/resumption architecture. The native MCP contract remains request-scoped `2026-07-28`; remote initialization compatibility remains stateless and bounded, with no `Mcp-Session-Id`, recovery GET, `Last-Event-ID`, persisted replay/session state, or legacy prepare/subscribe delivery descriptors. The packaged catalog grows from 52 to 54 tools by retaining beta.69 `git_commit` and adding owner-scoped `computer_observe` / `computer_act`.
|
|
251
|
+
- Add snapshot-bound browser and macOS application control. `computer_observe` combines bounded semantic evidence with native MCP screenshot content when available; `computer_act` requires the exact one-shot snapshot, performs read-only preflight, consumes mutation authority before backend handoff, dispatches at most once, captures post-state, and reports dispatch/effect settlement separately. Browser identity is bound to tab/document/frame/semantic evidence with high-confidence backend-node trusted input; application identity binds PID to exact libproc process birth plus owner-window evidence. Continuation, semantic delta, explicit expectation verification, screenshot-bound point/drag/scroll actions, and conservative retry guidance are included without exposing caller-selected JavaScript, JXA, raw CDP methods, backend-node IDs, or unbound screen coordinates.
|
|
252
|
+
- Extend the packaged browser extension with fixed shared DevTools session/observation modules, Chromium Accessibility plus DOMSnapshot fusion, frame/document epoch checks, screenshot provenance, trusted drag/wheel/text input, mutation-settlement tracking, and cancellation gates. The existing beta.69 pairing design is retained unchanged: process-owned one-shot fragment bootstrap, broker HMAC proof, extension identity/version/capability checks, and token-free public pairing status continue to be authoritative. Browser mutation classification now has one source, and transport send/timeout/disconnect/malformed-response uncertainty after dispatch is a fixed non-retryable unknown outcome while pre-send/read-only failures preserve their definite/retryable semantics.
|
|
253
|
+
- Extend macOS application automation with bounded window screenshots, PID-generation-bound Accessibility state, exact private value readback for verification, owner-window geometry, and a fixed native input helper. Snapshot-bound visual input remains disabled unless `MBM_MACOS_BACKGROUND_VISUAL_BACKEND=skylight-experimental` is explicitly configured and its probe succeeds. A new manual smoke runner uses a synthetic temporary application fixture and refuses to run without both the experimental setting and `--run`; it is intentionally outside automatic CI/TCC-dependent release preparation.
|
|
254
|
+
- Close two settlement gaps exposed by the integration. Fixed launch/JXA/native-input subprocesses now preserve definite pre-spawn failures but report timeout, cancellation, process error, resource-binding loss, or nonzero unknown settlement after process start as non-retryable `process_outcome_unknown_after_spawn`; the ordinary process API retains its historical behavior. Patch transactions now separately expose `patch_recovery_incomplete` when rollback of already-committed user-file state fails, while staging-only cleanup failure remains an internal cleanup fault.
|
|
255
|
+
- Apply the ordinary 7 MiB MCP tool-result boundary before publishing a Computer Use snapshot. If screenshot content alone would exceed the result, Machine Bridge removes the image and pixel-action authority but retains the still-valid semantic snapshot and private identity evidence. Post-action capture applies the same rule without losing the already-established dispatch/effect settlement or bounded `post_snapshot_id`; both capture-level and action-result-level screenshot omission now expose the structured `tool_result_budget` reason, while semantic-only compaction does not invent a screenshot omission. `post_screenshot_included` reflects actual returned native image content rather than policy intent. Regressions cover oversized initial and post-action application images and preserve non-replayable continuation semantics.
|
|
256
|
+
- An independent integration review challenged the seams added around the vNext port rather than assuming reference-source parity was sufficient. It corrected the actual-vs-requested post-image flag, unified two-stage result-budget observability, removed a latent false screenshot-omission reason from semantic-only compaction, and found stale snapshot-version documentation after the page module had moved to version 3. Browser snapshot-version documentation is now executable architecture policy. README and system overview also distinguish current native MCP from bounded stateless initialization compatibility so the removed session/replay model cannot return through documentation drift.
|
|
257
|
+
- The first complete release gate exposed a separate integration artifact: 17 ported browser/Computer Use/native/documentation files still had owner-only `0600` checkout modes and were rejected by `package:test`. The source modes are normalized to ordinary non-executable `0644` rather than weakening package hygiene; the targeted package manifest check now accepts the 455-file package inventory. A final repository-mode inventory also normalized six non-packaged Computer Use test fixtures that retained the same accidental owner-only mode.
|
|
258
|
+
- A subsequent candidate rerun exposed an unrelated but real resource-coordinator race under concurrent machine load: a reader could observe the exclusive publisher's legitimate short-lived staging inode and fail a heavy command with an internal error even though no corrupt lease/waiter existed. Live staging now has the stable `MBM_RESOURCE_STAGING_BUSY` classification; transaction readers release the lock generation and perform at most four five-millisecond retries, persistent live ownership still fails closed, and process admission maps exhausted staging/transaction contention to the existing retryable resource-unavailable result. Existing dead-publisher recovery remains identity-bound, and the original `full-access` path plus focused admission/process tests cover the repaired race.
|
|
259
|
+
- A second independent post-closure review found three additional cross-layer defects and two governance gaps. Computer Use snapshot TTL and application verification deadlines had inherited an injectable `Date.now()` duration clock, while resource-backed exact-value verification handles still used wall time despite the manager already owning a monotonic clock; snapshot authority now lives in a dedicated bounded store, all three lifetimes are monotonic, and clock rollback has regression coverage. Browser mutations whose extension-side result was oversized or unserializable were already non-retryable but lost structured side-effect settlement at the broker boundary; direct application unknown outcomes likewise dropped lower-level process settlement metadata. Both paths now preserve structured `side_effects_started` / `termination_requested` / `effect_settlement` evidence. Architecture now governs the Computer Use core/observation/recovery/native/browser modules and extension responsibility sizes, pins the local and extension 7 MiB result caps together, and critical coverage gates the Computer Use kernel rather than only its budget helper. Cheap DevTools input/observation, browser Computer Use, service-worker, and application-automation fixtures move into the fast plan.
|
|
260
|
+
- Keep the new responsibilities bounded instead of expanding central orchestrators: browser request settlement, non-replayable process settlement, and Computer Use result-budget handling are extracted into dedicated modules with architecture line caps; `LocalRuntime` remains below its constructor responsibility ceiling. The three settlement/budget boundaries now have explicit critical coverage thresholds and focused behavior fixtures, and BrowserOperationService coverage includes the Computer Use adapter entrypoints. Generated Tool/Policy references, local automation, architecture, security, threat-model, privacy, logging, overview, and testing documentation describe the same current contracts. The fast verification plan now contains 102 tasks after promoting five high-value GUI security fixtures; the final frozen fast run is required before candidate preparation. After normalizing the ported file modes, the complete 129-task plan also passes 129/129, including package, SBOM, install, stdio, Worker integration, and OAuth-browser verification; candidate preparation still reruns the complete frozen gate against the exact packaged source.
|
|
261
|
+
|
|
262
|
+
## 3.0.0-beta.69 - 2026-08-13
|
|
263
|
+
|
|
264
|
+
- Supersede beta.68 after its exact candidate was owner-activated, matched candidate provenance, passed the packaged deployed OAuth canary and live Worker/daemon/service verification, and was locally accepted, but the next ordinary local `git commit` could no longer be issued reliably through the generic MCP process surface. Machine Bridge's owner/full authorizer still permits local execution; the unstable boundary was the public tool shape: `run_process`/`exec_command` correctly advertise destructive/open-world arbitrary execution, so an upstream host safety layer may stop a repository-local commit before the request reaches the daemon. Beta.68 was never committed or pushed, its acceptance is removed, and the packaged repair moves to beta.69 rather than weakening the generic process annotations.
|
|
265
|
+
- Add a narrow `git_commit` tool for the common local-history operation without weakening generic process risk signaling. It is available only at the existing direct-exec policy level, so an edit-only account cannot create history. The trusted Git executable uses fixed plumbing: `write-tree`, `commit-tree`, then compare-and-swap `update-ref` against the previously observed HEAD. The message crosses stdin rather than argv; repository hooks, signing, editor invocation, staging, amend, push, tag, and publication are absent from the operation. A concurrent HEAD change fails closed instead of overwriting the competing commit, and an empty staged tree is rejected. Because a control experiment proved that even `write-tree` can execute a repository clean filter, structured commit also rejects executable filter configuration before touching the staged tree.
|
|
266
|
+
- Move Git repository discovery in front of every implementation-owned Git subprocess. Machine Bridge now walks only authority-permitted ancestors, rejects symbolic `.git` markers, reads bounded no-follow single-link gitdir/commondir pointer files, canonicalizes and authorizes the Git/common/object metadata roots plus recursive alternate object stores, and only then runs status/diff/log/show/commit. This closes a pre-existing linked-worktree/submodule class where a workspace-local `.git` pointer could make fixed read-only Git tools cross the configured filesystem boundary; alternate object stores receive the same recursive authority check, partial-clone lazy fetch is disabled, and `git_commit` separately authorizes its canonical worktree/object/ref metadata write roots before mutation.
|
|
267
|
+
- A second independent Git challenge reproduced repository-controlled clean-filter execution from both structured status and ordinary working-tree diff under the old fixed argv. Structured Git now disables optional index refresh, system config/attributes, lazy fetch, terminal prompts, signatures, submodule traversal, and external diff/textconv where applicable; working-tree/index-conversion operations fail closed on executable repository filters or external config/attributes indirection. `git_log` additionally requires exact record framing so malicious control characters cannot shift an unrequested author email into another projected field. Direct `.git` metadata is classified sensitive for delegated file access.
|
|
268
|
+
- Redacted local status now omits active, pending, and retired public/private JWK coordinates plus local key tags while retaining bounded diagnostic key identity/provider/timestamp metadata.
|
|
269
|
+
- Add real temporary-repository regressions for staged-only commit behavior, hook/signing suppression, stdin message isolation, empty-index and UTF-8 size failures, actual Git metadata write-root authorization, filter/include fail-closed behavior, alternate-object authority, CAS ref conflicts, malicious-log framing, local-state JWK redaction, and linked-worktree denial before any unauthorized Git subprocess. Catalog/schema/handler/authorization/routing tests now cover the 52-tool contract, and generated Tool Reference documentation is synchronized from the catalog.
|
|
270
|
+
- A fresh independent beta.69 review tightened structured Git discovery again before candidate freeze. Restricted callers now reject symbolic-link or special-file descendants inside Git metadata trees; literal path names cannot be reinterpreted as pathspec magic; `project_overview` reuses the same filesystem-first repository discovery instead of a second raw probe; and uncommon symbolic refs accepted by Git are no longer rejected by a narrower local grammar. External diff-order indirection plus partial-clone/promisor configuration also fail closed.
|
|
271
|
+
- Full verification exposed a separate Worker ready-path timing drift: ordinary async scheduling could be counted as reconnect recovery even when a verified daemon was already available. `daemon-ready-dispatch.ts` now assigns zero recovery delay to the already-ready path and measures only actual recovery waiting; focused runtime and Wrangler integration regressions preserve the original execution/settlement deadline contract.
|
|
272
|
+
- A third independent review found that the new plumbing commit path could flatten an in-progress merge into a single-parent commit while leaving `MERGE_HEAD` behind. `git_commit` now refuses merge, rebase, cherry-pick, revert, bisect, and sequencer state before `write-tree`; exhaustive marker coverage plus a real merge repository prove the rejection leaves HEAD/state unchanged. Restricted Git metadata-tree inspection now observes the runtime cancellation signal instead of traversing up to its entry ceiling after a call is cancelled or times out, and the five fixed Git process environment values have one authoritative source shared with the exact-value validator. The same review removed an obsolete `SECURITY.md` section that still described the retired resumable/session-backed MCP transport and added a documentation contract so those replay semantics cannot silently return.
|
|
273
|
+
|
|
274
|
+
## 3.0.0-beta.68 - 2026-08-13
|
|
275
|
+
|
|
276
|
+
- Supersede beta.67 after its exact accepted commit was guarded-pushed and mandatory hosted provider checks exposed four defects that local macOS verification could not close. Ubuntu reproduced an inode-reuse ABA in managed-job retirement; Windows exposed an unreferenced process-session revocation settlement timer that could leave top-level await unsettled; hosted macOS exposed lifecycle-test ordering that started a new termination case while a prior timeout was still draining and attached its rejection observer too late; JavaScript/TypeScript CodeQL rejected two read-only descriptor opens that omitted explicit private modes. Because the repair changes packaged source after beta.67 activation and acceptance, beta.67 remains historical live evidence but cannot authorize these bytes; beta.68 uses a new prerelease identity and must repeat candidate activation, deployed canary, live observation, and acceptance.
|
|
277
|
+
- Pin managed-job directories across the destructive quarantine rename on POSIX instead of relying on pathname reinspection alone. The pre-rename generation still matches the full filesystem identity, while an open directory descriptor keeps the original inode referenced through rename so a remove/recreate race cannot recycle that numeric inode before the moved-path device/inode check. This mirrors the state-root retirement boundary and fixes the Linux ABA without incorrectly comparing ctime after rename, because rename itself legitimately changes directory ctime.
|
|
278
|
+
- Keep process-session authority-revocation/shutdown settlement deadlines referenced while the caller is awaiting them. Ordinary `read_process` waits remain unreferenced, but a security-critical revocation cannot allow an otherwise-idle Node process to exit with an unsettled top-level await merely because its deadline timer was `unref()`ed. The Windows regression now completes under the production settlement contract.
|
|
279
|
+
- Make the runtime self-test observe lifecycle boundaries rather than machine speed. After a deliberate timeout it waits within the production process-tree escalation budget for tracker cleanup before beginning the next termination case, waits for the new process to increase tracker ownership, and attaches a rejection observer immediately so a fast SIGTERM cannot become an unhandled rejection. This preserves the production resource coordinator instead of bypassing it for the test.
|
|
280
|
+
- Add explicit private modes to the read-only project-metadata descriptor (`0600`) and state-root directory pin (`0700`). These flags do not create the existing targets, but make the least-privilege intent explicit at the open boundary and remove the ambiguous temporary-file sink shape reported by hosted CodeQL without adding a SARIF exception or weakening the zero-unaccepted-findings gate.
|
|
281
|
+
|
|
282
|
+
## 3.0.0-beta.67 - 2026-08-13
|
|
283
|
+
|
|
284
|
+
- Supersede the activated beta.66 candidate after a relay-availability incident review found real transport interruptions that did not correspond to daemon-process restarts. Historical logs include repeated abnormal WebSocket interruption/connect-timeout episodes and one reconnect-grace expiry that discarded a retained completed result; a fresh observation during this review reproduced a short `1006` relay interruption while the daemon remained healthy. macOS sleep/dark-wake explains some multi-minute event-loop stalls, but a separate long outage occurred without a matching sleep event, so VPN/TUN/network transport and local suspend remain distinct fault classes rather than one assumed root cause. Beta.66 has activation evidence but no repository acceptance record for this source generation; the packaged relay repair therefore moves to a new prerelease number instead of reusing the activated version.
|
|
285
|
+
- Keep short event-loop stalls tolerant but stop treating a many-minute local pause plus continued relay silence as a fresh liveness grace period. If measured event-loop lag already exceeds the heartbeat timeout plus the full recovery grace and the relay is still silent beyond the heartbeat timeout, the daemon treats the old WebSocket as stale and enters the existing same-daemon reconnect/rebind path immediately. Fresh inbound relay traffic processed after resume preserves that proven-live socket on the ordinary recovery path. A deterministic relay regression covers the fresh-inbound race as well as the stale-silent boundary.
|
|
286
|
+
- Make reconnect-grace expiry machine-queryable. `RelayCallRecovery` now emits the warning event `relay.calls.reconnect_expired` with only aggregate `cancelled_calls`, `discarded_results`, and `grace_ms`; no arguments, results, account identity, or call identifier is added. Runtime tests pin the aggregate fields, and operations/testing documentation now distinguishes short-stall recovery from long-pause reconnect.
|
|
287
|
+
- Complete an independent post-fix review across Worker waiter capacity/deadline accounting, release-runtime provenance, resource admission, state-root retirement, logging, privacy, documentation, and module boundaries. The review kept delegated pending activity hidden, preserved the 30+2 Worker capacity contract, found no tracked secret/key artifacts or TODO/FIXME/HACK residue, and explicitly scoped the stale historical audit wording about the first failed beta.66 activation so it cannot be read as denying the later successful beta.66 activation.
|
|
288
|
+
|
|
289
|
+
## 3.0.0-beta.66 - 2026-08-13
|
|
290
|
+
|
|
291
|
+
- Supersede beta.65 after its exact candidate passed frozen local/release gates, was activated by the owner, reported matching live daemon/Worker identity, completed the candidate-bound OAuth canary, and was locally accepted. A second independent staged-diff review before commit then found another member of the same resource-accounting family: npm's project/user configuration can redirect `npm run` through `script-shell`, so a canonical outer npm argv could still execute an arbitrary wrapper before the canary entrypoint while retaining the zero-resource `release-control` profile. An isolated control project reproduced that behavior, while the real beta.65 checkout reported `script-shell=null`, so the successful live canary itself was not affected. Beta.65 acceptance was deleted; beta.65 was never committed, pushed, tagged, released, or published.
|
|
292
|
+
- Move the liveness exception off npm lifecycle execution entirely. A subsequent independent pre-candidate review also rejected the first direct-Node form because `node scripts/release-oauth-canary.mjs ...` executed the mutable checkout module graph while admission proved only the canary entry file bytes; a same-version change in one of its local imports could therefore run unaccounted work. Beta.66 had not yet produced or activated a candidate, so the same beta.66 generation was tightened before freeze. Only exact direct Node argv `node <activated-runtime-package>/scripts/release-oauth-canary.mjs --allow-live-oauth-canary` may become `release-control`: the script operand must be absolute and canonicalize to the running package's own canary, the resolved Node executable must canonicalize to the daemon's `process.execPath`, the environment must contain none of the guarded Node/native debugging, profiling, TLS, loader, or resource-startup overrides, and the cwd package/version plus canary source bytes must match the running package. The packaged canary imports only activated-runtime modules while treating `process.cwd()` as the candidate/evidence data root. For prereleases it also canonicalizes its own package root and requires it to equal the package root containing activation `runtime_entry`, so a workspace/developer copy cannot produce indistinguishable release evidence even when its entry bytes match. Across both prerelease and stable channels it additionally requires the currently verified, startup-ready service daemon to report the candidate version, an `entryScript` canonically equal to that same package's `bin/machine-mcp.mjs`, and a canonical Node executable equal to the canary's `process.execPath`, and a daemon-lock Node runtime version equal to `process.versions.node`; this closes the future stable provenance gap without introducing a second activation-record schema. It requires exactly one `--allow-live-oauth-canary` argument, requires an empty `process.execArgv` so ordinary invocations cannot add Node preload/loader/debugger/profiler/runtime flags, and refuses `--state-dir`, `--workspace`, or any other unrecorded local-state override before state access, so acceptance evidence cannot silently describe a noncanonical state root. Workspace-relative Node, npm lifecycle, copied canary, shell-wrapped, and alternate-package-manager forms remain ordinary accounting. Regression coverage pins PATH shadowing, relative PATH resolution, Windows executable lookup, Node startup/environment injection, npm lifecycle fallback, activated-runtime entry identity, exact canary argv, and runtime/workspace byte identity.
|
|
293
|
+
- Make the canary independent of `npm_execpath` while retaining its package-content proof. The reusable `npm-cli.mjs` resolver locates a validated npm CLI from the running Node installation layout, including a package-manager prefix derived from Homebrew Cellar Node paths; the release canary disables lifecycle-provided and unrelated fallback locations before its explicit `--ignore-scripts` pack dry-run. The beta.66 npm version, Git tag, and GitHub Release were confirmed unused before the bump. Because these packaged bytes differ from the accepted beta.65 candidate, beta.66 must repeat the full frozen candidate, owner-terminal activation, deployed canary, live observation, and acceptance sequence.
|
|
294
|
+
- Reject the first prepared beta.66 candidate before activation after the owner-terminal command hit the promotion-content preflight with `npm pack dry-run returned an invalid file mode: 384`. The two post-candidate source files `src/local/resource-foreground-wait.mjs` and `src/worker/daemon-ready-waiters.ts` had been created as owner-only `0600`; promotion identity deliberately permits only package-safe `0644`/`0755`. That source/candidate check runs before the hardened npm session, candidate-runtime installation, Worker deployment, service handoff, or activation-record write, and no beta.66 activation record exists. Both files, plus the later extracted recovery-budget module, are normalized to `0644`. A tarball-to-current-package comparison also proved that the checkout had accumulated packaged runtime changes after the old candidate was frozen, so that candidate is discarded rather than repaired in place and beta.66 must be regenerated from the final reviewed tree. To prevent another owner-terminal attempt from being used as an agent-side freshness check, the canonical agent preflight is now direct Node argv `node scripts/start-release-candidate.mjs --install-only`, which runs the same source/promotion/tarball checks plus a disposable candidate install without Worker/service activation or activation evidence. The install-only path resolves a validated npm CLI from the running Node installation instead of trusting lifecycle `npm_execpath`, so project/user `script-shell` cannot interpose before the proof. The release workflow requires this agent preflight immediately before owner handoff.
|
|
295
|
+
- Harden the post-candidate availability work uncovered while reviewing that failed activation. Production foreground process resource admission no longer gets accidentally pinned to the historical two-second constructor override: `resource-foreground-wait.mjs` derives the default from 20% of the execution budget with a two-second floor, ten-second ceiling, and never beyond the execution timeout, while process-session startup defaults to ten seconds and explicit test/diagnostic overrides remain bounded at thirty minutes. New remote calls may wait up to ten seconds for a briefly reconnecting verified daemon, but that wait is capped by and deducted from the call's original execution/settlement budget using monotonic elapsed time, so the 60-second execution plus five-second Worker-settlement envelope cannot grow to 75 seconds and a one-second call cannot wait ten seconds before dispatch. Pre-dispatch daemon-ready waiters and already-detached pending calls share the same 30 ordinary + 2 reserved-control admission algebra, preserving `diagnose_runtime`/`list_roots` recovery capacity during an outage. Owner `server_info` keeps `pending_calls.active` as dispatched-call count while adding privacy-safe pre-dispatch waiter and combined capacity totals, so diagnostics no longer under-report the admission slots consumed during reconnect; delegated accounts continue to receive only hidden-activity capacity limits. Focused runtime/resource/Worker/architecture tests and critical-coverage thresholds pin the default wiring, deadline consumption, cancellation, waiter cleanup, combined-capacity behavior, and diagnostic projection.
|
|
296
|
+
|
|
297
|
+
## 3.0.0-beta.65 - 2026-08-13
|
|
298
|
+
|
|
299
|
+
- Supersede beta.64 after its exact candidate was owner-activated, the live daemon/Worker reported `3.0.0-beta.64`, the deployed OAuth canary started immediately and passed authorization-code exchange, authenticated MCP, refresh rotation, refreshed MCP, and cleanup, and local acceptance was recorded. An independent staged-diff review before commit then found one remaining member of the same resource-admission failure family: the release-control exception proved the cwd package/script identity but still identified the outer package manager only by basename `npm`. A PATH-resolved wrapper or lookalike could therefore inherit zero-resource accounting even though generic light commands had already been hardened to executable identity. Beta.64 was never committed, pushed, tagged, released, or published; its acceptance record is removed and cannot authorize beta.65.
|
|
300
|
+
- Bind the release-control exception to the executable that the OS would actually invoke. `resource-release-control-executable.mjs` resolves the first npm candidate in spawn search order instead of skipping an untrusted first match, canonicalizes its target, requires an npm/npm-cli target name, rejects cwd/HOME-contained targets and POSIX group/world-writable files, and supports explicit absolute npm paths. Only after that executable proof, the existing exact npm `run release:oauth-canary` lexical contract, and the runtime-bound cwd package/entrypoint proof all succeed does `resource-process-admission.mjs` grant the `release-control` light profile; otherwise the command falls back to ordinary heavy/adaptive accounting. Focused regressions cover a trusted npm, a HOME-shadowing first PATH match, an unsafe writable npm, a missing executable, a cwd-local executable, absolute invocation, and non-npm targets.
|
|
301
|
+
- Reserve `3.0.0-beta.65` only after confirming the npm version, Git tag, and GitHub Release are unused. Because the fix changes packaged runtime bytes after beta.64 activation, beta.65 must repeat frozen fast/full/release-only verification, exact candidate preparation, owner-terminal activation, deployed OAuth canary, observed live verification, and acceptance before any commit or push.
|
|
302
|
+
|
|
303
|
+
## 3.0.0-beta.64 - 2026-08-12
|
|
304
|
+
|
|
305
|
+
- Supersede the activated but unaccepted beta.63 candidate after the deployed OAuth-canary step exposed a resource-classification false positive under real multi-project concurrency. The exact canary managed job remained in admission for roughly twenty minutes without spawning a step or producing OAuth evidence because the generic package-script heuristic treated any `release:*` name as a `js-build` workload, charging 2 CPU, 0.5 I/O, and 2 GiB even though `release:oauth-canary` performs bounded local evidence work, an `--ignore-scripts` npm pack dry-run for promotion identity, and network control-plane requests. The job was cancelled only after its terminal result proved `steps=[]` and no `oauth-canary.json` existed, so no synthetic OAuth mutation had started. The classifier now exempts only direct npm argv for the canonical `release:oauth-canary` command as a light control-plane operation; shell-wrapped forms, alternate package managers, `release:candidate`, and lookalike names remain heavy. Architecture also pins the exact script body and forbids implicit `prerelease:oauth-canary`/`postrelease:oauth-canary` npm hooks so lifecycle expansion cannot smuggle extra local work into the exception. The liveness exception is additionally bound to the command cwd: its package name/version must match the currently running Machine Bridge runtime and its canary entrypoint bytes must match the runtime's packaged entrypoint, so another workspace cannot obtain the exception merely by choosing the same script name. Beta.63 is not accepted or published, and beta.64 must repeat frozen verification, exact candidate preparation, owner activation, and the live canary so the classification fix is exercised by the installed runtime itself.
|
|
306
|
+
- Close the adjacent generic shell-light laundering path found while challenging that exception. The previous light detector trusted a shell payload whose text began with a cheap probe such as `echo`, `ps`, or `git status` unless a short denylist appeared after a control operator; an unrelated generic command, startup profile, PATH-resolved lookalike, substitution, or later shell segment could therefore inherit a zero-resource bypass without proving the executable that would actually run. Arbitrary shell execution now receives no generic zero-resource class at all: it remains adaptive or is promoted by the existing heavy shell/build classifiers. The canary exception is direct npm only, so no shell syntax/profile proof is part of that liveness boundary.
|
|
307
|
+
- Narrow the direct arbitrary-process light allowlist by executable identity rather than basename. `resource-light-command.mjs` accepts only a small set of standard absolute executables for constant/output, process-table, uptime, and sleep probes; the same basenames reached through PATH remain adaptive. `find -exec`, `awk system()`, arbitrary `osascript`, `open`, caller-controlled Git helpers/configuration, recursive search, whole-file processors, filesystem metadata traversal, configurable lookup helpers, and every arbitrary shell likewise remain under admission. Implementation-owned Git and health probes already use a separate fixed-argv/internal boundary, so control-plane liveness does not depend on trusting caller-selected executable names.
|
|
308
|
+
- Extend the beta.63 Linux state-root retirement repair across the full moved-root verification interval. The original POSIX descriptor pin prevented immediate inode reuse before the first post-rename identity check, but a same-user replacement installed while the verifier traversed the quarantine could still become the pathname handed to recursive deletion. The descriptor now remains authoritative through a second device/inode recheck after verification; a deterministic fixture replaces the quarantine inside the verifier and requires the replacement to remain retained. Portable Node.js still lacks descriptor-relative recursive `openat`/`unlinkat` deletion, so the final identity-check-to-`rm` hostile-same-user race is documented as a residual instead of being claimed eliminated.
|
|
309
|
+
|
|
310
|
+
## 3.0.0-beta.63 - 2026-08-12
|
|
311
|
+
|
|
312
|
+
- Supersede beta.62 after its exact candidate was owner-activated, passed the deployed OAuth canary and live daemon/Worker verification, was accepted, committed, and guarded-pushed, but the exact pushed head then failed mandatory hosted provider gates. Ubuntu `check:full` exposed a Linux inode-reuse ABA in state-root retirement, Windows `check:platform` exposed a test-only 100 ms process-session settlement deadline leaking into real cleanup, and JavaScript/TypeScript CodeQL rejected ten new findings. Beta.62 therefore remains useful live evidence but is not publishable; its source acceptance is removed and beta.63 must repeat the complete candidate/activation/canary/acceptance/provider sequence.
|
|
313
|
+
- Pin the original POSIX state-root directory by an `O_NOFOLLOW|O_DIRECTORY` descriptor across quarantine rename. The pre-rename path still has to match the complete `(dev, ino, ctime)` generation, while the open descriptor keeps that inode referenced so a same-user remove/recreate race cannot recycle the numeric inode before the moved-path `(dev, ino)` recheck. A replacement generation remains quarantined and never reaches destructive state verification; Windows retains its platform path because directory replacement while held open follows different filesystem semantics.
|
|
314
|
+
- Keep the synthetic delivered-but-never-settled process-session revocation deadline local to that negative fixture. The shared manager once used 100 ms for the whole test, so its final cleanup could misclassify a normally terminating Windows `taskkill` process as unsettled; real spawned sessions now use the production five-second settlement budget, while only the artificial never-close record temporarily uses 100 ms and restores the manager contract in `finally`.
|
|
315
|
+
- Resolve the exact-head CodeQL findings without adding blanket suppressions: verification-generation file reads now use the existing descriptor/identity-verified bounded read primitive; resource-accounting calls no longer pass a dead timestamp parameter; host-snapshot single-flight state stores a record containing the Promise rather than treating the Promise itself as lifecycle identity; and the two file-race test fixtures avoid check-then-reuse path patterns. Existing accepted findings remain narrowly scoped and unchanged.
|
|
316
|
+
|
|
317
|
+
## 3.0.0-beta.62 - 2026-08-12
|
|
318
|
+
|
|
319
|
+
- Supersede the activated but unaccepted beta.61 candidate after deployed OAuth-canary cleanup exposed an end-to-end account-administration success-status mismatch. The Worker `/admin/clients` DELETE route removes the client plus its codes and tokens and returns JSON `200`, while beta.61's local `AccountAdminClient` incorrectly required `204` for every DELETE and could therefore report `protocol_error` after client cleanup had already committed. Success status is now endpoint-specific: OAuth-client deletion requires `200` JSON, account deletion requires `204`, account creation requires `201`, and the remaining admin operations require `200`; reverse-status regressions prevent the two DELETE contracts from collapsing together again. Because this is a packaged-source change after beta.61 activation, beta.61 must not be accepted or published; beta.62 requires a fresh frozen gate, exact candidate, owner activation, deployed OAuth canary, and observed live verification.
|
|
320
|
+
- Preserve mutation-settlement ambiguity when account administration receives an HTTP success whose response violates the local protocol contract. Unexpected successful status codes and empty, oversized, malformed, or non-object successful response bodies can arrive after the Worker has already committed a mutation, so those `protocol_error` results are now explicitly non-retryable and carry only the bounded facts `request_delivery=sent` and `effect_settlement=unknown`. Read-only protocol failures remain ordinary protocol errors. Regression coverage exercises both reversed DELETE statuses and malformed successful mutation JSON so callers cannot mistake a response-decoding failure for proof that the remote effect did not happen.
|
|
321
|
+
- Refuse automatic HTTP redirects on credential-bearing release and administration requests. `AccountAdminClient` now uses `redirect=error` for every signed admin request, and the deployed release OAuth canary uses the same fail-closed default for dynamic registration, token exchange, and authenticated MCP calls; only the authorization request opts into `manual` so its expected `303` callback can be validated locally. Focused regressions pin both policies, preventing an unexpected Worker or intermediary redirect from turning a same-origin signed/mutation or synthetic OAuth request into a second network request at a Location target.
|
|
322
|
+
- Removed a load-dependent false-positive from the shared Wrangler completion wrapper after an intentionally concurrent beta.62 fast/full verification run reproduced it. The completion-grace timer could request SIGTERM in the narrow interval after a normal CLI had already begun natural exit but before Node had published its child exit state; the later `close(code=0)` was then mislabeled as “completed but did not exit”. A real zero exit now wins over a raced cleanup request, while only a completed CLI that actually closes from the requested `SIGTERM` is accepted through the bounded-hang path. A deterministic fixture holds a successful command alive just beyond the short test grace while ignoring the raced SIGTERM, then exits zero, so the original misclassification is reproducible without relying on scheduler load; the existing completed-resident fixture still proves real hangs are terminated and diagnosed.
|
|
323
|
+
- Make every fast/full/platform verification result generation-bound instead of relying on operator discipline to keep the checkout frozen. Repeated independent review runs proved that a concurrent source/test/documentation edit can otherwise produce a plausible mixed-generation success or failure. `run-checks.mjs` now hashes the complete verification input surface before and after the plan—including source, tests, scripts, browser/CI/docs, release evidence/candidate state, package/configuration files, and file modes—and discards the run if that identity changes. The guard deliberately supersedes even an individual task failure when inputs drift, because a failure from mixed bytes is not valid causal evidence; stable-generation failures retain their original error. Unit and architecture contracts pin both behaviors. The Wrangler lifecycle regression file was also normalized from accidental owner-only `0600` to ordinary source mode `0644` rather than weakening package hygiene.
|
|
324
|
+
- Split local account administration's HTTP response boundary out of the signing/command client after the architecture gate correctly rejected the accumulated module at 250 lines against its 240-line responsibility ceiling. `account-admin-response.mjs` now owns endpoint-specific success status, bounded response streaming/UTF-8 JSON decoding, remote error sanitization, body cancellation, and mutation-settlement protocol errors under its own 120-line architecture budget; `account-admin.mjs` is back to account/signing/request orchestration. The extracted source is normalized to package-safe `0644` mode and the existing end-to-end account-admin regression continues to exercise the same behavior through the public client. The critical coverage gate now pins the extracted response boundary independently at 100% function coverage and at least 75% branch coverage; the frozen regression currently measures 100% (9/9) functions and 85.7% (36/42) branches, so extraction cannot silently move settlement/status logic outside the gated surface.
|
|
325
|
+
|
|
326
|
+
## 3.0.0-beta.61 - 2026-08-09
|
|
327
|
+
|
|
328
|
+
- Repaired a deployed-edge OAuth token-persistence failure discovered during ChatGPT connector verification. Authorization and token issuance reached the persistence stage but the deployed Durable Object returned an unexpected server error on the security-critical multi-record convenience write even though the equivalent local Wrangler/workerd flow passed. OAuth access/refresh state now commits atomically through an explicit Durable Object transaction with named single-key writes and bounded `oauth`/`refresh`/`commit` failure classes; live verification restored the connector, authenticated MCP calls, and refresh-token rotation. The project does not claim that Cloudflare multi-key `put()` is unsupported; the exact provider-internal difference remains unresolved and is treated as a local-vs-deployed runtime parity gap.
|
|
329
|
+
- Applied the same transaction/per-key persistence discipline to authority-protected multi-record writes even when no revocation record is queued, eliminated writes to the reserved authority-revocation queue key, and regression-budgeted the maximum authority queue. Refresh replay markers still compact retry-only payload after their bounded concurrent-retry window, and consumed-token replay state now persists in 8 deterministic 1024-record shards rather than inside the main `oauth-refresh` value; legacy schema-2/schema-3 state is reconstructed and migrated atomically through the same persistence codec so active-token, replay, retry, admin-revocation, and capacity semantics stay unified.
|
|
330
|
+
- Made the schema-1 authority-revocation queue structurally exact, not merely value-valid. Unknown top-level or per-record fields now fail closed instead of being copied through `readQueue()` and silently persisted by the next protected transaction; this keeps the 1024-record/single-value capacity budget meaningful even for damaged or unexpected Durable Object state.
|
|
331
|
+
- Extended that exact versioned-state rule across OAuth persistence. The main schema-1 OAuth envelope and account/client/code/token/failure records, the schema-3 refresh envelope and token/replay/family records, and the new consumed-token shard envelope now reject unknown fields at their read boundary. Shared field sets live in a dedicated structural contract beside the existing OAuth identifier grammar so optional beta.61 additions remain explicit while damaged state cannot smuggle unbudgeted payload through validation and back into the next transaction.
|
|
332
|
+
- Tightened the shared Worker replay-nonce store at the same read boundary. Persisted daemon-preflight, admin, and DPoP nonce maps must now fit the caller's declared cardinality cap before they are copied or pruned; an oversized same-key value fails closed even if its excess entries are already expired. The unused `boundedNoncePresent` export was removed so the single consume path owns replay-state validation and mutation.
|
|
333
|
+
- Bound persisted replay-nonce expirations to each protocol's reachable time horizon as well as its count cap. Daemon preflight, signed administration, and DPoP each pass a maximum future window of twice their accepted timestamp skew/TTL, matching the farthest expiry a valid proof can produce. Corrupt state can no longer pin a full replay map indefinitely with safe-integer expirations years in the future.
|
|
334
|
+
- Removed a phantom local error code from account administration. Malformed, empty, or oversized successful Worker responses previously constructed `invalid_response`, but that value was not part of the `BridgeError` contract and was silently normalized to `execution_failed`. Those branches now use the existing `protocol_error` code explicitly, with regressions asserting the actual contract rather than only matching human-readable text.
|
|
335
|
+
- Bounded and sanitized non-success account-admin error text at the local client boundary. The same client backs the direct terminal command as well as tool-mediated flows, so it no longer relies on later MCP serialization to constrain a Worker-provided `message`/`error`: control and bidirectional-text characters are removed, whitespace is normalized, and the terminal-facing message is capped at 2,000 characters before `BridgeError` construction.
|
|
336
|
+
- Corrected account-admin 5xx classification and mutation settlement. The Worker intentionally converts uncaught admin failures to HTTP 500, so the local client now reports those responses as `unavailable` rather than `invalid_request`; reads remain retryable, while mutations are non-retryable and explicitly record that the request was sent but effect settlement is unknown.
|
|
337
|
+
- Added account-admin success-status validation instead of accepting arbitrary successful responses, but the beta.61 candidate still incorrectly treated every DELETE as a `204` operation. Its deployed OAuth canary later proved that `/admin/clients` deletion uses JSON `200`; beta.62 supersedes the incomplete beta.61 rule while retaining `201` for account creation and strict `200`/`204` endpoint validation.
|
|
338
|
+
- Removed the unused `remoteBridgeError` deserializer and its self-referential test. No production path imported it; retaining a tested-but-unreachable remote-error reconstruction API after the old stateful remote/session paths were removed created dead contract surface without protecting any executable flow.
|
|
339
|
+
- Tightened incident and release evidence rules after the investigation: exact live identity and privacy-safe stage evidence precede speculative semantic changes; observed facts, inferences, falsified hypotheses, and unknowns stay distinct; disproved patches require independent justification or removal; credentials/state/security controls are not generic diagnostic resets; hosted-runtime behavior requires deployed canaries when local emulation cannot prove parity; and verification runs are valid only against a frozen source snapshot. Release acceptance now requires candidate-bound deployed OAuth canary evidence: a synthetic reviewer/client must complete authorization-code exchange, authenticated MCP, refresh rotation, refreshed MCP, and cleanup without persisting or printing canary credentials/tokens/identifiers.
|
|
340
|
+
- Superseded beta.60 as the source release target after a second scheduler review. Beta.60 was activated from a local candidate at `2026-08-08T23:23:27.866Z` but has no local acceptance record; it remains the live Worker/daemon baseline until a new beta.61 candidate is explicitly activated, observed, and accepted.
|
|
341
|
+
- Refined machine-user resource scheduling with conservative protected backfill: young or structurally impossible large requests still allow fit-aware smaller work, while an aged feasible rank-zero waiter blocked by current coordinator leases can stop new backfill long enough for CPU, I/O, memory, disk, or same-project capacity to drain. Queue diagnostics expose only the protected-waiter count, not command text or paths.
|
|
342
|
+
- Preserved the one bounded beta.60-to-beta.61 machine-user resource-lock transition required for a safe live update. Beta.60 uses `transaction.lock/owner.json` as a directory mutex, so beta.61 keeps that schema-1 directory wire shape instead of publishing the same path as a regular owner-state file. The final-name `mkdir` remains the cross-version atomic exclusion point; `owner.json` is written atomically immediately afterwards, and a directory with no owner record is never reclaimed until a bounded incomplete-owner grace has elapsed. Release and stale recovery revalidate the exact directory inode plus owner token/process generation, quarantine that generation by rename before recursive removal, and restore it if identity verification fails. A transition-only branch can also wait for or reclaim the short-lived regular-file beta.61 lock generation used before this correction. This state bridge does not restore an obsolete runtime protocol and is not a mixed-version steady-state contract.
|
|
343
|
+
- Bound stale resource-lease pruning to the lease generation that was actually inspected. Reclamation now removes a lease only while its `lease_id`, ownership token, single-link regular-file shape, and filesystem identity still match; a path replacement during cleanup fails closed instead of being deleted by a bare pathname unlink.
|
|
344
|
+
- Fixed nested coordinator self-deadlock by treating process-ancestor leases as orchestration envelopes instead of blindly summing every nested lease. Active leases keep their full persisted requests and independent crash ownership, while live accounting builds an ephemeral process-ancestry forest and charges each root as the component-wise maximum of its own envelope and the sum of direct child envelopes. A pending nested request reserves only the additional delta; same-key ancestor contention is ignored only for that ancestry chain, while same-key siblings still serialize. If ancestry sampling fails, accounting falls back to conservative full summation. Process ancestry is not sampled at all while the lease set is empty; once leases exist, the full parent snapshot is cached for one second and concurrent callers coalesce behind the same sample.
|
|
345
|
+
- Kept isolated POSIX process-group reservations durable after the direct caller releases its local lease handle. Explicit release now verifies ownership but leaves a bound lease persisted while the process group is still alive; ordinary pruning removes it only after the group exits. This closes the accounting gap where a detached compiler/test descendant could be reparented to launchd and continue consuming resources after its caller returned.
|
|
346
|
+
- Bound that retained POSIX group reservation to the original process generation rather than the numeric PGID alone. A live group still keeps the lease when its original leader has exited and descendants remain, but if the leader PID has been reused with a different recorded start identity the stale lease is reclaimable even when the reused numeric process group is currently alive. Deterministic regression coverage simulates the generation mismatch against a real detached process group so PID/PGID reuse cannot indefinitely pin phantom capacity.
|
|
347
|
+
- Removed blocking host/process probes from the ordinary live admission path. CPU pressure now comes from Node's cumulative OS CPU counters instead of a whole-process `%cpu` scan: full quick evidence is reused for at most 500 ms, while a machine-global cumulative CPU anchor may cross project scopes for at most two seconds to avoid a needless cold sample. Older anchors force a fresh 50 ms CPU window so a long idle interval cannot smear current pressure into a stale average. CPU/mixed/adaptive work uses the quick host path; fresh `iostat` is reserved for I/O-dominant or unbounded roots, and successful I/O evidence may be reused boundedly only within its original project/filesystem scope. Host probes remain single-flight per anonymous canonical project scope so concurrent requests do not create a probe herd. Child process-start identity remains sampled asynchronously before the coordinator lock.
|
|
348
|
+
- Kept failed Darwin I/O probes out of that five-second evidence cache. `io_sampled` and its reusable timestamp are now published only after `iostat` succeeds and yields a finite numeric sample; timeout/failure/malformed output remains unknown so a later heavy admission retries the full probe instead of treating a failed observation as recent I/O evidence.
|
|
349
|
+
- Made heavy roots yield without reducing bounded interactive throughput. POSIX background resource roots are launched through `nice +5`; heavy roots whose internal fan-out cannot be safely bounded (for example a shell-composed build) use the smaller `nice +2`, while bounded ordinary/interactive roots are unchanged. This remains scheduler preference rather than CPU quota enforcement. Unknown/unbounded CPU fan-out is expanded to the current admission CPU limit, and that policy-expanded reservation is now persisted into the durable lease instead of falling back to the smaller profile hint after admission, so later roots and surviving nested children continue to see the capacity that was actually approved. Cheap bounded metadata probes (`ps`, `wc`, `uptime`, `df`) bypass heavy admission while recursive filesystem walks such as `du` do not.
|
|
350
|
+
- Added disk-headroom pressure without restoring a rigid global build ban. The soft floor is `min(80 GiB, max(8 GiB, 15% of the volume))` and the hard post-reservation floor is `min(50 GiB, max(5 GiB, 10%))`, so small volumes are not permanently classified as pressured while large volumes retain bounded safety headroom. Build-cache partition hashes reuse the canonical project identity, preventing symlink/path aliases from duplicating compiler cache roots.
|
|
351
|
+
- Scoped Yellow admission penalties to the pressured resource instead of taxing every dimension. CPU busy/CPU PSI tightens CPU capacity, disk throughput/I/O PSI/soft disk headroom tightens I/O capacity, and memory/pageout/swap/memory PSI tightens memory capacity. `heavy_root_count` remains advisory density telemetry but no longer recreates a global CPU/I/O/memory penalty without a corresponding bottleneck signal. This prevents disk-only or count-only warnings from stranding otherwise healthy capacity while retaining per-resource backpressure.
|
|
352
|
+
- Canonicalized project-contention identity across implementations and filesystem aliases. The v1 contention-key material now uses the canonical filesystem path (including existing symlink ancestors) before hashing, so `/var` versus `/private/var` and symlinked workspace aliases cannot silently create different Node/Python project mutexes. Windows identity additionally normalizes separators, case, and extended-path prefixes so equivalent NTFS aliases converge before hashing.
|
|
353
|
+
- Corrected project contention scope for shell roots. A provable literal `cd` chain now narrows same-project serialization to the last certain directory even when the inner executable is not a known build family; dynamic/quoted/otherwise ambiguous directory changes fall back conservatively instead of guessing. This prevents sibling repositories under one parent from sharing a false contention key.
|
|
354
|
+
- Extracted shell command-shape analysis and tightened orchestration-script classification so an ordinary argument such as `tests/foo` or `release-notes.md` cannot make a read-only command look heavy. Only the actually invoked shell/Node/Python script operand or package-manager script name can select a bounded heavy profile. The verification runner reserves its actual configured/default internal concurrency before spawning parallel checks. Direct Cargo/Swift/Xcode and make/ninja/cmake/Gradle/Maven/Go builds now make admission and execution agree: absent an explicit worker count the bounded default is a ceiling that is refit on every coordinator admission iteration to the smaller of measured CPU headroom and durable reservation headroom. The same schema-1 waiter is atomically updated before fairness selection without resetting its ID, enqueue time, or aging rank, so a constrained build can shrink while waiting and re-expand when capacity returns; the final lease-selected worker count is enforced through argv/environment (`CARGO_BUILD_JOBS` or `MBM_CHECK_CONCURRENCY` where applicable). Verification-plan memory reservation contracts with fitted fan-out down to its 2048 MiB floor instead of retaining the stale larger-worker budget. Empty `MBM_CHECK_CONCURRENCY` keeps the runner's implicit/default semantics and may be replaced by the fitted value, while non-empty values outside `1..16` are preserved and classified unbounded instead of being silently rewritten or charged as the default. The elasticity marker is process-local only and does not change the schema-1 waiter/lease wire shape. Explicit `-j`/`--parallel`/`--max-workers`/`-T`/`-p` values and valid `CARGO_BUILD_JOBS`/`CMAKE_BUILD_PARALLEL_LEVEL` are never silently reduced. Cargo now accounts its current explicit jobs grammar exactly: negative CLI/environment values resolve relative to logical CPUs, `default` resolves to the logical-CPU default, CLI jobs override `CARGO_BUILD_JOBS`, and arguments after Cargo's `--` separator do not become compiler fan-out; invalid/zero/nonpositive/out-of-contract values remain fail-closed as unbounded, while the no-explicit-setting path retains Machine Bridge's elastic default ceiling. Maven 3.9+ `MAVEN_ARGS` is now part of thread accounting: because the launcher prepends it to the CLI and Maven reads the first `-T`/`--threads` value, an environment thread setting is charged and preserved even when a later user argv specifies another value. Maven core-multiplier forms such as `-T2.5C` are charged using Maven's integer multiplier-times-available-processors calculation. Visible GNU make settings in `GNUMAKEFLAGS`/`MAKEFLAGS` now follow make's implicit leading-dash and compact short-option parsing while preserving jobserver state. Gradle now has a dedicated current-semantics worker parser: `JAVA_OPTS` precedes `GRADLE_OPTS` in the launcher, direct `-Dorg.gradle.workers.max=...`/`--system-prop=...` updates that system-property map, and `--max-workers` is the final build-option override. Valid effective values are charged without injecting a replacement; invalid final properties fail before CLI recovery, and repeated/invalid `--max-workers` values use the lightweight pre-build validation profile. Malformed JVM-option quoting and otherwise valid counts above the modeled maximum remain fail-closed as unbounded. The obsolete mixed build-config concurrency adapter was removed after CMake, Go, Ninja, and Gradle gained dedicated parsers; Make environment accounting is now wired directly. Go concurrency now has a dedicated parser matching the current go command's ordering and failure boundaries: quoted `GOFLAGS` applies first, direct `-p`/`--p` overrides it, repeated numeric values use the final effective setting, `go test` respects package-list versus `-args`/positional-test-argument boundaries, and ordinary `go build` stops at its first package operand. A final nonpositive numeric `-p` uses a lightweight pre-build validation profile because Go rejects it before compiler fan-out, malformed/non-numeric GOFLAGS remains fatal before CLI override, and a syntactically possible `-p` value belonging to a preceding flag fails closed as unbounded instead of entering that light fast path. SwiftPM fan-out now has a dedicated parser matching its scalar `UInt32` Argument Parser contract: repeated `-j`/`--jobs` values use the final setting, equals forms and accepted leading-plus integers are charged exactly, zero remains unbounded because llbuild substitutes hardware concurrency, and valid counts above the modeled maximum remain unbounded unless a later scalar option replaces them. Direct missing/non-UInt32 or unsupported joined-short forms such as `-j8` use lightweight pre-build validation; shell-wrapped Swift is only bounded when the shell contains one provable Swift segment, so mixed orchestration remains fail-closed as unbounded. Xcodebuild now separates real build/test invocations from query, package-resolution, export/import, and platform/component-maintenance modes before build-root mutation, so `-help`/`-usage` and non-build commands no longer receive synthetic `-jobs`/`-derivedDataPath` flags. Those non-build modes now receive workload-specific admission instead of the generic adaptive fallback: settings/metadata queries stay small adaptive work; package resolution is project-serialized mixed work with a 4 GiB disk safety reservation; archive/localization/xcframework import-export is project-serialized I/O with an 8 GiB reservation; platform/component install/download/prepare operations are unbounded high-I/O with an 8 GiB minimum safety reservation; component deletion is I/O-heavy with no invented future disk consumption and no disk-reclaim privilege. These reservations are safety floors, not claimed upper bounds on native operation size. Its dedicated build parser reflects the current native CLI observed on this host: only separated `-jobs NUMBER` enters the native jobs-option path and accepts leading `+`; lookalike `-jobs=...` forms do not receive the same native validation and are never treated as hard concurrency bounds. Canonical zero/negative separated counts fail before build, and a second real `-jobs` option is rejected outright. Canonical positive separated bounds are charged exactly; equals forms, noncanonical values that Xcode may accept by numeric-prefix conversion, and oversized values stay fail-closed as unbounded. `test` and `test-without-building` remain overall unbounded because Xcode exposes independent destination and parallel-testing runner fan-out, while the known/default build-phase `-jobs` ceiling is still retained separately. The obsolete generic compiler-job parser chain was removed once Xcode gained this dedicated model. Ninja direct fan-out now has its own getopt-aligned parser: repeated `-j` options use the final value, `-j0` remains effectively infinite/unbounded, and negative/non-numeric values or Ninja's unsupported `--jobs` spelling use the lightweight pre-build validation profile instead of waiting for heavy capacity before Ninja exits. Any valid positive direct `-jN` remains the hard local worker bound and disables inherited jobserver participation. Ninja 1.13+ GNU jobserver participation is no longer accidentally disabled by Machine Bridge's implicit `-j` cap: supported FIFO/semaphore jobserver authentication in `MAKEFLAGS` is preserved without injecting a local `-j`. Jobserver-aware Ninja is conservatively classified cooperative/unbounded even when MAKEFLAGS exposes `-jN`, because current Ninja can fail to initialize the inherited jobserver and continue with native local parallelism. The jobserver parser mirrors current Ninja ordering: MAKEFLAGS dry-run flag letters disable jobserver use, the last recognized auth/fds descriptor wins, negative descriptors disable it, malformed `--jobserver-fds` fails closed, and unsupported POSIX pipe descriptors do not suppress the local bound. This preservation marker is process-local and never changes the schema-1 wire shape. pytest-xdist now distinguishes fixed and truly dynamic worker counts: numeric `-n` is charged directly, `-n 0` is single-process, and `auto`/`logical` is only bounded when `--maxprocesses=N` supplies a hard ceiling; auto-worker environment hints remain non-authoritative because project hooks can override them. CMake build concurrency now uses a dedicated current-semantics parser instead of generic first-match handling: repeated `-j`/`--parallel` options use the final CMake-level value, positive CLI concurrency overrides `CMAKE_BUILD_PARALLEL_LEVEL`, and invalid/zero/too-large pure CLI or environment values use the lightweight pre-build validation profile rather than waiting for heavy capacity before CMake rejects them. Value-less/defined-empty parallelism remains unbounded because CMake delegates it to the native tool. Uninspected `--preset` builds and native arguments after `--` are also fail-closed as unbounded and are left untouched because presets can provide `jobs`/`nativeToolOptions` and generator-specific native options can independently raise fan-out. Explicit fan-out that cannot be bounded safely is classified unbounded instead of being charged as the default. Shell-wrapped implicit Swift and generic compositions that cannot be safely rewritten remain conservatively unbounded.
|
|
355
|
+
- Fixed admission-wait liveness under real pressure. Coordinator backoff/lock waits now use a referenced timer so an otherwise-idle Node process cannot exit with an unsettled top-level await, and abort listeners are removed on both timeout and cancellation instead of accumulating during long waits. Same-daemon cancellation/timeout, stale-lease pruning, and stale/expired-waiter pruning now wake peer waiters immediately so capacity or fairness changes do not wait for the next jittered poll. Stale waiter pruning revalidates ownership and filesystem identity and fails closed if the record changes before deletion instead of silently dropping a changed queue entry.
|
|
356
|
+
- Made resource-directory crash recovery generation-aware as well. Internal exclusive-file staging names intentionally remain PID-based, but recovery no longer treats a live numeric PID as proof that an uncommitted staging artifact still belongs to that process. It compares the current process start identity with the staging file's write-time ownership lower bound through the existing process-instance inspector, so a PID reused long after a crashed publisher cannot permanently block lease/waiter directory recovery; a genuine current publisher is still protected.
|
|
357
|
+
- Closed resource-lease cleanup races around failure and short-lived children. A failed durable `ResourceLease.release()` no longer marks its handle closed before the caller can retry; a validated/token-matching lease whose identity changes before destructive removal now fails closed instead of returning an ambiguous false success; fire-and-forget cleanup paths consume cleanup rejection explicitly instead of creating unhandled rejected promises; and persistent process sessions do not release a provisional lease until process binding has settled, matching the one-shot and managed-job ordering for children that exit almost immediately. Process binding is now a one-way ownership transition over the complete owner tuple: an exact PID/process-group retry is idempotent, while changing the PID, isolation flag, or POSIX process-group identity is rejected instead of replacing durable accounting ownership. Persisted isolated process-group IDs are required to equal their leader PID.
|
|
358
|
+
- Made managed-job cleanup wait behind process-tree termination settlement. A timed-out, cancelled, or resource-bind-failed step no longer resolves merely because its direct leader closed while an isolated descendant is still awaiting the escalation phase; `finally_steps` begin only after that termination barrier, preventing cleanup from racing a still-live forward-effect process tree. Recovery never replays ordinary business steps; it runs only recovery/finally work, and any resource/state reconstruction `mainError` now makes the terminal status `recovery_failed` rather than the contradictory `recovered` plus `error_class`. Staged cancellation, runner-launch failure, recovery exhaustion, and runner completion now converge on the same result-first terminal persistence contract with explicit result/artifact evidence. `recovery.lock` and `transition.lock` are no longer treated as ordinary terminal artifacts: only their owner/reclaimer lock primitive may remove them, preventing a terminal scrub from publishing an unlocked critical section before the holder actually exits.
|
|
359
|
+
- Closed two managed-job lifecycle gaps found while investigating interrupted work. An exact 50-record retained set no longer deadlocks all new durable submissions: a create transaction reserves one slot by evicting only the oldest safely removable terminal record, returns a structured retryable `limit_exceeded` error when all slots are active/staged/unreadable, and serializes prune/recheck/publication across processes through an owner-identity-checked root capacity lock so two concurrent creators cannot exceed the hard cap. The previously unreachable internal staged-plan `approve()` path and its misleading `pending-local-operator` continuation were removed; staged jobs are now explicitly review-only and can only be cancelled/inspected, while execution always requires a separate direct submission. Retention policy moved to a dedicated critical-coverage module with explicit capacity-boundary, lock-inventory, and no-promotion regressions.
|
|
360
|
+
- Hardened managed-job retention as part of the independent lifecycle review. Staged expiry now participates in the per-job transition lock, re-reads the winning state before mutation, and commits through the shared result-first terminal persistence boundary; `read_job` returns explicit `result_persisted=false` status evidence without re-reading an unpersisted result. Seven-day terminal retention is measured from terminal `finished_at` rather than pre-transition directory age, so a long-abandoned staged draft is not deleted in the same pass that first expires it. During the narrow result-first/status-second runner settlement window, `read_job` now derives an in-memory terminal outer status from a valid durable terminal result instead of returning a mixed active-status/terminal-result generation; runner-owned status persistence remains untouched. Staged cancellation and expiry no longer treat `recovery.lock` as a terminal artifact; transition/recovery locks remain removable only by their owner/reclaimer primitives.
|
|
361
|
+
- Made local authority revocation acknowledgement fail closed across durable jobs. A matching managed job that cannot be safely inspected or cancelled now makes the revocation application incomplete instead of being reduced to a warning; the daemon withholds `authority_revoke_ack` and interrupts the current relay generation so the Worker's persisted revocation queue is replayed promptly on reconnect. Successful partial cancellation remains idempotent on retry, and revocation uses a module-internal cancellation path so a job accepted under an earlier writable policy remains revocable after the public `cancel_job` tool is disabled by a narrower daemon policy. The same review removed an unused shared revocation-message serializer and a test-only production service-convergence wrapper, and removed process IDs from routine default-level startup/takeover logs and the managed-job identifier from default asynchronous runner-failure logs while keeping exact identity available in explicit diagnostic/job state. Managed-job observation windows in stdio/local-self integration now allow up to five minutes for real machine-level resource admission while leaving the job step execution timeouts unchanged, preventing a busy host from being misclassified as a product failure. The `start_job` schema/documentation now also states the real idempotency boundary: `idempotency_key` deduplicates uncertain retries only while the original job record is retained, and capacity/retention eviction ends that evidence window; the tool remains explicitly non-idempotent rather than implying permanent exactly-once execution.
|
|
362
|
+
- Tightened the independent managed-job integrity review around destructive cleanup and operator diagnosis. Terminal artifact cleanup now accepts persisted status/result only when job ID, terminal state, and `finished_at` identify one commit generation; the degraded `result_persisted=false` form must carry a valid settlement timestamp and bounded terminal-record error class. Corrupt terminal evidence is projected as unreadable state for uninstall inventory instead of being treated as harmless completed metadata, and integrity errors retain their explicit diagnostic class rather than collapsing into generic resource unavailability. Seven-day/capacity retirement now verifies the exact observed filesystem generation, atomically moves that generation to an identity-encoded retired name, rechecks the moved inode before recursive removal, and reclaims a verified retired generation on the next managed-job maintenance pass if the process crashes between quarantine and deletion. Retired-state inventory is itself fail closed: the internal `retired_job_*` namespace is deliberately outside the public `job_...` ID grammar, a valid crash residue is reported only as privacy-bounded cleanup-pending internal state until reclaimed, and a same-name replacement, wrong-type retired entry, encoded-generation mismatch, or unreadable retired directory becomes an `unreadable` destructive-state blocker without exposing the encoded device/inode as a job ID. Recognized retired state continues to count against the 50-item hard capacity until safely removed. Full uninstall performs this retired cleanup only after acquiring its maintenance/service locks and still refuses to remove the state root when any abnormal residue remains; its error names only coarse `retired-managed-job:<status>` state and directs persistent unreadable residue to owner-only state inspection rather than `read_job`. Sustained `local_authority_revocation_retry` relay warnings now direct operators to local authority, process-session, and managed-job state rather than incorrectly suggesting internet/Worker troubleshooting. The remaining dead `approval` and `job approve` parser tables were removed after the executable approval path had already been deleted; unknown job actions now reach the single command handler instead of being misreported by a stale `approve` positional rule, and persisted `status.approval` remains only as an on-disk launch/review compatibility field.
|
|
363
|
+
- Extended the independent lifecycle review from managed-job state into process ownership and whole-state deletion. One-shot commands, fixed internal executables, and detached managed-job steps no longer treat a ChildProcess `error` event as process death; tracker/session/resource ownership is released only after close/exit settlement. A process-session start that fails after spawn retains hidden ownership and its resource lease until real close, forced `kill_process` fails rather than claiming termination when the direct tree-kill request cannot be delivered, and authority revocation retains/retries an unkillable matching session while still attempting every other local execution category before withholding acknowledgement. Idempotent `start_job` replay now reconciles a durable terminal result before any queued-runner relaunch and treats only a genuinely missing status as absence; runner fatal settlement also requires a confirmed runner claim plus valid same-job active state before it may write terminal evidence or scrub artifacts. Recovery bootstrap is stricter still: a recovery runner confirms its runner claim, completes the token-bound recovery-lock handoff, and only then gains authority to persist terminal evidence; bootstrap failure therefore leaves `interrupted` status and the plan available for retry, with a 30-second monotonic handoff budget. Full state-root uninstall is now generation-bound through a reserved rename/revalidate/delete transaction with crash-residue recovery; malformed, wrong-type, mismatched, unreadable, replaced, or symlink-traversed state evidence blocks destructive cleanup. Managed-job retirement follows the same no-pathname-rollback rule on verification failure; malformed `retired_job_*` residue and wrong-type public `job_...` state are reserved blockers that count toward capacity, while deterministic target inspection occurs before any terminal-history eviction. Destructive profile inventory likewise rejects unknown or wrong-type children of the reserved `profiles/` namespace instead of filtering them out. The beta.60 resource-transaction compatibility lock uses a narrower rule: incomplete owner-less directories are reclaimed with generation-checked empty `rmdir`, so a late owner publication atomically defeats reclamation, while the remaining token-bearing quarantine restore refuses to overwrite a replacement generation. Resource-coordinator lock waiting is now operation-bounded: acquisition is capped by the caller's remaining admission budget, while post-spawn lease bind/release may wait up to 30 seconds. A deterministic 5.5-second transaction-lock hold proves dead-runner recovery no longer punches through the old five-second internal lock deadline as permanent `recovery_failed`, including under V8 coverage instrumentation. Managed-job active lifecycle classification now has one shared source used by retention, manager reconciliation, detached-runner fatal settlement, and the production full-access diagnostic; the latter no longer omits `recovered`, `cancelled_before_start`, or `expired_before_start` and therefore cannot turn an already-terminal job into a five-minute false wait. A dedicated fast/critical-coverage state-root retirement regression measures 100% function and 81.1% branch coverage against a 90/70 gate.
|
|
364
|
+
- Hardened the private npm bootstrap against transient **and slow-but-progressing** registry transfers after the install smoke gate exposed the difference. Exact immutable npm/undici/brace-expansion GETs still make at most three attempts with 750/1500 ms bounded backoff for explicit transient network codes, HTTP 429, or HTTP 5xx, but the old per-attempt 60-second wall deadline is now a referenced **no-progress** timeout refreshed only by response/body progress plus an independent five-minute absolute attempt ceiling. A real registry path measured at roughly 20 KiB/s therefore no longer restarts a multi-megabyte immutable tarball every minute; the repaired `install:test` completed the isolated hardened npm, pack, global install, and default-start boundary in about 7 minutes. Redirects, proxy-configuration/certificate/policy failures, size violations, and other non-transient errors remain single-attempt fail-closed results. Fault injection now covers timeout→503→byte-identical success, continuously progressing slow bodies, idle and absolute timeouts, exact-HTTPS enforcement, default proxy-aware agent construction, invalid proxy/NO_PROXY input, setup/response failure, declared and streaming byte ceilings, retry exhaustion, and no retry for redirects/certificate rejection. Critical coverage records `hardened-npm-download.mjs` at 94.7% function / 78.1% branch and its timeout helper at 100% / 92.3%, while the download module remains within its existing 110-line architecture ceiling.
|
|
365
|
+
- Made platform service status/mutation fail closed instead of collapsing unknown state into inactivity. launchd exit 113 is the explicit missing-service evidence; every other nonzero `launchctl print` is `status_unavailable`, failed-query stdout is ignored, and stop succeeds only after the service is both inactive and unloaded from the launchd domain, so a failed `bootout` plus an independently exited process cannot authorize plist deletion. systemd now projects only active/inactive/failed/confirmed-missing evidence as boolean activity; transition states, installed-but-unknown state, and unrecognized command output remain `active:null`. launchd/systemd direct start/restart refuse unavailable provider status or a missing definition, matching the owned-service runtime guard. `service status` preserves provider uncertainty as `effective_active:null` unless a workspace daemon is positively alive. Deterministic platform/status/CLI tests cover missing, arbitrary query failure, normal unload, still-loaded/inactive launchd state, post-bootout status loss, systemd transition/unknown state, and tri-state status projection; architecture checks lock these boundaries.
|
|
366
|
+
- Stopped advertising an already-started foreground process timeout as safe to retry while tree termination is still settling. One-shot execution keeps its low-latency timeout contract, but the public `timeout` error is now `retryable: false` with bounded `side_effects_started`, `termination_requested`, and `effect_settlement: "pending"` metadata; process tracking and the durable resource lease continue until the child/tree lifecycle closes.
|
|
367
|
+
- Applied the same ambiguous-side-effect contract at the Worker settlement boundary. Once a transient request-scoped call has reached the daemon, timeout/cancellation evidence is non-retryable instead of inviting an automatic duplicate while the original effect may still be settling. A successful `cancel_call` send reports `termination_requested: true` with pending settlement; a detached/closed transport reports unknown settlement without inventing a termination request. If an already-dispatched call loses its daemon connection and the bounded same-instance reconnect grace expires, the resulting `unavailable` error is likewise non-retryable; pre-dispatch availability failures remain separately retryable.
|
|
368
|
+
- Bound relay `cancel_call` to the authenticated ready connection generation and the canonical call-ID grammar. Reconnect promotion already sends `resume_calls`, queued revocations, and `ready_ack` in-order before a rebound socket can receive later cancellation traffic, so accepting cancellation before readiness served no continuity purpose and allowed a pre-ready control frame to mutate local call state. Malformed or pre-ready cancellation is now a protocol violation; a ready-generation cancellation still suppresses/terminates the matching request exactly as before.
|
|
369
|
+
- Kept the stateless remote initialization compatibility surface from weakening current intermediary-routing invariants. Older HTTP clients are not required to send the beta.61 `Mcp-Method`, `Mcp-Name`, or schema-declared `Mcp-Param-*` mirrors, but if any of those current headers are present they must agree with the JSON-RPC body before compatibility dispatch. This preserves old-host interoperability without allowing a request body to execute one tool or method while an intermediary-visible current header claims another.
|
|
370
|
+
- Closed the remaining mirrored-header namespace ambiguity for both native and compatibility requests. `Mcp-Name` is now rejected on methods where no name/URI mirror is defined, and every supplied `Mcp-Param-*` header must belong to the selected tool's declared `x-mcp-header` bindings; undeclared headers, headers belonging to another tool, and parameter mirrors on non-tool methods fail with the same `-32020` routing-contract error instead of being silently ignored. For current named methods, malformed or missing body name/URI fields are validated first and remain ordinary `-32602` parameter errors rather than being misclassified as a missing mirror-header contract error.
|
|
371
|
+
- Made long integration/coverage runtimes cooperate with real machine-user pressure instead of treating a transient busy host as a product failure. Production foreground process admission still uses the 2-second retryable window; `local-self-test` waits up to five minutes at both one-shot and persistent-process boundaries, its command timeouts still begin only after admission/spawn, and the resource-executing `agent-context-test` runtime uses the same test-only wait. `full-access-test` now also gives its internal real-machine `LocalRuntime` a five-minute cooperative admission budget and its detached managed-job lifecycle the same five-minute observation window; this prevents the full gate's own parallel CPU/I/O load from making a healthy diagnostic fail after the production two-second admission window without changing ordinary foreground runtime behavior.
|
|
372
|
+
- Promoted the resource scheduler into the critical-module coverage contract. The full coverage suite now executes the direct admission/build-root fixtures and enforces explicit thresholds for admission policy, fairness/waiters, command/shell classification, host pressure, wait liveness, staging recovery, build-root/process admission, and the persisted request contract; release architecture tests prevent those fixtures/thresholds from being silently removed. The V8 collector now merges repeated function executions by exact range with nearest-enclosing inheritance when a child range disappears, instead of treating a missing child record as uncovered. A source/test/mode/symlink generation digest is checked before and after collection so a long coverage run cannot combine multiple source generations into false evidence.
|
|
373
|
+
- Added Linux `MemAvailable` and Pressure Stall Information sampling for CPU, memory, and I/O. PSI is optional live-pressure evidence, not quota enforcement: 10% recent stalls tighten admission to Yellow and sustained memory `full` pressure at 60% is Red; missing PSI remains unknown and is not reported as sampled I/O. Windows now also contributes physical-memory availability plus cumulative CPU idle/total evidence from Node's OS APIs; once two samples exist, the coordinator derives busy cores from the delta instead of treating Windows CPU and memory pressure as permanently unknown. The cumulative counters remain private coordinator evidence and are stripped from public diagnostics; Windows I/O throughput remains unknown rather than relying on localized performance-counter text.
|
|
374
|
+
- Kept historical resource learning out of this release. A source review of local CognactApp showed the right prerequisite: settlement-time `wait4`/`rusage` CPU, peak RSS, I/O, wall-time, descendant, and process-group evidence. Node does not currently expose an equivalent trustworthy per-child boundary, so beta.61 does not infer resource cost from wall time or `ps` snapshots.
|
|
375
|
+
- Kept disk-pressure protection self-recoverable without creating a general pressure bypass. Only direct standard absolute deletion executables are internally classified into a fixed small `disk-reclaim` envelope; PATH-resolved or shell-composed deletion cannot claim it. That envelope may proceed under Yellow limits when free-disk headroom is the sole Red reason, while memory, thermal, PSI, CPU/load, or any other independent Red evidence still blocks it. This lets an operator remove already-identified regenerable data after crossing the disk hard floor without teaching arbitrary heavy work to impersonate cleanup.
|
|
376
|
+
- Made MCP `2026-07-28` the only native state model and removed the old stateful `2025-11-25` initialize/session/recovery adapter, signed-session store, `Last-Event-ID` replay path, durable MCP stream/pending-call persistence, prepare/subscribe delivery descriptors, era-specific controllers, and their production retry/cancellation machinery. HTTP and stdio share the current request-scoped tool core; `server/discover`, per-request metadata, current tool methods, direct tool-response streaming/cancellation, and same-daemon transient relay rebinding remain the only native delivery semantics. Final remote HTTP interoperability additionally accepts bounded stateless initialization-era `2025-06-18` and `2025-11-25` requests for `initialize`, `notifications/initialized`, `ping`, `tools/list`, and `tools/call`; those tool calls route through the current controller, never create `Mcp-Session-Id` or replay state, and do not restore the removed protocol session architecture. stdio remains current-only. Because this server advertises no change notifications, native `subscriptions/listen` remains finite and stateless: it validates the filter, acknowledges an empty honored subset, returns graceful completion, and closes without constructing a subscription registry or replay stream.
|
|
377
|
+
- Corrected the current `subscriptions/listen` zero-capability path after a `2026-07-28` conformance reread. The server no longer reports a fictitious subscription-capacity failure merely because it advertises no change notifications. HTTP and stdio now validate bounded filters, acknowledge the empty supported notification subset, return a correlated `resultType: "complete"` result carrying the subscription ID, and terminate immediately. This remains stateless: no subscription registry, replay store, resumable stream, or compatibility-era state was restored.
|
|
378
|
+
- Removed the remaining browser-visible and authorization scaffolding that implied the deleted MCP delivery era. CORS no longer advertises or accepts `Mcp-Session-Id` or `Last-Event-ID`; the DPoP internal-retry binding used only by legacy prepare retries is gone; Worker alarms, pending capacity, observability, and result ownership now model transient request-scoped calls only. A new deterministic response-proxy regression drives both response-body cancellation and `Request.signal` abort, proves caller-supplied internal stream capabilities are replaced, binds one credential-free cancel control to the random direct-call capability, and requires the public stream to close after queued data drains. Local Wrangler raw-TCP disconnect propagation is not treated as authoritative cancellation evidence; deployed-edge candidate verification remains the real transport check.
|
|
379
|
+
- Narrowed retained upgrade code to migration-only state readers backed by real source states instead of broad runtime compatibility. At this source cutoff the public npm channels are `latest=2.0.0` and `beta=3.0.0-beta.38`, while the owner machine has the explicitly recorded live beta.60 candidate. Browser pairing and OAuth migrations remain because those published states differ from the current schema; the beta.60 resource-lock bridge remains only for the live handoff. Successful migration writes the current state shape and never makes the producing protocol/runtime executable again.
|
|
380
|
+
- Aligned the final MCP `2026-07-28` HTTP mismatch path with the released wire contract. A present `MCP-Protocol-Version` that does not match a missing or different body `_meta.protocolVersion` returns HTTP 400 / JSON-RPC `-32020 HeaderMismatch` before body-metadata structural validation, including at the real Worker entrypoint. Unknown/future versions stay on current validation and are rejected as unsupported rather than being interpreted as another protocol era. Authenticated POSTs require a parsed `application/json` media type before JSON materialization and return HTTP 415 for missing/non-JSON values even when the body is not JSON; exact base-type parsing accepts case variants and parameters while rejecting values such as `application/jsonx` or `text/plain; a=application/json`. The rejection path boundedly drains/cancels the network body before responding so workerd cannot resume reading an abandoned stream after the 415 has already been sent.
|
|
381
|
+
- Tightened account least-privilege discovery independently of dynamic daemon availability. The shared account-access contract now marks `diagnose_runtime`, `list_local_resources`, `stage_job`, and `start_job` owner-only for authenticated remote accounts; local policy profiles keep their existing machine-owner behavior. Local and Worker tool catalogs remove those tools from non-owner remote roles while the operation authorizer enforces the same owner-only invariant before operation-risk classification as defense in depth. `server_info`, `project_overview`, session bootstrap, and task routing now consume one effective tool set equal to daemon/effective policy intersected with the account contract, rather than reconstructing authority from policy alone; the routing combiner also intersects project/skill/keyword seed recommendations with that same set. Durable-job creation routes are omitted when an account has only list/read/cancel controls, while inspection/cancellation of that account's own existing jobs remains principal-bound and routable. Capability responses label repository/skill/registered-command metadata as project-or-user-provided planning context with `authority_expansion: false`; actual execution authority remains the policy, account, and operation gates even when project metadata recommends an action. `start_job` also exposes its already-implemented principal-bound `idempotency_key` in the public schema so uncertain remote submission retries can return the same durable job instead of forcing clients to risk duplicate execution. Routing/automation diagnostics now call that account-attenuated set `effective authority` rather than `effective policy`, and application-discovery denial distinguishes a pure policy denial from an account/daemon authority denial so diagnostics cannot overstate the caller's permissions.
|
|
382
|
+
- Closed a transient process-session shutdown leak found while making the resource-binding regression load-independent. The test now waits for the short-lived child to actually exit instead of assuming a 25 ms post-bind close latency, while still proving that the provisional lease is never released before binding settles and is released exactly once. Separately, `ProcessSessionManager.clear()` now terminates every still-live session process tree before dropping the registry, so daemon stop, supersession, or fatal relay teardown cannot leave detached interactive sessions running as ownerless processes; their existing close handlers still perform the binding-ordered durable lease release.
|
|
383
|
+
- Closed the corresponding post-spawn cancellation hole in `start_process`. If cancellation becomes visible only after the child has spawned and its resource lease has bound, the session is removed before any handle can escape and the child tree is force-terminated; the ordinary close path still releases the durable lease exactly once. A cancelled start can therefore no longer return an error while leaving an unaddressable interactive process running.
|
|
384
|
+
- Closed diagnostic and mixed-version privacy side channels between remote account principals. Non-owner `server_info` no longer exposes global task/tool/call/process/audit activity, stable device-root key identity, protected local-resource inventory, Worker pending/socket/observability activity, or exact daemon-only tool names; principal-scoped managed-job and process-session aggregates remain available, while hidden global state is represented explicitly rather than forged as zero. The Worker now also attenuates `project_overview` returned by an older daemon before it reaches a non-owner account: absolute workspace/Git/top-level paths, daemon-only tool names, and daemon-global capability-routing history are removed while daemon tool counts and hidden markers remain. Account/relay activity projection fails closed unless account ownership is explicitly `true`. Owner diagnostics retain the complete authorized view.
|
|
385
|
+
- Strengthened the privacy of local audit and edge observability without changing authorization semantics. Risky-operation target correlation is HMAC-keyed with a per-daemon runtime key before persistence, and account/client/family identifiers are likewise HMAC-pseudonymized before the existing per-file salted audit references are derived; the salt stored beside the audit chain is therefore no longer sufficient to recompute those references from guessed paths, short commands, or account identifiers. Cross-restart target/principal correlation is intentionally not promised. The throttled Worker edge logger now reuses the same value-level portable redactor as ordinary Worker observability, so credentials, email addresses, user-home paths, and private-key material embedded inside otherwise innocuous string fields cannot bypass key-name redaction.
|
|
386
|
+
- Preserved privacy-bounded deny-path audit evidence at the same execution boundary. Once a relay operation has been effect-classified, `OperationAuthorizer` publishes only `allowed: false`, the coarse risk category/scopes, and the runtime-keyed HMAC target fingerprint into the request context before role-ceiling or protected-root checks can reject it. The existing outer audit middleware therefore records `authorization_denied` with the correct risk class and opaque target correlation instead of degrading a denied sensitive/external operation to `ordinary operation`; raw paths, argv, resource names, and raw target hashes remain absent from persistent audit state. Owner-only tools that are rejected before effect classification receive only a static `owner-only tool` category and no target fingerprint.
|
|
387
|
+
- Closed a rolling-upgrade TOCTOU in stale resource-transaction recovery. If beta.61 observes a beta.60-compatible `transaction.lock/` directory without `owner.json` after the orphan grace, but the older holder completes `owner.json` before quarantine, recovery now revalidates that the owner record is still absent after moving the exact directory generation; a newly completed owner restores the directory and forces a wait instead of being deleted as an orphan.
|
|
388
|
+
- Normalized newly added packaged source modules to ordinary `0644` file mode. The full `package:test` already rejects any npm tarball entry outside the expected `0644`/`0755` set; the correction prevents source modules created with owner-only local write defaults from becoming unreadable when a package is installed by one account and executed by another low-privilege service account.
|
|
389
|
+
- Fixed `candidate-runtime-store-test` teardown so its top-level candidate and external symlink-target fixtures are removed in `finally` on both success and assertion failure. Repeated green runs had been leaving `mbm-candidate-runtime-*` and `mbm-candidate-outside-*` directories under the macOS temporary root; the nested symlink fixtures already had their own cleanup. Interrupted/force-killed tests can still leave ordinary OS-temporary evidence, but a successful run no longer accumulates it.
|
|
390
|
+
- Kept managed-job effect classification aligned with the actual resource-injection contract. Protected local resources referenced through `stdin_resource`, `env_resources`, or `{{resource:name}}` argv tokens now all add the same `sensitive-read` effect scope and bounded reference-count projection, so audit/authorization metadata cannot describe an argv-injected secret as an ordinary persistent job.
|
|
391
|
+
- Hardened the co-hosted OAuth authorization server for the final 2026 MCP authorization profile. Authorization-server metadata now advertises RFC 9207 issuer responses, successful authorization redirects carry the exact `iss` issuer, Protected Resource Metadata no longer advertises `offline_access` as a resource scope, and successful RFC 7591 Dynamic Client Registration returns `201 Created` instead of `200 OK` while retaining refresh-token support in authorization-server metadata. MCP 401 challenges now include only the minimum Machine Bridge resource scope alongside `resource_metadata` for both Bearer and DPoP paths. Persisted authorization codes, refresh tokens, and access tokens are rechecked against the canonical server scope when consumed; damaged scope state can no longer mint, rotate, or authorize credentials merely because the resource/audience still matches.
|
|
392
|
+
- Hardened the retained DCR fallback against first-use trust confusion and capacity drift. The authorization page now labels an unapproved dynamically registered client as unverified and its display name as self-asserted, distinguishes a previously authorized account-bound client, and adds an explicit warning for loopback HTTP callbacks while continuing to show the exact validated redirect URI. Registration and owner client-admin views now share one client-capacity/idle-TTL contract, so `/admin/clients.maximum` reports the actual 50-client DCR ceiling instead of an obsolete 128-client value; unused and long-idle client pruning continues to use the same source constants.
|
|
393
|
+
- Implemented RFC 6749 refresh-scope narrowing without shrinking the refresh grant itself. A refresh request may ask for an originally granted subset for the new access token, while the rotated refresh token retains the full source scope. The consumed-token retry marker records the access scope of the first replacement so bounded concurrent retries can reproduce the same deterministic token pair only under the same scope; a changed-scope retry is rejected rather than reinterpreting an already issued access token with broader authority.
|
|
394
|
+
- Added the RFC 6749 cache-control compatibility header required on credential-bearing token responses: successful authorization-code and refresh exchanges now send both `Cache-Control: no-store` and `Pragma: no-cache` without changing generic MCP JSON response headers.
|
|
395
|
+
- Fixed a source-verification liveness gap around Worker type generation. On the current Node 26.7.0 owner environment, both retained Wrangler 4.115.0 and current 4.120.0 can write the requested declarations, print the command's final completion notice, and then remain resident instead of returning control to `typecheck`; the A/B result therefore does not justify blaming the 4.120.0 upgrade. `worker:types` now deletes any stale target before launch, forwards Wrangler output, enforces a hard generation timeout, and grants a short post-completion exit grace only after both the final command-completion notice and a newly written target exist. A completed CLI that still does not exit is terminated gracefully; failure to terminate gracefully remains an error rather than being converted to success. A deterministic regression covers normal exit, completed-but-resident cleanup, nonzero failure, and a pre-completion stall, and the real `worker:types -> worker tsc -> local tsc` chain returns normally again.
|
|
396
|
+
- Extended that bounded Wrangler lifecycle to the release `worker:dry-run` gate after final release-readiness review reproduced the same defect there: Wrangler 4.120.0 printed `--dry-run: exiting now.` and the complete upload/binding summary, yet the real CLI process remained resident for more than ninety seconds. `worker:types` and `worker:dry-run` now share one completion/timeout/termination state machine; a hanging command is accepted only after its command-specific completion marker (and, for generated types, the new target file) has been observed, then a bounded natural-exit grace and graceful termination succeed. Clean exit, completed-but-resident, nonzero failure, and pre-completion stall fixtures cover both adapters, and the real Worker dry run now returns zero with no residual Wrangler process instead of blocking release preparation indefinitely. The upstream Node/Wrangler lifecycle cause remains unresolved.
|
|
397
|
+
- Closed a crash-recovery hole in the rolling-compatible resource transaction mutex after the full coverage sequence repeatedly reproduced `MBM_RESOURCE_TRANSACTION_BUSY`. If a process died after `mkdir(transaction.lock)` but before the atomic `owner.json` rename, `replaceFileAtomicallySync` could leave `.owner.json.<pid>.<nonce>.tmp` inside the ownerless directory. The existing incomplete-owner path intentionally used empty-directory `rmdir` so a late beta.60 owner publication could atomically defeat reclamation; the crash staging made that directory permanently non-empty and therefore permanently busy. `resource-staging-recovery.mjs` now recognizes only that exact owner-staging shape, waits for a still-current publisher, and removes only a dead-publisher single-link generation after identity revalidation; unknown, multiple, or hard-linked ownerless contents remain fail-closed, and canonical `rmdir` still preserves the late-owner race guarantee. Deterministic tests cover dead staging recovery, live-publisher preservation, and unknown-content refusal. The investigation also fixed the managed-job recovery fixture's separate unhandled-rejection escape hatch so setup-lock acquisition failure now wakes the readiness waiter and surfaces through the test boundary. Full critical coverage passes after the production repair.
|
|
398
|
+
- Fixed the current MCP response proxy's upstream-failure semantics. An exception from the internal SSE reader previously entered the generic cancellation helper, which closed the public `ReadableStream` before `target.error()` ran; clients could therefore observe a transport failure as a clean EOF. Upstream pump failure now retains the public stream long enough to surface the original stream error while still aborting/cancelling the internal call and issuing the credential-free cancellation control. The regression requires the frame before the failure to arrive and the following public read to reject, while normal upstream completion and client/request cancellation continue to close cleanly.
|
|
399
|
+
- Closed a managed-job launch ownership race around `runner.pid`. The launcher previously spawned the detached runner before publishing its provisional claim; if claim publication wrote the file but failed during its final permission check, the parent could classify launch as failed while a kill-delivery failure still left the child able to confirm that claim and execute. Runner claims are now two-phase (`committed:false` then an owner-only atomic `committed:true` replacement), and the child refuses to upgrade or execute an uncommitted claim. The managed-job integration regression covers idempotent committed publication plus an uncommitted valid pid/token claim that must time out unchanged.
|
|
400
|
+
- Strengthened local authority revocation and terminal runtime teardown from "termination requested" to "termination settled" semantics. Windows `taskkill.exe` is asynchronous, so a successful spawn of the helper could previously let process-session revocation delete its retained handle and acknowledge the durable Worker revocation before the process actually closed. Process-session revocation now waits for `close` within a bounded deadline and retains/retries on non-settlement. Runtime shutdown additionally drains the shared process tracker, immediately terminates any child registered after drain begins, waits for all tracked children and process sessions to close, and enters a distinct retryable `stop_failed` lifecycle state rather than advertising `stopped` when ownership remains. Superseded/fatal relay callbacks and CLI signal shutdown now await that teardown before releasing the daemon lock or exiting.
|
|
401
|
+
- Closed the final shutdown late-spawn window above the process tracker. `CallRegistry.cancelAll()` used to abort and immediately `finish()` every call, erasing handler ownership before the handler's lifecycle `finally` had actually returned; such a cancelled handler could therefore register a child after an empty process drain had already completed. Runtime shutdown now uses a terminal call-registry drain that rejects new opens, cancels existing calls without deleting them, waits for real handler `finish()` settlement on a monotonic deadline, and only then begins the process/session drains. A stalled handler remains accounted and makes shutdown retryable rather than allowing daemon ownership release. The critical coverage gate now includes both this call-drain helper and the extracted process-session termination helper, and coverage collection includes the dedicated process-output/authority-settlement regression.
|
|
402
|
+
- Made that `stop_failed` retry contract real rather than nominal. `ProcessTracker.drain()` previously kept its per-child `drainRequested` marker after a failed settlement deadline, so a later `runtime.stop()` retry could retain the child but never issue another termination request. Failed drains now clear only the surviving attempt markers before returning retryable `unavailable`; a deterministic first-fail/second-success regression requires the next drain to send termination again. The same review unified one-shot processes, process sessions, and managed-job steps on `child-process-settlement.mjs`: all prefer real `close`, but an observed `exit` with no `close` gets the same one-second residual-stdio fallback before tracker/session/resource release. Adapter-level fault injection proves one-shot and session ownership no longer remains indefinitely when libuv never emits `close`, while the managed-job integration suite remains green after removing its duplicate settlement wiring.
|
|
403
|
+
- Normalized six newly added local source modules from owner-only `0600` working-tree modes to ordinary read-only-source `0644` package modes after the npm package contract caught them at task 112/117. Two were introduced by this review and four predated it in the current uncommitted tree; no content or executable bit changed. The package manifest regression now passes with all 417 packed files using their expected modes.
|
|
404
|
+
- Removed the obsolete fire-and-forget process-session `clear()` path after all production and test cleanup moved to close-settled `clearAndWait()`. Also eliminated unexplained empty `catch {}` blocks from production source: intentionally suppressed parse, observer, socket-close, temporary-cleanup, and last-resort diagnostic failures now carry an explicit local rationale, while the review of those sites drove the ownership fixes above instead of merely adding comments.
|
|
405
|
+
- Advanced the exact source and private control-plane Wrangler toolchain from `4.115.0` to `4.120.0` and its reviewed lifecycle-script allowlist from `workerd@1.20260722.1` to `workerd@1.20260801.1`. The private toolchain still pins Wrangler, undici `7.29.0`, sharp `0.35.3`, and install-script permissions exactly. Prior deploy dry-run, private-toolchain lifecycle, and live Worker OAuth/MCP evidence remains specific to the recorded source/runtime generations; current source type generation additionally uses the bounded completion/cleanup contract above instead of treating raw CLI process exit as the only completion signal.
|
|
406
|
+
|
|
407
|
+
## 3.0.0-beta.60 - 2026-08-08
|
|
408
|
+
|
|
409
|
+
- Supersede the unactivated beta.59 candidate before publication and move resource coordination into a separate beta.60 change. The beta.59 tarball/manifest were removed; the running service remains on the previously activated baseline until a new candidate is independently verified.
|
|
410
|
+
- Add a per-user durable resource coordinator shared by one-shot processes, process sessions, detached managed-job steps, and compatible external workflow runners. Heavy/adaptive roots acquire crash-recoverable PID/start-time leases with CPU, I/O, memory, and disk reservations; control-plane/internal fixed commands and explicit light reads bypass the heavy gate. Interactive calls wait only briefly and return a structured retryable capacity error, while detached/background work may queue without consuming local MCP call slots.
|
|
411
|
+
- Make admission work-conserving rather than globally serial: host pressure combines macOS memory pressure, pageout/swapout deltas, CPU/load, thermal state, disk throughput/IOPS, free-space floors, and a five-second startup reservation window; Green permits bounded overcommit, Yellow tightens it, and Red defers heavy work. Durable waiters use interactive/ordinary/background priority with two-minute aging and select the highest-priority request that actually fits, avoiding head-of-line blocking. Same-project Cargo/Swift/Xcode/JS build families serialize only their shared cache family while unrelated projects can still run concurrently.
|
|
412
|
+
- Bound compiler fan-out and move supported build caches outside repositories. Cargo receives `CARGO_BUILD_JOBS` plus a stable per-project `CARGO_TARGET_DIR`; direct SwiftPM uses documented `--jobs`/`--scratch-path`; direct Xcode uses `-jobs`/`-derivedDataPath`; explicit user paths remain authoritative. macOS caches live under `~/Library/Caches/AgentBuilds.noindex` with a Spotlight exclusion marker. Build-root preparation is transactional with admission: any preparation failure releases the lease instead of leaving phantom capacity.
|
|
413
|
+
- Add privacy-safe resource diagnostics and strict protocol validation. `diagnose_runtime` reports pressure state, aggregate reservations, and waiter counts without command text or project paths; lease/waiter files are owner-only, bounded, strict-schema records and stale PID generations are reclaimed. New fast-plan tests cover pressure/admission, fairness, project contention, build-root controls, override propagation, and failure-path lease release.
|
|
414
|
+
- Make the shared coordinator crash-consistent across its own atomic file primitives. A runner killed between hard-link publication and staging unlink, or during an atomic lease replacement, can leave a strictly named `.lease_*.tmp` generation. The coordinator now recovers only provable internal staging shapes: same-inode two-link committed aliases, or dead-publisher single-link uncommitted replacements. All other unexpected directory entries still fail closed; managed-job integration uses a test-private coordinator/build root so fault injection cannot corrupt the real user scheduling domain.
|
|
415
|
+
- Correct an over-conservative shell-script profile discovered by the real-world workflow gate. Named build/test/verify/gate/release/archive/fuzz shell roots now use a bounded mixed reservation (`2.5` CPU, `0.5` normalized I/O, 2 GiB memory, 3 GiB disk) with same-project serialization instead of being treated as effectively unbounded. This keeps process-tree accounting conservative while allowing long project gates to start under ordinary Yellow load; Node and Python profiles use the same values.
|
|
416
|
+
|
|
417
|
+
## 3.0.0-beta.59 - 2026-08-08
|
|
418
|
+
|
|
419
|
+
- Reject the activated-but-unaccepted beta.58 candidate after live browser verification found that the local CLI `browser setup` path had not migrated with the hardened pairing protocol. The MCP pair action opened the new process-owned ephemeral listener, but the CLI still opened the sanitized long-lived broker `/pair` URL directly. That page intentionally contains no grant, so the `document_start` content script exits without bootstrap material and first pairing cannot complete. beta.58 has no acceptance record and must not be published.
|
|
420
|
+
- Make the ephemeral pairing launcher the single grant-construction boundary. Callers now provide only the broker port and current extension credential; `browser-pairing-launch.mjs` creates the 30-second grant itself. The CLI reads the current non-legacy pairing state through the same bounded/no-follow/single-link store path, opens the same one-shot listener as the MCP action, keeps its printed/JSON `pairing_url` sanitized, and closes the listener immediately if the OS browser opener fails.
|
|
421
|
+
- Add `browser-cli-pairing:test` to the fast plan and release contract. The regression runs a real ephemeral listener against temporary pairing state, proves the opened port differs from the broker port, verifies the fragment carries only broker port plus short-lived grant, verifies the served page contains neither grant nor long-lived token, and requires opener failure to leave no reachable listener. Architecture guards forbid the CLI from reopening the fixed broker URL directly.
|
|
422
|
+
|
|
423
|
+
## 3.0.0-beta.58 - 2026-08-08
|
|
424
|
+
|
|
425
|
+
- Bound signed account-admin request bodies before hashing or parsing. The authorization path now drains the original network body once under the 64 KiB limit, hashes those exact bytes, and rebuilds the internal admin request from the verified buffer; declared oversize bodies are cancelled before the first pull and chunked oversize bodies stop at the limit.
|
|
426
|
+
- Bound internal MCP JSON materialization too: stream descriptors are capped at 1 KiB and HTTP terminal fallback responses reuse the resumable-message byte ceiling instead of calling bare `response.json()`.
|
|
427
|
+
- Make managed-job approval normalization strict: explicit invalid booleans, timeouts, capture modes, final-step lists, or temporary-file lists are rejected instead of silently becoming defaults. Corrupt resource registries no longer truncate beyond 64 entries or normalize invalid `resources` types to an empty registry.
|
|
428
|
+
- Preserve browser rollback readability while hardening pairing. The envelope remains schema 2 for beta.55 compatibility and uses `pairingAuthVersion: 2`; `migrationPending` is a required boolean. Explicit pairing now uses a process-owned one-shot random loopback page, so a process occupying the long-lived broker port cannot redirect the fragment bootstrap. Both normal broker auth and first-pair auth require an init HMAC before allocating pending state, and repeated identical challenges are idempotent rather than consuming extra slots.
|
|
429
|
+
- Remove remaining small semantic drift: MCP HTTP era detection now checks the supported-version set rather than index 0 and uses one legacy fallback; call-registry origin diagnostics use a null-prototype map so prototype-shaped origin labels remain ordinary data.
|
|
430
|
+
|
|
431
|
+
- Supersede the unfinished beta.57 candidate after continued SSH fault injection found that hard-link installation still released the staging pathname without a descriptor-pinned ownership check. The installer now holds the original staging file descriptor across `link`, compares the post-link target and source against the descriptor after link-count/ctime mutation, removes the staging source only while it still matches that generation, rolls back a verified installed target if the source changes, and performs final staging cleanup only against identities captured from the generated files. A deterministic regression replaces the staging pathname immediately after link creation and requires both the installed target rollback and preservation of the replacement.
|
|
432
|
+
- Bind provisional managed-job runner claims to one launch attempt rather than PID alone. Publication rejects malformed launch tokens before creating `runner.pid`, and an existing claim is reusable only when both PID and the 32-hex launch token match, so PID reuse or a second launch in the same parent process cannot inherit stale runner ownership.
|
|
433
|
+
- Remove reusable browser broker credentials from the network path and close the first-pair loopback TOFU gap. Already-paired runtime/extension clients first send a role-bound init HMAC so untrusted local processes cannot consume challenge slots, then authenticate the broker with role-separated HMAC server proofs before WebSocket upgrade and send only five-second one-time client proofs; legacy bearer subprotocols are rejected. The fixed `/pair` HTTP page is permanently token-free. An explicit pair action places a 30-second bootstrap only in the URL fragment; the Manifest V3 content script runs at `document_start`, strips the fragment before page scripts, and keeps it in the extension isolated world. A two-step `/pair-auth` exchange uses that fragment proof as the temporary key: an init HMAC is verified before any pending slot is allocated, then the broker proves possession, consumes the client proof once, and only then releases the long-lived extension token. The pairing envelope intentionally remains schema 2 so beta.55 rollback can still read it; `pairingAuthVersion: 2` marks the hardened protocol, rotates the previously page-exposed extension token, preserves the runtime key for migration identity, and persists `migrationPending` so an old broker occupying the original port causes a fail-closed restart requirement rather than adjacent-port split-brain.
|
|
434
|
+
|
|
435
|
+
## 3.0.0-beta.57 - 2026-08-08
|
|
436
|
+
|
|
437
|
+
- Supersede the unactivated beta.56 candidate after another independent architecture/security review found additional packaged local-state and rollback defects. Beta.56 had no activation or acceptance record; its tarball/manifest were removed before these changes. Live beta.55 remains the operational service while beta.57 is verified.
|
|
438
|
+
- Make SSH-key setup validate before mutation and compensate by object identity instead of pathname. Existing private/public pairs are fully verified before any permission normalization; permission changes reopen the exact expected generation and fchmod the descriptor, so an invalid or replaced public path cannot be widened to `0644`. Generated-key results retain non-enumerable internal generation identities for rollback without exposing key bytes or identities through CLI/MCP JSON. State-write rollback and partial key installation delete only files that still match those identities, preserve replacements, retain primary-before-cleanup error causality, verify a newly linked target is still the staging inode before source cleanup, and remove the unreachable cross-filesystem copy fallback for same-directory staging.
|
|
439
|
+
- Treat malformed managed-job runner ownership as damaged authority, never absence. Successfully read but invalid `runner.pid` JSON now propagates as unreadable ownership; pruning retains the job directory and logs only a bounded error class, while active-job inventory conservatively reports `unreadable` with `runner_alive=true` so uninstall cannot proceed from corrupt ownership evidence. Managed-job JSON readers also distinguish legitimate atomic-generation churn from corruption: a stable `MBM_IDENTITY_CHANGED` code may be retried at most four times so the runner can publish terminal status concurrently with readers, while persistent churn, hard links, symlinks, and other I/O still fail closed as `identity_changed`/their existing error class.
|
|
440
|
+
- Bind service-definition removal to the definition observed before provider shutdown. Launchd/systemd uninstall snapshots the no-follow, single-link filesystem generation before stop/disable and removes the definition only if that exact generation remains afterward. A replacement or newly appeared definition is retained and removal returns `definition_changed` instead of deleting a pathname merely because the provider was stopped. Windows Task Scheduler removal likewise snapshots the state-root `service-launcher.cmd`; successful task deletion removes only that unchanged launcher, while a replacement is retained and returns `launcher_changed`.
|
|
441
|
+
- Eliminate stale workspace-state mutations around startup locks. SSH resource registration, ordinary start, secret rotation, and persistent activation use pre-lock state only to identify the lock namespace, then reload authoritative workspace state after acquiring the startup lock before modifying resources, policy, Worker/device state, or persisted secrets. Daemon-only service network environment is likewise loaded only after that lock/fresh-state boundary, preventing a wait from pinning obsolete proxy/CA values into `process.env`. Ordinary foreground start no longer performs its later best-effort machine-global autostart write after releasing all service serialization: it reacquires a short `runtime-start-autostart` machine-service lock only around the final provider/service-owner/environment mutation, without holding that lock across Worker/OAuth/relay network work.
|
|
442
|
+
- Remove the unused `state-locations.mjs`. The beta.53 review had incorrectly described it as an active state-location boundary and claimed direct `state.mjs` fan-in fell to 17; a later import-graph audit proved the module had zero importers, its Windows/state-root/workspace-hash semantics had already diverged from the live contract, and actual direct `state.mjs` fan-in is 22. Static package identity remains correctly isolated in `package-identity.mjs`; state-root/profile/workspace identity remains in `state.mjs` until a future extraction has real consumers and parity tests.
|
|
443
|
+
- Prevent same-state browser broker split-brain after partial proxy authentication. A contender that receives `EADDRINUSE` still probes the existing broker with the shared runtime credential; if the WebSocket upgrade succeeds but the authenticated peer does not complete its runtime hello before the bounded handshake deadline, startup now fails and retries later instead of moving to another port, becoming a second owner, and rewriting the shared pairing port. Unauthenticated/unrelated occupied ports can still fall through to the next bounded port.
|
|
444
|
+
- Distinguish the exclusive-file publisher's own hard-link commit window from persistent multiple-link ownership corruption. `createExclusiveFileSync` intentionally links a fully written staging inode to its final no-replace name before unlinking the staging alias; a concurrent legitimate reader can therefore observe `nlink=2` for a few microseconds. Secure-file now reports that condition as `MBM_MULTIPLE_HARD_LINKS`, and only process/owner-state/managed-job locks, browser pairing, and runner-claim reads that explicitly consume this publication protocol retry it up to four times with 1 ms scheduling gaps. A persistent hard link still fails closed after the fixed budget. Runner claims also moved from the generic bounded reader to path-identity-verified, single-link reads.
|
|
445
|
+
|
|
446
|
+
## 3.0.0-beta.56 - 2026-08-08
|
|
447
|
+
|
|
448
|
+
- Supersede beta.55 after exact-head CodeQL reported `js/insecure-temporary-file` on the new POSIX managed-job directory descriptor open. The call is read-only (`O_RDONLY | O_NOFOLLOW | O_DIRECTORY`) and never sets `O_CREAT`, so it does not create a temporary file; however CodeQL models an `open` reached from an OS-temp test path as insecure when no explicit private mode argument is present.
|
|
449
|
+
- Keep the descriptor-pinned directory design and make its privacy contract explicit by passing mode `0o700` to `openSync`. Node ignores the mode when no file is created, while the explicit owner-only mode documents the intended boundary and satisfies the static-analysis model without weakening no-follow, directory-only, descriptor identity, canonical containment, or inode-pinning guarantees. A managed-job boundary regression captures the actual third argument and requires `0o700`; architecture tests prohibit dropping it.
|
|
450
|
+
- Invalidate the beta.55 acceptance and candidate because `src/local/managed-job-directory.mjs` is packaged source. Beta.56 requires a new frozen-source verification, exact candidate, owner activation, independent live verification, acceptance, guarded push, and exact-head provider checks. The live beta.55 Worker remains operational and retains the previously verified Durable Objects rows-read repair.
|
|
451
|
+
|
|
452
|
+
## 3.0.0-beta.55 - 2026-08-08
|
|
453
|
+
|
|
454
|
+
- Supersede the activated and locally accepted beta.54 candidate after exact-head Ubuntu CI exposed a filesystem-generation ABA defect. The secure-file regression deleted a snapshot source and recreated the same pathname; Linux immediately reused the freed inode, so the production `(dev, ino)`-only identity comparison treated the replacement as the original file. The test failure is therefore release-blocking production evidence rather than a flaky fixture.
|
|
455
|
+
- Extend the shared filesystem identity with change-time generation. Real Node 26 BigInt `fstat`/`lstat` observations retain exact `ctimeNs`; Number-backed injected metadata may retain `ctimeMs`; when either compared identity has generation evidence, both must carry the same generation. This keeps the existing lossless device/inode protection while rejecting same-inode unlink/recreate ABA across secure descriptor/path checks, owner/state cleanup, process and managed-job locks, Worker-secret cleanup, security-audit identity, and SSH-key snapshots.
|
|
456
|
+
- Preserve legitimate self-mutation in Worker-secret setup. The temporary secret file keeps its creation identity until the mandatory owner-only chmod succeeds, then refreshes the identity before the deployment callback so final cleanup compares against the post-chmod generation. A deterministic injected regression changes only `ctimeNs` across that intentional chmod and requires cleanup to succeed against the refreshed generation. Managed-job directories deliberately use a different invariant: directory ctime changes whenever children are created or removed, so POSIX resolution pins an `O_DIRECTORY|O_NOFOLLOW` descriptor across realpath/path rechecks and compares exact device/inode while the old inode cannot be recycled. Windows retains exact device/inode path rechecks because Node does not expose the same directory-descriptor behavior there.
|
|
457
|
+
- Keep beta.54's Durable Objects quota result as operational evidence only. The owner activated the exact beta.54 candidate and live Cloudflare analytics showed beta.50 at 24,801 rows read across 546 invocations (45.42 rows/request) versus beta.54 at 3,321 rows across 280 invocations (11.86 rows/request) over the first three complete post-activation minutes, about a 74% reduction despite materially higher request rate. That validates the DO repair but does not authorize publishing a candidate whose packaged local filesystem source is now known to be incomplete. The beta.54 acceptance record is removed; beta.55 requires a fresh exact candidate, owner activation, live verification, acceptance, guarded push, and exact-head provider checks.
|
|
458
|
+
|
|
459
|
+
## 3.0.0-beta.54 - 2026-08-08
|
|
460
|
+
|
|
461
|
+
### Durable Object rows-read amplification repair
|
|
462
|
+
|
|
463
|
+
- Supersede beta.53 before candidate preparation after live Cloudflare quota evidence exposed a release-blocking Durable Objects read-amplification defect. After the free-tier daily reset at 00:00 UTC, the active beta.50 deployment had already accumulated 1,344,623 `rows_read` and 13,918 `rows_written` by roughly 03:31 UTC. The reads came from one active `BridgeRoom` object and were accompanied by thousands of hibernation/HTTP stream-disconnect events, proving that the previous 90% daily warning was not a one-off spike. Beta.53 had no release candidate, activation, or acceptance record.
|
|
464
|
+
- Remove the hot-path full-table sweep that caused the quota growth. Ordinary HTTP/WebSocket event entry now checks the persisted Durable Object alarm and enumerates durable stream records only when the alarm is missing, already due, or unreadable. A future alarm is authoritative for existing durable deadlines. New durable-call admission updates the active stream row and advances the persisted alarm to no later than the operation deadline inside the same storage transaction, so a crash cannot leave a committed earlier call behind a later alarm. Post-dispatch scheduling only coalesces daemon/transient deadlines and does not rescan durable rows. Actual alarm events still perform bounded durable expiry/recovery and compute the next deadline.
|
|
465
|
+
- Collapse legacy streamed-call admission into one transaction. Request-idempotency, expiry pruning, completed-stream capacity, daemon-call capacity, stream creation, and durable-call activation share one `list({prefix:"mcp-stream:"})` observation and one active-stream write before daemon dispatch. The removed beta.44 global `mcp-stream-index` remains migration-only and is never recreated, so the rows-read repair does not reintroduce the old global-row write hotspot.
|
|
466
|
+
- Give each new random stream/call generation one shared random suffix. Daemon terminal results can therefore point-read the exact stream row instead of scanning all retained streams by call ID. Pre-beta.54 calls used independent random IDs and retain only a bounded migration fallback after a point miss until those old pending calls expire. Duplicate terminal results against a ready derived stream also stop after the point read and cannot fall back to enumeration.
|
|
467
|
+
- Remove the production request-key full-scan helper. Lost legacy `prepare` responses are still idempotent because the combined admission transaction returns the already authoritative stream as `resume`; changed arguments still conflict before a second daemon send. Sessionless legacy calls remain intentionally non-idempotent and receive independent random stream generations. Modern request-scoped cancellation returns after the transient-registry miss instead of scanning legacy durable state.
|
|
468
|
+
- Add explicit Durable Object read observability and budgets. `server_info` now exposes isolate-local aggregate `stream_rows_read_estimate`, `stream_gets`, `stream_lists`, and `stream_list_rows` beside the existing write/alarm counters without recording storage keys, stream IDs, request IDs, or account identity. Tests retain 24 background stream rows and require the production combined lifecycle to perform one prefix scan at admission, one point lookup for terminal ownership, zero prefix scans during settlement/duplicate terminal lookup, and three stream-row mutations through acknowledgement cleanup. Future-alarm scheduling tests require zero durable deadline scans and preserve missing/overdue-alarm recovery.
|
|
469
|
+
- Treat the fix as unverified until it is observed live. The currently running accepted service remains beta.50 and will continue consuming the old read pattern until an exact beta.54 candidate is owner-activated. Beta.54 requires complete frozen-source gates, an exact candidate, owner activation, independent service/Worker identity verification, and a post-activation Cloudflare `rows_read` slope check before acceptance.
|
|
470
|
+
|
|
471
|
+
## 3.0.0-beta.53 - 2026-08-08
|
|
472
|
+
|
|
473
|
+
- Make local ownership snapshots descriptor-coherent. Process/startup locks, managed-job locks, owner-state/owned-JSON cleanup, service ownership, state recovery markers, and persisted control JSON now bind bytes and lossless BigInt filesystem identity to the same open descriptor, reject multiple hard links, and recheck single-link identity at destructive removal. Corrupt state recovery preserves the exact bytes that were classified as corrupt and will not rename or delete a path that was replaced after inspection.
|
|
474
|
+
- Harden destructive evidence and provider cleanup. Worker-name inventory and state-root/log-schema markers use identity-verified single-link reads; a nonzero Wrangler delete result can no longer become success from stderr prose. Systemd removal is decided from parsed provider state plus command exit status, retains an installed unit after any failed disable, and no longer assumes a missing unit file means an in-memory service is inactive.
|
|
475
|
+
- Deep-validate the main Durable Object OAuth store before authorization consumes it. Persisted accounts, clients, codes, tokens, throttling records, map keys, redirect/resource URLs, PKCE material, refresh families, DPoP thumbprints, and authorization identities now have a shared bounded contract. Structurally corrupt schema-1 state fails with the existing repair-required service error while invalid account roles retain their explicit quarantine/revocation path.
|
|
476
|
+
- Remove check/use splits in local file flows. Browser resource injection now uses the exact byte snapshot that passed resource validation; managed-job internal plan/status JSON uses identity-verified single-link reads while explicitly supplied user files retain ordinary hard-link compatibility; external plan file errors are no longer mislabeled as JSON parse failures.
|
|
477
|
+
- Reduce duplicate static package-identity parsing by moving package root/name/version to `package-identity.mjs`. The same review also introduced `state-locations.mjs` and reported that state path/hash consumers had migrated to it; beta.57 later proved that statement incorrect: the module had zero importers, the live path contract remained in `state.mjs`, and the claimed fan-in reduction to 17 never occurred. The dead/divergent module is removed in beta.57 rather than retroactively treated as an architectural boundary.
|
|
478
|
+
- Remove duplicate and obsolete adapters: CLI browser pairing now consumes a port-only projection from the canonical pairing store instead of parsing credential state itself; CLI/account/stdio reuse package identity instead of reparsing the root manifest; duplicate package-root calculation, unused device-root/WebCrypto/bearer adapters, `remoteBridgeError`, and the unused active-status convergence wrapper were removed.
|
|
479
|
+
- Tighten privacy and diagnostic cardinality. Worker health accepts only a bounded printable version token before including it in mismatch diagnostics; structured local/Worker log maps and security-audit target projection use null-prototype objects; audit target hashing is canonical across object key order while retaining prototype-shaped own keys; `search_text` skip logic uses typed error reasons instead of English messages.
|
|
480
|
+
- Clean reconstructible ignored review evidence from `.project-local`, reducing the local scratch tree from about 135 MiB to about 12 MiB before the final verification scratch, and remove obsolete local files containing the live Worker endpoint. Tracked/package privacy scans continue to contain only synthetic/example sensitive-looking fixtures.
|
|
481
|
+
- Invalidate and delete the unactivated `3.0.0-beta.52` candidate. Beta.52 was never owner-activated or accepted. Beta.53 requires a new full verification, exact candidate, owner activation, independent live verification, and acceptance cycle; no beta.52 candidate hash or prior full-gate result is release evidence for beta.53.
|
|
482
|
+
|
|
483
|
+
## 3.0.0-beta.52 - 2026-08-08
|
|
484
|
+
|
|
485
|
+
- Re-review two external agent/control-plane codebases at fixed upstream commits before the next owner activation: `earendil-works/pi@e47b8e37a6211ebd0b2942fa87059d64f81eec02` and `huangruiteng/loopx@29b086a1752a5329cb46de220225f2902353af3e`. The review line-scanned the complete text/source trees and then deeply traced their concurrency, deferred-tool, retry, lease, state/projection, output-budget, canary, and transaction implementations against Machine Bridge rather than importing either architecture wholesale.
|
|
486
|
+
- Apply Pi's bounded metadata fan-out pattern only where Machine Bridge had independent read-only I/O. `list_dir` now resolves metadata in ordered batches of 16 instead of serially awaiting up to 10,000 `lstat` operations. A 10,000-file local benchmark kept byte-identical output while reducing the stable median from about 160 ms to 79 ms; fault tests require bounded concurrency, enumeration-order preservation, cancellation between prefetched entries, and exact consumed-error behavior.
|
|
487
|
+
- Apply the same ordered bounded fan-out to `search_text`. Up to 16 independent secure file reads execute concurrently, but results are consumed in the original walk order; `max_files`/`max_matches` accounting and early-stop semantics remain sequentially equivalent, and failures from work beyond an already-satisfied stop condition cannot escape. Three old-vs-new result fixtures are byte-identical; the 10,000-small-file no-match benchmark fell from about 649 ms to 287 ms median, with colder prototype runs showing larger gains.
|
|
488
|
+
- Extend the explicit compact read-model pattern from `server_info` to `project_overview`. `detail: "summary"` preserves workspace/Git identity, effective and daemon policies/tool counts, compact capability-routing evidence, and up to 40 top-level `name/type` entries while omitting exact tool arrays, account ID, routing fingerprints, per-entry absolute paths/sizes, and long cold-path explanations. Remote calls deliberately ask the daemon for its backward-compatible default/full state, compute authenticated account authority in the Worker, and only then project summary; durable replay persists the requested summary bit and performs the same post-authority projection. The empty/default call remains backward-compatible `full`. On the current workspace the local result shrank from roughly 7.5 KiB to 2.7 KiB and a simulated owner-decorated remote result from roughly 10.5 KiB to 3.5 KiB.
|
|
489
|
+
- Add LoopX-style semantic output ratchets without adopting its canary scheduler. Compact `server_info` and `project_overview` now have absolute size budgets, exact hot-path shape assertions, and scale tests proving that hundreds of tool names/per-tool counters do not make the summary grow or leak cold-path identities. New directory/search/projector modules are critical-coverage gated. Dynamic task-dependent MCP tool exposure is intentionally not copied from Pi's provider-level deferred tools: MCP tool-list changes are a protocol/client concern, and Machine Bridge keeps a deterministic stable catalog.
|
|
490
|
+
- Invalidate and delete the unactivated beta.51 candidate because these improvements change packaged production bytes. Beta.51 was never owner-activated or accepted. The persistent live beta.50 service remains operational evidence only; beta.52 requires a fresh full gate, exact candidate, owner activation, observed live verification, acceptance, guarded push, and exact-head provider checks.
|
|
491
|
+
|
|
492
|
+
## 3.0.0-beta.51 - 2026-08-07
|
|
493
|
+
|
|
494
|
+
- Supersede the accepted-but-unpublished beta.50 candidate after exact-head provider checks exposed two release blockers. JavaScript/TypeScript CodeQL rejected two packaged no-op assignments (`ownsTemporary = false` immediately before return in atomic replacement and `staged = false` immediately before return in workspace atomic write). Remove those assignments without changing settlement or cleanup semantics; because packaged source bytes change, beta.50 acceptance is invalid for publication and a fresh candidate/activation/acceptance cycle is mandatory.
|
|
495
|
+
- Fix the Windows-only security-property fixture for managed-job identity checks. The test previously compared injected paths against the POSIX literal `/tmp/jobs`, while production correctly resolves the requested root first; on Windows the drive-qualified canonical path caused the fixture to trigger an earlier root-identity mismatch and never reach the intended canonical-target assertion. The fixture now uses `path.resolve()`/`path.join()` for root, outside target, and expected job directory. Production managed-job resolution is unchanged.
|
|
496
|
+
- Remove `release-acceptance/v3.0.0-beta.50.json` from the release branch because provider-side gates found defects after local acceptance. The live beta.50 owner activation remains historical operational evidence only; beta.51 must pass the complete local suite, exact candidate preparation, owner activation, observed live verification, acceptance, guarded push, and exact-head provider checks before prerelease publication.
|
|
497
|
+
|
|
498
|
+
## 3.0.0-beta.50 - 2026-08-07
|
|
499
|
+
|
|
500
|
+
### Close independent-review filesystem, stream, logging, and privacy gaps
|
|
501
|
+
|
|
502
|
+
- Supersede beta.49 before owner activation. A fresh independent review found that patch collision identity and patch commit identity had diverged: the per-path mutation coordinator case-folded resolved paths on Windows and macOS, while patch collision detection case-folded only Windows and staged patch targets still used overwrite-capable rename. On a common case-insensitive macOS volume, two patch targets such as `Foo` and `foo` could therefore pass preflight and one staged commit could replace the other. Beta.49 was never activated; its private candidate was removed and must not be accepted or reused.
|
|
503
|
+
- Make one `fileMutationPathKey` the path-conflict identity for both coordination and patch preflight. Patch targets now commit with a no-overwrite hard-link primitive; a target that appears after preflight fails as `conflict/target_appeared` rather than being replaced. Fault injection covers Darwin case aliases, late `EEXIST`, same-path ordering, and multi-path reservations.
|
|
504
|
+
- Extract staging, whole-file commit, multi-file patch commit, rollback, and artifact cleanup into `workspace-file-transaction.mjs`. `workspace-file-service.mjs` returns to authorization/path/content orchestration and falls below a tightened responsibility ceiling. Pre-commit cleanup failure preserves `[primary, cleanup...]` causes behind a non-exposed internal error; post-commit staging cleanup returns a fixed warning instead of retroactively reporting a committed mutation as failed.
|
|
505
|
+
- Harden the shared exclusive-file primitive used by owner state, locks, managed-job claims, pairing state, audit state, and Worker-secret setup. Remove the unused `cleanupTargetOnFailure` behavior that could delete an already-existing target after `EEXIST`; aggregate pre-commit staging cleanup failures with the primary error; and represent post-commit staging cleanup as a non-serialized internal artifact plus a fixed warning. Worker-secret setup immediately retries such a secret-bearing staging artifact with an identity check and refuses deployment if cleanup cannot be proved.
|
|
506
|
+
- Generalize the beta.47 Windows filesystem-identity correction. `filesystem-identity.mjs` now rejects lossy Number-backed device/inode values and compares exact BigInt identities. Secure descriptor/path verification performs independent BigInt `fstat`/`lstat` observations instead of treating unsafe identifiers as equal. Process/startup locks, managed-job locks/directories, Worker-secret cleanup, exclusive owner-file removal, security-audit cache identity, and SSH-key snapshots use the shared lossless boundary. Tests distinguish adjacent inode values above `2^53` and require unrepresentable Number identities to fail closed.
|
|
507
|
+
- Remove the Worker legacy-stream channel's process-wide subscriber-admission Promise. Subscriber count plus WebSocket registration is a synchronous per-stream Durable Object admission step; the post-registration storage recheck must not serialize unrelated streams behind one slow storage read. A deterministic regression holds one stream's recheck open while another stream must subscribe independently, and the channel responsibility ceiling is tightened.
|
|
508
|
+
- Reduce routine log metadata. Worker unexpected HTTP errors report a bounded route class (`mcp`, `daemon`, `oauth`, `admin`, or `other`) rather than the raw request pathname. Routine Worker deployment success/progress logs no longer retain the workspace-derived Worker name or `workers.dev` endpoint; the explicit ready/connection handoff still prints the endpoint when the operator actually needs it.
|
|
509
|
+
- Re-review ignored local artifacts as privacy state, not merely Git-excluded files. Remove reconstructible downloaded toolchains/experiments, obsolete timeout snapshots, and stale beta.13-beta.15 live endpoint probes that had no tracked references. The local review directory fell from roughly 406 MiB to 12 MiB and no remaining ignored text file matched the live Worker-endpoint pattern. Tracked/unignored privacy and reachable-history gates remain authoritative for publication.
|
|
510
|
+
- Distinguish malformed lock content from lock-storage failure across startup/daemon, owner-state, managed-job transition/recovery, and runner-owner reads. Successfully read malformed JSON may use the existing bounded stale-recovery rules, but oversized, permission, I/O, descriptor, or identity failures now propagate and retain the lock/job state for inspection instead of being treated as an absent or reclaimable owner. Deterministic oversized-lock regressions cover startup, daemon-owner inspection, owner-state, recovery, and runner metadata.
|
|
511
|
+
- Preserve daemon log evidence when its schema marker cannot be trusted. Only a missing marker or a successfully read explicit schema-version mismatch can initialize/reset log format; an oversized, inaccessible, symbolic, hard-linked, or otherwise unreadable `.log-schema` blocks trimming before either daemon log is truncated. A cross-platform oversized-marker regression verifies both log streams and the marker remain byte-for-byte intact.
|
|
512
|
+
- Preserve the decisions not to over-refactor: the local/Worker import graph remains acyclic, same-OS-user adversarial filesystem replacement remains an explicitly documented residual risk requiring OS isolation, and near-ceiling OAuth/daemon/diagnostic modules are not split unless an independent responsibility can be extracted without obscuring their state machines.
|
|
513
|
+
|
|
514
|
+
## 3.0.0-beta.49 - 2026-08-07
|
|
515
|
+
|
|
516
|
+
### Remove unrelated file-mutation contention without weakening commit safety
|
|
517
|
+
|
|
518
|
+
- Replace the process-wide file mutation queue with a dedicated per-resolved-path coordinator. Writes and edits to the same canonical target remain strictly ordered, while independent files no longer block each other merely because they share one runtime.
|
|
519
|
+
- Reserve every source and destination of a multi-file patch synchronously before waiting on prior reservations. An overlapping write/edit/patch therefore queues behind the complete transaction, unrelated paths remain concurrent, and no lock-order cycle can arise between two multi-path mutations.
|
|
520
|
+
- Keep each path reservation until the mutation callback itself settles; cancellation does not race the lock release ahead of an already-started filesystem await. Existing SHA-256 compare-and-swap checks, flushed temporary files, atomic rename/link commits, symlink and hard-link protections, patch collision checks, and rollback semantics remain authoritative.
|
|
521
|
+
- Add direct concurrency/failure regressions, same-file concurrent edit coverage, architecture ownership limits, and critical-module coverage for the new coordinator. `LocalRuntime` no longer owns a global mutation queue, restoring composition-root headroom.
|
|
522
|
+
- Add an opt-in `server_info { detail: "summary" }` hot-path projection inspired by LoopX's canonical-decision/compact-projection split. The existing empty/default call remains byte-shape compatible with full diagnostics. Summary keeps effective policy/count, automatic-execution/owner-ambient-authority semantics, daemon readiness and relay state, bounded pending/socket capacity, and foreground/settlement limits while omitting account identifiers, OAuth metadata, exact tool arrays, and per-tool observability. Worker projection ownership moves out of stream dispatch, and legacy resumable calls now preserve the detail argument.
|
|
523
|
+
- Extract the Worker daemon-status projection into `daemon-status.ts`; `BridgeRoom` retains stale-socket reclamation but no longer owns the ready-socket/attachment-to-status mapping. The Worker composition root falls from 843 to 820 lines and its architecture ceiling is tightened from 850 to 830.
|
|
524
|
+
- Define handler return as the local tool settlement point. Cancellation remains cooperative before/during cancellable work, and remote cancellation still suppresses a result whose owner stopped waiting, but a signal arriving after a non-cancellable commit has begun can no longer make `ToolExecutor` report `cancelled` after the handler, observability, and audit have recorded successful completion.
|
|
525
|
+
- Preserve the primary owner-state operation failure when lock release also fails. Shared state locks now aggregate `[primary, release]` in causal order instead of allowing a changed/unreadable lock during cleanup to replace the original failure.
|
|
526
|
+
- Set repository `save-exact=true` in addition to `engine-strict=true`. Root dependency fields were already architecture-gated to exact semantic versions; the npm setting prevents future save operations from silently reintroducing ranges. The project deliberately does not set npm `min-release-age`: a blanket age window can block a newly published security fix, while Machine Bridge already uses exact pins, committed locks, hardened npm, audit/signature checks, and reviewed lifecycle-script allowlists.
|
|
527
|
+
- The accepted beta.48 artifact remains valid evidence only for beta.48 and cannot be reused for beta.49.
|
|
528
|
+
|
|
529
|
+
## 3.0.0-beta.48 - 2026-08-07
|
|
530
|
+
|
|
531
|
+
### Keep release activation out of first-run account provisioning
|
|
532
|
+
|
|
533
|
+
- Supersede beta.47 after the owner ran the exact candidate activation command and the Worker advanced to beta.47, but the command exited nonzero with an `unauthorized` authentication error before foreground candidate relay readiness. Forward recovery then installed, started, and verified the exact beta.47 login service, so remote control recovered and the live Worker/daemon converged on beta.47; however, no beta.47 activation record was written and the failed owner command is not valid release evidence.
|
|
534
|
+
- Remove the redundant initial-owner provisioning round trip from candidate activation and its one allowed same-identity Worker repair. Candidate activation already requires an existing deployment; after Worker convergence it now creates only the device session needed for the candidate relay. Ordinary first-run/start still checks account inventory and creates the initial owner when required. This removes an independent account-admin authentication dependency from the pre-readiness release path without weakening relay authentication or account administration.
|
|
535
|
+
- Preserve the phase boundary: any failure before candidate relay readiness still exits nonzero even if forward recovery later restores a ready candidate service, while only explicitly classified post-readiness settlement failures may become recovered success. The fault-injection regression now uses the observed `BridgeError(authentication_failed, "unauthorized")` shape and still proves nonzero pre-readiness recovery.
|
|
536
|
+
- Add release-architecture wiring checks so both the normal activation preparation and same-identity repair path must disable initial-owner provisioning, while general startup keeps provisioning enabled by default. Beta.47 remains blocked; beta.48 requires a new exact candidate, owner activation, observed live verification, acceptance, guarded push, and provider-side gates.
|
|
537
|
+
- Harden the real process-tree regression exposed by beta.48 candidate preparation under V8 coverage. The test no longer samples descendant liveness at one fixed 2.5-second instant; it polls only through the production SIGTERM grace plus both bounded ownership-observation budgets and fails if the SIGTERM-ignoring descendant is still alive after that complete bound. This removes scheduler-sensitive false failures without changing runtime termination deadlines or accepting a leaked process.
|
|
538
|
+
|
|
539
|
+
## 3.0.0-beta.47 - 2026-08-07
|
|
540
|
+
|
|
541
|
+
### Preserve Windows filesystem identity and bounded process-tree cleanup
|
|
542
|
+
|
|
543
|
+
- Supersede beta.46 after exact-head Windows CI reached packaged managed-job directory validation and exposed a production portability defect: Number-backed filesystem identity can lose precision for Windows file identifiers. Managed-job root and job-directory before/after/canonical checks now use lossless BigInt `lstat` observations while retaining symlink, type, containment, canonical-target, and TOCTOU fail-closed checks.
|
|
544
|
+
- Bound one-shot process termination more tightly. Pre-SIGTERM ownership capture and post-SIGTERM refresh share one monotonic snapshot budget; forced termination still requires current captured process identity, so a direct child exiting cannot silently cancel cleanup of an owned SIGTERM-ignoring descendant and stale or unprovable ownership still prevents SIGKILL.
|
|
545
|
+
- Add deterministic boundary, property, architecture, real-process, and coverage regressions for BigInt identity, unsafe/changing identity rejection, shared ownership-budget exhaustion, descendant cleanup, and module responsibility limits.
|
|
546
|
+
- Remove the beta.46 acceptance record because packaged production bytes changed. Beta.47 requires a fresh exact candidate, owner activation, observed live verification, acceptance, guarded push, and successful provider-side Windows/security gates before merge or publication.
|
|
547
|
+
|
|
548
|
+
### Cut verification latency and remote-call amplification
|
|
549
|
+
|
|
550
|
+
- Replace the serial fast-check launcher with a bounded runner that directly executes simple single-Node package scripts, preserves npm for lifecycle hooks/compound or non-Node scripts, parallelizes only the fast-plan tasks not marked as process-heavy barriers, and stops scheduling new work after the first observed failure while retaining bounded diagnostics. No verification task is removed.
|
|
551
|
+
- Replace hundreds of per-file `node --check` child processes with one parse-only Node VM-module subprocess plus the existing shell-wrapper syntax check. This removes process-start amplification and large latency variance without evaluating or linking repository modules.
|
|
552
|
+
- Shorten real process-tree fault-injection fixtures without replacing them with mocks: managed-job descendant timeout coverage now reaches the same timeout/SIGTERM/SIGKILL/terminal-state path in seconds instead of deliberately idling for three minutes, and the local shell tree fixture uses a bounded ten-second timeout. The coverage runner also stops executing `runtime-self-test` twice because `local-self-test` already invokes it.
|
|
553
|
+
- Make `project_overview` run its independent top-level-directory and Git-root probes concurrently and bound the returned top-level inventory to 40 entries with explicit total/truncation metadata, reducing response/context amplification for broad workspaces.
|
|
554
|
+
- Stop instructing hosts to call `resolve_task_capabilities` before every substantive direct task. Resolution remains the explicit path for refreshed instructions, local skills/commands, and application/browser routing; straightforward file, Git, and shell work can use the exposed tools directly.
|
|
555
|
+
- Extract relay close/error, handshake/readiness, user-cause, and reconnect classification from the previously saturated connection lifecycle module into a dedicated boundary module, preserving the existing relay API while restoring architectural responsibility headroom.
|
|
556
|
+
- Keep the extracted relay-classification boundary inside the critical-module coverage gate and preserve publishable source modes; package inspection rejects private-only source modes before candidate creation.
|
|
557
|
+
- Clarify the host boundary: host-rendered tool-call indicators and cached connector schemas are not Machine Bridge logs and cannot be suppressed or invalidated by the server. The runtime now documents reducing unnecessary calls and treating the server-reported 60-second foreground ceiling as authoritative.
|
|
558
|
+
|
|
559
|
+
## 3.0.0-beta.46 - 2026-08-07
|
|
560
|
+
|
|
561
|
+
### Clear Windows and CodeQL release gates without weakening policy
|
|
562
|
+
|
|
563
|
+
- Supersede beta.45 after its first exact-commit pull-request run exposed two blocking external-gate defects. Windows checkout converted executable workflow YAML to CRLF, so the repository-native LF-only Workflow Policy Gate failed even though the dedicated Linux gate passed. The JavaScript/TypeScript CodeQL run also rejected seven release failure sinks whose externally influenced diagnostic value was interpolated into a log string and one trust-broker test mutation that reopened a previously inspected path.
|
|
564
|
+
- Add a minimal Git attribute contract that normalizes `.github/workflows/*.yml` and `.yaml` as text with `eol=lf`. The workflow-policy regression queries Git's effective `text` and `eol` attributes for both extensions; the verifier still rejects CRLF source and is not weakened for Windows.
|
|
565
|
+
- Encode every top-level release, acceptance, publication, soak, backlog, candidate-start, and guarded-push failure as one JSON log record with a fixed validated event name and the existing bounded portable-redaction result. Hostile CR/LF, terminal controls, credentials, email addresses, and home paths cannot create a second physical log line or escape the redaction boundary.
|
|
566
|
+
- Replace the macOS trust-broker tamper test's path-based append with an `O_NOFOLLOW` descriptor open, `fstat` regular-file/single-link validation, descriptor write, and guaranteed close. The test still proves tampered binaries are rebuilt and re-signed without retaining a CodeQL-visible check/use split.
|
|
567
|
+
- Remove the beta.45 acceptance record because these release-script bytes change the package. Beta.46 requires a new exact candidate, owner activation, live verification, acceptance, guarded push, and successful Windows/CodeQL reruns before prerelease publication.
|
|
568
|
+
|
|
569
|
+
## 3.0.0-beta.45 - 2026-08-06
|
|
570
|
+
|
|
571
|
+
### Stop Durable Objects stream write amplification and restore fresh CI bootstrap
|
|
572
|
+
|
|
573
|
+
- Supersede beta.44 after live quota evidence and GitHub CI exposed two release-blocking mechanisms. One beta.44 Worker isolate reported 264 estimated resumable-stream rows for 40 calls (about 6.6 rows per call before all acknowledgement cleanup); the state machine could write both a per-stream row and the global `mcp-stream-index` at begin, activation, terminal settlement, and cleanup, producing up to eight logical rows for one ordinary call.
|
|
574
|
+
- Make `mcp-stream:*` records the sole Durable Object authority. Capacity admission, request-id deduplication, persisted-call lookup, detach/rebind, deadline expiry, terminal replay, and cleanup use bounded transaction-safe prefix enumeration. Existing beta.44 records remain readable, while the derived legacy index is deleted at most once and is never recreated.
|
|
575
|
+
- Bound an immediate Worker-local lifecycle to three committed rows and an ordinary daemon lifecycle to four. Duplicate settlement and read-only lookup paths write zero rows. A committed-mutation meter separates stream puts, stream deletes, one-time legacy-index migration, alarm sets/deletes, and alarm no-ops; rolled-back transactions are excluded.
|
|
576
|
+
- Add repeated lifecycle, migration, reconnect, expiry, race, persistence-failure, key-integrity, and transaction-rollback regressions. Repository Durable Object storage doubles now implement the production `list({ prefix })` contract rather than preserving a production fallback for incomplete mocks.
|
|
577
|
+
- Fix the pre-`npm ci` CI bootstrap. The beta.44 workflow imported `https-proxy-agent` through the hardened npm downloader before dependencies existed, so Ubuntu, macOS, and package-audit jobs failed in a fresh checkout. The bootstrap download closure now uses only Node 26 standard-library `https.Agent({ proxyEnv })`, with exact HTTPS artifact URLs, bounded downloads, proxy validation, redirect rejection, and cleanup guarantees retained.
|
|
578
|
+
- Remove the beta.44 acceptance record because both Worker and packaged bytes changed. Beta.45 requires a fresh exact candidate, owner activation, live Worker/service verification, acceptance, guarded push, and complete external CI before any prerelease publication.
|
|
579
|
+
|
|
580
|
+
## 3.0.0-beta.44 - 2026-08-06
|
|
581
|
+
|
|
582
|
+
### Make managed-job cancellation and workflow governance fail closed
|
|
583
|
+
|
|
584
|
+
- Supersede beta.43 before owner activation. A Workflow Bundle-controlled independent review found that managed-job cancellation and job-directory discovery still used `existsSync`: permission or I/O failure could be interpreted as no cancellation, and a symbolic-link job directory could redirect status, plan, cancellation, or cleanup operations outside the managed-job root. Beta.44 canonicalizes the root before resolving a validated job id, rejects symlinked or identity-changing directories, writes cancellation markers through flushed atomic replacement, and treats only `ENOENT` as no cancellation. Marker type, link count, UTF-8, timestamp shape, and path identity are independently verified; unreadable cancellation evidence fails the job instead of allowing later steps to continue.
|
|
585
|
+
- Make runner ownership discovery fail closed. Provisional claim polling now uses the shared present-path inspector and preserves the storage error as the cause; permission, I/O, wrong-type, and symbolic-link failures no longer become a thirty-second false absence.
|
|
586
|
+
- Centralize temporary hardened-npm session settlement. Candidate and registry-package activation clear their live session reference and call one helper that preserves the primary failure and aggregates cleanup failure, preventing the two owner entrypoints from drifting.
|
|
587
|
+
- Redact the remaining release subprocess diagnostics. npm global-prefix and GitHub Release command failures use the shared bounded command label and portable log redaction rather than exposing full arguments, credential-bearing URLs, home paths, or raw remote output.
|
|
588
|
+
- Rename the GitHub-side workflow checker to **Workflow Policy Gate** so it cannot be confused with the local Universal AI Development Workflow Bundle control plane. The gate now validates executable YAML structure: required commands must be real `run` steps, required action inputs must belong to the matching immutable action step, and comments, names, or near-match commands cannot forge release evidence.
|
|
589
|
+
- Add fast fault injection for managed-job storage errors, symlink and hard-link markers, job-root escape, malformed cancellation evidence, runner-claim I/O failure, workflow comment forgery, near-match commands, and release diagnostic redaction. Local Workflow Bundle authority remains excluded from Git and npm package bytes.
|
|
590
|
+
- Advance all runtime and extension identities to beta.44. The beta.43 tarball and pending manifest are stale after these packaged changes and must not be activated, accepted, published, or used as soak evidence. A fresh exact beta.44 candidate and complete local/owner/registry lifecycle are required.
|
|
591
|
+
|
|
592
|
+
## 3.0.0-beta.43 - 2026-08-06
|
|
593
|
+
|
|
594
|
+
### Close second-pass activation, publication, and deployment-fingerprint gaps
|
|
595
|
+
|
|
596
|
+
- Block beta.42 before owner activation. Its candidate wrapper disposed the temporary hardened npm before reading the current global rollback baseline, then attempted to execute the deleted npm CLI path. The owner command would therefore fail before Worker/service mutation. Beta.43 captures the baseline while the session is live, authorizes Worker mutation before downloads or installation, and allocates a persistent release-channel runtime only for a real persistent activation; `--install-only` removes its disposable foreground runtime. Candidate prepare/record/verify and the first guarded push also use hardened npm, so accepted bytes are never regenerated by the ambient bundle.
|
|
597
|
+
- Make candidate-runtime pruning path-safe and evidence-safe. State, release-channel, runtime-container, active-runtime, and inactive-runtime directories must be real contained directories; symlinked ancestors and identity changes fail before recursive deletion. Operational quota, memory, stale-handle, retry, and buffer failures remain non-blocking warnings, while structural failures remain blocking. All blocking pruning completes before an activation record is written.
|
|
598
|
+
- Restore bounded network behavior after trusted-executable migration. Absolute POSIX and Windows Git paths retain the forced HTTP/1.1 transport policy, and every Git/GitHub/npm registry network attempt has a hard timeout, bounded output, and classified retry behavior.
|
|
599
|
+
- Reconcile irreversible publication outcomes. npm publication checks for an exact preexisting version, publishes only the privately staged accepted tarball, and after every upload result waits for matching version, SHA-1, SRI, dist-tag, and publication metadata. Ambiguous results prohibit blind retry; an exact remotely visible object settles idempotently or as a bounded recovered success. GitHub Release mutation similarly waits for matching prerelease/final metadata and the exact REST SHA-256 asset before reporting success.
|
|
600
|
+
- Preserve primary and cleanup failures throughout acceptance, consumer verification, hardened npm construction, soak verification, GitHub publication, and CI bootstrap. Concurrent failures are aggregated instead of allowing temporary cleanup to replace the causal error. Storage/resource failures such as `EDQUOT`, `ENOMEM`, `EAGAIN`, `ENOBUFS`, `EINTR`, and `ESTALE` are operational and do not trigger destructive private-toolchain reconstruction.
|
|
601
|
+
- Make registry installation state explicit. The published-prerelease installer records the global-install attempt before npm mutation and distinguishes an attempted, completed-but-unverified, and fully verified global replacement in failure guidance.
|
|
602
|
+
- Upgrade the Worker deployment fingerprint to a length-framed v5 format. Required Worker/shared/config sources are read through bounded no-follow identity checks; missing, unreadable, hard-linked, special, or symlinked paths fail closed. File count, normalized relative paths, and bytes are individually framed so different file layouts cannot produce the same HMAC input.
|
|
603
|
+
- Bound the OAuth browser regression itself. Headless Chrome runs in a dedicated process group; cleanup escalates from TERM to KILL, closes every local HTTP server, removes the profile with bounded retries, and aggregates cleanup failures with the causal assertion error. A renderer that inherits Chrome stderr can no longer keep the full release gate alive indefinitely.
|
|
604
|
+
- Add a repository-native Workflow Policy Gate. Six workflows are read through bounded no-follow identity checks and validated for approved triggers, read-only default permissions, reviewed job-level writes, per-job timeouts, workflow/ref concurrency, immutable Action SHAs, disabled checkout credentials, fixed Node selection, and direct event-data shell interpolation. Fault injection covers dynamic/unreviewed Actions, privileged triggers, permission expansion, malformed UTF-8, missing contracts, symlinks, and hard links; release creation now requires a successful exact-commit Workflow Policy Gate run.
|
|
605
|
+
- Make security and release state discovery fail closed. Browser pairing, service network environment, machine service ownership, global configuration, legacy approval state, prerelease activation, soak evidence, and official conformance checkout inspection treat only `ENOENT` as absence. Permission, I/O, wrong-type, symlink, hard-link, and identity errors remain distinct failures instead of generating new credentials, dropping saved environment, overwriting ownership, or reporting missing evidence.
|
|
606
|
+
- Bind the development macOS trust-broker cache to both source and compiled binary SHA-256. Reuse additionally requires a regular single-link owner-only executable; tamper or an obsolete marker rebuilds and re-signs the broker, while access and cleanup failures remain blocking. Temporary compiler output is read through the same bounded no-follow boundary before atomic replacement.
|
|
607
|
+
- Redact release diagnostics consistently. Git/GitHub/npm subprocess failures expose only a bounded executable/subcommand label and sanitized output; access tokens, bearer values, credential-bearing URLs, email-shaped identities, home paths, controls, and excessive remote output are removed. GitHub control scripts are now included in syntax, lint, and complexity gates, and the redundant release-side npm-environment forwarding module was removed.
|
|
608
|
+
- Retain the beta.39 consumer isolation and beta.40-beta.42 activation/publication hardening. Beta.43 changes packaged and Worker bytes and requires a fresh exact candidate, owner-machine activation, registry publication, published-package activation, and complete seven-day soak.
|
|
609
|
+
|
|
610
|
+
## 3.0.0-beta.42 - 2026-08-05
|
|
611
|
+
|
|
612
|
+
### Close release-path and recovered-activation audit gaps
|
|
613
|
+
|
|
614
|
+
- Block beta.41 before owner activation. An independent source review found that its recovered-success branch accepted any post-readiness exception once the exact candidate service converged, so an unexpected `TypeError`, invariant defect, or other programming failure could be converted into a successful activation. Beta.42 permits recovered success only for three explicit operational classes: relay authentication rejection, autostart definition installation failure, and autostart start/persistence failure. Unknown errors retain their original error type and remain nonzero even when the compatible service is verified ready.
|
|
615
|
+
- Preserve recovered activation evidence end to end. The CLI returns a bounded reason and detail, the owner wrapper validates and prints the recovery warning, and local/registry activation records persist the same optional metadata. Missing, malformed, or inconsistent recovery fields fail closed.
|
|
616
|
+
- Remove ambient npm from sensitive release mutations. Candidate installation, registry-published global installation, and `npm publish` now use a temporary integrity-pinned hardened npm 12.0.1 with fixed undici 6.28.0 and brace-expansion 5.0.9. Nested npm execution modes are removed case-insensitively, and critical pack/install/publish commands explicitly override dry-run and workspace configuration so parent lifecycle variables or user npm configuration cannot create a false success.
|
|
617
|
+
- Make private-toolchain recovery non-destructive. Only positively identified marker, manifest, path-shape, or dependency-integrity corruption triggers reconstruction. Permission, I/O, storage, read-only-filesystem, descriptor exhaustion, and timeout failures are propagated without deleting the existing hardened npm or Wrangler tree. Global rollback-baseline discovery likewise treats only an absent package as empty state and rejects unreadable, malformed, symlinked, or escaping installations.
|
|
618
|
+
- Strengthen artifact evidence. The consumer gate performs an ordinary installation including optional production dependencies, and both workspace and consumer CycloneDX validation require one complete, unique, closed dependency entry for every root/component reference. Hardened npm and Wrangler verification are split into bounded modules and reject symlinked critical runtime paths.
|
|
619
|
+
- Canonicalize the consumer fixture itself before npm operations and stage the accepted tarball inside that fixture. This avoids npm 12 treating a valid external `file:` dependency as invalid when macOS aliases `/var` to `/private/var`, without weakening the zero-problem dependency-tree requirement.
|
|
620
|
+
- Bind every publication channel to the exact accepted tarball. GitHub Release publication stages the no-follow, single-link accepted candidate into a private temporary directory, uploads that file without repacking, and verifies the remote REST asset SHA-256. npm publication runs the full prepublication gate, requires npm's own tarball dry-run to report the accepted name/version/SHA-1/SRI, and then publishes the same staged bytes with lifecycle scripts disabled. Published installation and formal soak independently require the GitHub asset digest and npm registry hashes to match local acceptance.
|
|
621
|
+
- Remove PATH-resolved release control tools and ambiguous post-success cleanup. GitHub push/backlog/Release, acceptance indexing, publication locking, soak tag lookup, and the portable verifier use trusted absolute git/gh executables. Registry installation resolves the owner's actual global npm prefix before hardened installation. Non-critical candidate-runtime, Release staging, backfill, and post-publish temporary cleanup failures produce bounded warnings only after the irreversible result is independently verified; unknown/programming failures remain blocking.
|
|
622
|
+
- Retain the beta.39 consumer dependency isolation and beta.40/beta.41 relay/service recovery mechanics. Beta.42 is a new functional prerelease and requires a new complete seven-day soak after exact registry publication and published-package activation.
|
|
623
|
+
|
|
624
|
+
## 3.0.0-beta.41 - 2026-08-05
|
|
625
|
+
|
|
626
|
+
### Complete verified forward recovery as an activation success
|
|
627
|
+
|
|
628
|
+
- Block beta.40 after the owner-terminal command reached an exact beta.40 Worker and verified login daemon through automatic compatible-service recovery but still exited nonzero and wrote no activation record. The final runtime was healthy, yet the release workflow correctly could not treat a failed command as candidate acceptance.
|
|
629
|
+
- Distinguish pre-verification failure from post-verification handoff failure. A candidate that never completed device authentication and `ready_ack` still fails even when a compatible service later recovers. When the foreground candidate had already completed end-to-end readiness, however, a later installation, asynchronous relay, or strict service-start failure may settle successfully only after compensation independently verifies the exact candidate service daemon, readiness checkpoint, and Worker version.
|
|
630
|
+
- Return a structured recovered activation result for that narrow final-state success. Human output emits a warning with the bounded recovery class, JSON output records `activation_recovered` and `activation_recovery_reason`, and the owner command exits successfully so the existing candidate wrapper can write its activation evidence. Primary error text is not silently discarded into an ordinary success path.
|
|
631
|
+
- Keep cleanup and convergence fail closed. Provider-active state alone, an unverified daemon, wrong entrypoint/version, Worker mismatch, lock-release failure, or a candidate that never reached readiness continues to produce a nonzero error with aggregated diagnostics.
|
|
632
|
+
- Retain the beta.39 installed-consumer security corrections and beta.40 bounded authentication/convergence mechanics unchanged. Beta.41 was prepared but blocked before owner activation by the independent release-path audit described in beta.42; no beta.41 activation or soak evidence is valid.
|
|
633
|
+
|
|
634
|
+
## 3.0.0-beta.40 - 2026-08-05
|
|
635
|
+
|
|
636
|
+
### Make failed candidate activation converge or remain diagnostically exact
|
|
637
|
+
|
|
638
|
+
- Block beta.39 after its owner-terminal activation updated the Worker but exhausted candidate device-authentication startup and then failed to restore a running persistent daemon. The compatible beta.39 service could be recovered manually from the exact isolated candidate, but the owner command exited unsuccessfully and wrote no activation record; beta.39 therefore cannot be accepted, published, or used for soak evidence.
|
|
639
|
+
- Extend post-deployment candidate authentication convergence to ten bounded starts with exponential delay while retaining exactly one same-name, same-device-identity repair deployment. This accommodates delayed Worker secret/identity convergence without turning ambiguous network, TLS, proxy, or health errors into repeated remote writes.
|
|
640
|
+
- Separate strict service handoff from failure compensation. Normal activation still requires the committed service owner and post-`ready_ack` daemon checkpoint. After the Worker has advanced, compensation starts the compatible provider without the ordinary readiness helper immediately stopping it, then independently requires the exact candidate service daemon and Worker to converge before recovery is reported successful.
|
|
641
|
+
- Preserve the primary activation error together with the exact candidate-service recovery failure. A provider that merely appeared active is no longer described as recovered, and incomplete cleanup reports both the authentication cause and the final daemon/Worker convergence state.
|
|
642
|
+
- Retain the beta.39 consumer-artifact, hardened npm, private Wrangler, audit, signature, SBOM, nested npm-environment, and Dependabot metadata corrections unchanged. Beta.40 was prepared as the next prerelease but was later blocked by the recovered-activation settlement defect described in beta.41; no beta.40 soak evidence is valid.
|
|
643
|
+
|
|
644
|
+
## 3.0.0-beta.39 - 2026-08-05
|
|
645
|
+
|
|
646
|
+
### Audit the installed consumer and isolate the deployment toolchain
|
|
647
|
+
|
|
648
|
+
- Remove Wrangler from the published package's production dependency graph. The package now ships an exact private-toolchain manifest and lockfile, installs that control-plane toolchain under the owner-only state root on demand, serializes installation with a process-identity lock, rejects tampered templates or dependency edges, requires Wrangler 4.115.0, undici 7.29.0, and sharp 0.35.3 exactly, and refreshes a zero-vulnerability npm audit plus registry-signature verification at least every 24 hours. The installer itself runs through a package-owned hardened npm 12.0.1 whose pinned tarball is rebuilt with undici 6.28.0 and brace-expansion 5.0.9 after independent SHA-512 verification.
|
|
649
|
+
- Add a final-consumer security gate that packs the actual tarball, installs it into an empty package, requires a zero-vulnerability production audit, validates the installed dependency tree, and generates a CycloneDX SBOM from that consumer installation. Wrangler and Miniflare are forbidden from the published runtime tree; vulnerable undici versions fail both tree and SBOM validation. CI package-audit, the full installation test, and release verification now execute this gate.
|
|
650
|
+
- Sanitize inherited npm dry-run/global/workspace settings for nested package operations. An outer `npm publish --dry-run` can no longer make release-acceptance or consumer-security fixture packs report success without writing a tarball.
|
|
651
|
+
- Keep Node.js 26 as the package/runtime requirement while changing only the development-engine mismatch policy to a warning. This lets GitHub's Node 24 Dependabot updater inspect and update dependency metadata; the published `engines` contract, strict consumer installation, CLI startup guard, doctor check, and CI Node 26 baseline remain unchanged.
|
|
652
|
+
- Invalidate the beta.38 soak. Its root override selected undici 7.29.0 only in the source workspace; ordinary npm consumers installed Wrangler/Miniflare with undici 7.28.0 and therefore inherited one high and three moderate audit findings. Beta.39 is a new functional prerelease and requires a new complete soak.
|
|
653
|
+
|
|
654
|
+
## 3.0.0-beta.38 - 2026-08-05
|
|
655
|
+
|
|
656
|
+
### Keep relay liveness acknowledgement off durable storage paths
|
|
657
|
+
|
|
658
|
+
- Send the Worker `pong` immediately after the authenticated socket attachment is refreshed, before any Durable Object alarm read or write. A slow alarm/storage operation can no longer delay heartbeat acknowledgement and make an otherwise healthy connection appear silent.
|
|
659
|
+
- Make daemon activity refresh scheduling-explicit. Heartbeats perform one alarm schedule after `pong`, and terminal tool results coalesce liveness and pending-call deadline updates into exactly one schedule instead of the previous implicit-plus-explicit pair.
|
|
660
|
+
- Isolate the complete event-time alarm scheduling path, not only the final alarm write. Durable deadline reads, invalid-socket cleanup, or diagnostic callback failures now become bounded observability events instead of aborting a registered call before dispatch or rejecting a WebSocket message event. The actual Durable Object `alarm()` handler remains failure-propagating so the platform can retry it.
|
|
661
|
+
- Add architecture regressions that require `pong` to precede alarm scheduling, forbid socket-touch helpers from acquiring hidden alarm ownership, and require one terminal-result alarm schedule.
|
|
662
|
+
- Record the live beta.37 incident boundary: the same launchd daemon (PID unchanged, `runs=1`) recovered a `1006 connection_interrupted` episode in 2.631 seconds on its first attempt. macOS changed the `utun5` link-quality classification from good to poor four seconds before the close while the default route remained inside the Karing system-extension tunnel. This is strong temporal correlation with OS Wi-Fi/TUN path degradation, not proof that Karing, a selected proxy node, Cloudflare, or any specific upstream component caused the close.
|
|
663
|
+
|
|
664
|
+
## 3.0.0-beta.37 - 2026-08-04
|
|
665
|
+
|
|
666
|
+
### Close second-order relay recovery races
|
|
667
|
+
|
|
668
|
+
- Bind asynchronous daemon-authentication proof failures to the WebSocket generation that requested them. A rejected proof from an already closed socket can no longer terminate a replacement connection that is currently connecting or ready.
|
|
669
|
+
- Apply explicit close-category precedence. The first specific connect, handshake, readiness, heartbeat, or Worker recovery cause survives later specific or generic close signals; only an empty or generic transport category may be upgraded.
|
|
670
|
+
- Separate socket cleanup from alarm ownership. Runtime-alarm invalidation no longer recursively schedules another alarm, and the final alarm deadline is recomputed after detach/rebind state changes so reconnect grace cannot inherit a stale pre-detach deadline.
|
|
671
|
+
- Close invalidated sockets before awaiting durable cleanup. Concurrent `error`/`close` callbacks share one cleanup Promise; successful cleanup remains terminal, while a transient failure is retried once in-event and releases its slot for a later callback without duplicating disconnected metrics or warning logs. Welcome, readiness-probe, replacement, liveness, send-failure, error, and close paths preserve the intended close reason even when storage cleanup fails.
|
|
672
|
+
- Mark the authenticated relay diagnostic snapshot as recovered when a probing socket becomes ready, extend outage duration through the actual readiness instant, canonicalize timestamps, and accept only stable coarse transport error classes. Failed reconnect attempts no longer erase the duration of the preceding healthy ready interval. A healthy `server_info.daemon.relay_transport` no longer reports the preceding reconnect as currently active or exposes arbitrary daemon metadata.
|
|
673
|
+
- Add fault-directed regressions for stale authentication promises, competing specific close causes, send-failure precedence, post-invalidation deadline recomputation, cleanup deduplication/retry, previous-ready-duration retention, ready-state diagnostic projection, and the scheduling-free cleanup architecture contract. Beta.36 was prepared but not activated; beta.37 supersedes that local candidate.
|
|
674
|
+
|
|
675
|
+
## 3.0.0-beta.36 - 2026-08-04
|
|
676
|
+
|
|
677
|
+
### Preserve and expose relay-disconnect evidence
|
|
678
|
+
|
|
679
|
+
- Preserve a specific connect, handshake, readiness, or heartbeat timeout classification when a later generic WebSocket error arrives before the close event. The late error can still terminate the socket, but it no longer erases the causal category used for recovery diagnosis.
|
|
680
|
+
- Make Worker daemon-socket cleanup idempotent. Error, close, candidate timeout, readiness timeout, liveness timeout, verified replacement, and send-failure paths converge on one expiry, pending-call detach, disconnected metric, and runtime-alarm transition, preventing duplicate Durable Object work when one socket emits both error and close. Synchronous stale-socket reclamation now retains its asynchronous cleanup with Durable Object `waitUntil` and converts storage failures into one bounded observability event instead of an unhandled rejection.
|
|
681
|
+
- Add a schema-versioned, privacy-bounded relay diagnostic summary to the authenticated daemon hello. The Worker sanitizes and preserves the immediately preceding reconnect episode in the daemon attachment and exposes it as authenticated `server_info.daemon.relay_transport`; endpoints, interface names, DNS data, arguments, and results remain excluded.
|
|
682
|
+
- Make `machine-mcp doctor` report its diagnostic scope explicitly. Doctor uses an isolated local runtime and does not inspect the running service process or its remote relay, so a green doctor result can no longer be mistaken for service WebSocket health.
|
|
683
|
+
- Add deterministic regressions for late-error classification, diagnostic bounding/projection, idempotent socket expiry, unified stale-candidate invalidation, retained asynchronous cleanup, authenticated server-info projection, and doctor scope.
|
|
684
|
+
- Pin the transitive `brace-expansion` and `undici` packages to fixed same-major releases through root overrides. The release audit discovered high-severity advisories in ESLint/Wrangler dependency paths; `npm audit fix --force` proposed an unrelated Wrangler downgrade, so beta.36 keeps the tested Wrangler/Miniflare versions while selecting `brace-expansion` 5.0.9 and `undici` 7.29.0.
|
|
685
|
+
|
|
686
|
+
## 3.0.0-beta.35 - 2026-08-03
|
|
687
|
+
|
|
688
|
+
### Enforce the patch-helper call contract
|
|
689
|
+
|
|
690
|
+
- Remove the obsolete third argument from the workspace patch call after beta.32 intentionally removed path data from `applyUpdateHunks` errors. The extra argument had no runtime effect but violated the helper contract and was rejected by the zero-unaccepted-findings CodeQL gate.
|
|
691
|
+
- Add an architecture source-contract regression requiring the single workspace call to match the two-argument helper signature, so local verification catches the mismatch before remote CodeQL.
|
|
692
|
+
|
|
693
|
+
## 3.0.0-beta.34 - 2026-08-03
|
|
694
|
+
|
|
695
|
+
### Classify daemon terminal-result dispositions
|
|
696
|
+
|
|
697
|
+
- Replace the ambiguous Worker `unmatched_results` interpretation with an explicit `terminal_results` disposition matrix. Successful transient and durable settlements are counted separately from owner-missing results that are acknowledged to terminate normal at-least-once replay and stale-connection results that are rejected without acknowledgement.
|
|
698
|
+
- Retain `calls.unmatched_results` as a compatibility aggregate of `owner_missing_acknowledged` and `stale_connection_rejected`, and mark that scope machine-readably. Operators no longer need to treat a harmless duplicate after cancellation, timeout, reconnect, deployment, or lost acknowledgement as evidence of a connection-identity defect.
|
|
699
|
+
- Centralize the settlement-to-acknowledgement decision and test all four outcomes. A deployed Worker integration regression completes a real call, consumes its acknowledgement, resends the identical result, proves a second acknowledgement, and verifies that only `owner_missing_acknowledged` increases.
|
|
700
|
+
- Update architecture and operations contracts so stale ownership is diagnosed from `stale_connection_rejected`, while sustained owner-missing growth is investigated as acknowledgement loss or bounded lifecycle overlap rather than automatically classified as protocol corruption.
|
|
701
|
+
|
|
702
|
+
## 3.0.0-beta.33 - 2026-08-03
|
|
703
|
+
|
|
704
|
+
### Clarify prerelease rollback evidence
|
|
705
|
+
|
|
706
|
+
- Upgrade prerelease activation records to schema 2 and replace the ambiguous `previous` field with `global_package_rollback_baseline`. The field now states exactly what activation records retain: the globally installed npm package version and entrypoint available for operator-directed disaster recovery, not the service runtime active immediately before activation.
|
|
707
|
+
- Keep schema 1 activation records readable without rewriting historical evidence. Legacy `previous` values are normalized in memory to the schema 2 field, while mixed-version fields, duplicate baseline fields, relative entrypoints, and malformed baselines fail closed.
|
|
708
|
+
- Keep transaction-scoped service recovery separate. `runtime-activation` continues to capture and verify the actual pre-handoff service version and entrypoint during activation; the persistent activation record no longer invites those two recovery concepts to be conflated.
|
|
709
|
+
- Make both local-candidate and published-prerelease writers consume the shared activation schema constant, add disk-level migration and rejection regressions, and enforce the field distinction in architecture and release documentation gates.
|
|
710
|
+
|
|
711
|
+
## 3.0.0-beta.32 - 2026-08-03
|
|
712
|
+
|
|
713
|
+
### Typed file mutation failures
|
|
714
|
+
|
|
715
|
+
- Replace ordinary exceptions in workspace file, patch, and remote path-boundary operations with the existing stable `BridgeError` contract. `write_file`, `edit_file`, and `apply_patch` now preserve actionable error codes and bounded `details.reason` values through local execution, stdio MCP, daemon WebSocket transport, Worker adaptation, and public MCP tool results instead of collapsing expected state failures to `execution_failed`.
|
|
716
|
+
- Classify create-only collisions, optimistic SHA-256 mismatches, targets that appear during commit, unsupported target types, symbolic-link destinations, duplicate patch paths, and stale or ambiguous patch contexts as `conflict`. Missing edit text is `not_found`; malformed patch envelopes, invalid text/image inputs, and invalid line ranges are `invalid_request`; bounded read/write violations are `limit_exceeded`; hard-link read denial is `permission_denied`; workspace escape is `path_boundary`.
|
|
717
|
+
- Keep sensitive and irrecoverable failures fail-closed. Error details contain only bounded reason tokens, counts, limits, and hunk/line indexes, never paths, file contents, old/new text, or expected/actual hashes. Incomplete staged-write cleanup and incomplete patch rollback remain non-exposed `internal_error` results while retaining their causes locally.
|
|
718
|
+
- Add direct runtime, atomic fault-injection, Worker-adapter, and live stdio regressions proving stable code/reason propagation, no overwrite after create-only or stale-precondition failure, transactional rollback, and absence of absolute paths in public error objects. Update tool discovery descriptions, generated reference, architecture, testing, and client guidance.
|
|
719
|
+
|
|
720
|
+
## 3.0.0-beta.31 - 2026-08-03
|
|
721
|
+
|
|
722
|
+
### Preserve host delivery margin for synchronous tools
|
|
723
|
+
|
|
724
|
+
- Reduce the remote synchronous foreground ceiling from 85 to 60 seconds. The previous 85-second execution allowance plus five seconds of Worker settlement could consume roughly 90 seconds before terminal handling completed; live evidence showed a temporally aligned 83.5-second command complete locally after the ChatGPT task had already ended with a message-send timeout. Defaults remain 30 or 60 seconds, owner-local commands retain their local budget, and longer remote work continues through process sessions or managed jobs.
|
|
725
|
+
- Separate the daemon execution deadline from the Worker settlement deadline. A second review found that the first beta.31 candidate sent the 65-second settlement deadline to the daemon as its local execution deadline, so the claimed five-second margin was not real for tools governed only by the relay envelope. The daemon now receives at most 60 seconds, while the Worker records a settlement deadline five seconds later for result acceptance, persistence, acknowledgement, and terminal settlement. Admission and transport latency may consume part of that internal interval, so it is not an external host guarantee.
|
|
726
|
+
- Replace the ambiguous zero-recipient counter with explicit Worker-internal transport metrics for terminal publication, live internal-subscriber sends, storage responses, and the completion-between-lookup-and-subscription race. These metrics do not assert public SSE consumption or host receipt; `server_info.tool_delivery.host_terminal_receipt_observable=false` makes that boundary machine-readable without logging call IDs, arguments, or results.
|
|
727
|
+
- Reduce the unactivated legacy-stream retention ceiling from the obsolete 730-second local-envelope-derived value to 185 seconds: the 65-second maximum hosted settlement deadline plus the 120-second terminal replay window. Activated calls still extend their records across the actual operation/reconnect state machine; abandoned prepare records no longer occupy the bounded 64-stream capacity for more than the hosted contract requires.
|
|
728
|
+
- Update the executable tool catalog, client guidance, generated reference, timeout regressions, and upgrade documentation. Existing MCP hosts may retain an older cached tool schema until they rediscover or reconnect; Worker validation remains authoritative and rejects oversized requests before dispatch.
|
|
729
|
+
|
|
730
|
+
## 3.0.0-beta.30 - 2026-08-02
|
|
731
|
+
|
|
732
|
+
### Resumable MCP delivery under transient interruption
|
|
733
|
+
|
|
734
|
+
- Make the advertised and executed foreground timeout contract match the enforced Worker ceiling: configurable foreground tools now declare a maximum of 85 seconds and default to 30 or 60 seconds. Relay execution uses those same defaults when the argument is omitted, and a registered-command manifest cannot silently extend a relay call beyond 85 seconds; owner-local registered commands may retain their explicit local manifest budget. Longer remote work must use process sessions or managed jobs, eliminating host-generated or locally inherited 120–600 second work that outlived its Worker response.
|
|
735
|
+
- Stop legacy recovery subscribers from replacing one another. Up to four concurrent subscribers may observe the same persisted terminal result; excess subscribers receive a bounded retryable response, and terminal fan-out closes every subscriber cleanly.
|
|
736
|
+
- Extend internal terminal-subscription recovery from a sub-second retry burst to a bounded multi-second backoff. Cancelling a public SSE reader now releases only its internal delivery subscription while the durable legacy operation remains resumable through `Last-Event-ID`. DPoP-protected prepare retries use one outer-Worker-generated opaque retry ID: the first attempt atomically consumes the proof and binds it, and only the same internal request may reuse that proof for at most four authorization attempts; another request remains a replay failure.
|
|
737
|
+
- Make repeated signed-session legacy `tools/call` delivery idempotent throughout the bounded two-minute recovery window. OAuth token, signed MCP session, typed request ID, tool name, and a canonical SHA-256 argument fingerprint bind the stream before daemon dispatch; an identical retry reattaches to the active or terminal stream, while changed arguments are rejected instead of duplicating side effects. Sessionless legacy POSTs never retry an ambiguous prepare.
|
|
738
|
+
- Add regressions for concurrent subscriber fan-out and limits, delivery-subscription cleanup, canonical request fingerprints, persisted retry identity, the unified foreground timeout catalog, and effective relay timeout alignment for shell, direct-process, and registered-command execution. Clarify that a macOS sleep interval may legitimately surface as an event-loop-stall warning without implying daemon failure.
|
|
739
|
+
|
|
740
|
+
## 3.0.0-beta.29 - 2026-08-01
|
|
741
|
+
|
|
742
|
+
### Bounded security-audit throughput and retention
|
|
743
|
+
|
|
744
|
+
- Reuse one verified security-audit state inside the dedicated audit worker instead of rereading, reparsing, and rehashing the complete retained chain for every batch. The cache is invalidated by file identity, size, modification time, or metadata-change time, so another process or external alteration still forces full verification before a write.
|
|
745
|
+
- Bound retention by both 4,096 events and 4 MiB. Oversized-but-valid event histories now evict the oldest events, advance the chain anchor, and remain verifiable instead of permanently failing before the advertised event limit. Runtime diagnostics expose the byte ceiling explicitly.
|
|
746
|
+
- Fix an owner-state-lock race where a contender observed `EEXIST` just before the holder released the lock and then misclassified the now-missing file as malformed. Missing, invalid, and valid-owner states are now distinct, preserving fail-closed handling for actual corruption while allowing normal retry.
|
|
747
|
+
- Add regressions for cached-state tamper invalidation, byte-driven retention, cross-worker sequence preservation, and the lock release/acquire window. Keep audit state construction in a focused module rather than raising the existing architecture budget.
|
|
748
|
+
- Mark Worker observability counters as current-isolate metrics and state explicitly that durable calls can cross isolate lifetimes, so completed/failed counts are not misread as algebraically closed process-lifetime totals.
|
|
749
|
+
|
|
750
|
+
## 3.0.0-beta.28 - 2026-07-31
|
|
751
|
+
|
|
752
|
+
### Verified service restart semantics
|
|
753
|
+
|
|
754
|
+
- Fix `service restart` returning `already_running` without invoking launchd, systemd, or Task Scheduler. Start remains idempotent, while restart now always reaches the provider when the committed service is active.
|
|
755
|
+
- Require an active-service restart to return explicit provider restart evidence and to converge on a replacement daemon PID before reporting success. A still-ready pre-restart daemon is now `daemon_replacement_not_observed`, not successful convergence.
|
|
756
|
+
- Extract service daemon convergence into a focused module and add regressions for provider invocation, old-PID rejection, replacement readiness, and missing restart evidence.
|
|
757
|
+
|
|
758
|
+
## 3.0.0-beta.27 - 2026-07-31
|
|
759
|
+
|
|
760
|
+
### Control-plane resilience under host I/O pressure
|
|
761
|
+
|
|
762
|
+
- Remove synchronous process-table inspection from foreground timeout and cancellation paths. Process-group identity capture, post-`SIGTERM` refresh, and pre-`SIGKILL` PID/start-time revalidation now use bounded asynchronous `ps` execution with a fixed minimal `PATH`/locale environment, while ambiguous ownership still fails closed. Windows taskkill fallback is idempotent across an `error`/nonzero-`exit` race.
|
|
763
|
+
- Preserve process ownership after a tool result has timed out or been cancelled. Runtime status now distinguishes active calls from draining calls, terminating processes, and pending escalation checks instead of implying that a returned timeout means all operating-system work has stopped.
|
|
764
|
+
- Extend `diagnose_runtime` with privacy-safe local lifecycle, call-capacity, draining-process, execution-guardrail, relay-heartbeat, and audit-health snapshots so remote operators can observe the repaired control plane; local stdio `server_info` retains the equivalent detailed runtime view.
|
|
765
|
+
- Reserve control-plane capacity at both relay layers: two of thirty-two Worker pending-call slots and two of sixteen local runtime slots are restricted to bounded diagnosis/recovery tools. Ordinary transient and durable-stream work share the same admission contract and cannot consume those slots.
|
|
766
|
+
- Split relay heartbeat policy from WebSocket transport. The daemon measures local event-loop lag, reports bounded `runtime.event_loop.stall` warnings, sends a fresh heartbeat, and grants a short recovery interval before classifying remote silence. A locally stalled daemon no longer immediately destroys a healthy relay socket and amplifies one slow operation into a reconnect outage.
|
|
767
|
+
- Move security-audit startup verification, hash-chain updates, atomic replacement, and `fsync` into a dedicated Worker thread; construction now reports `audit_initializing` without synchronously reading persistent state, and stale post-failure Worker events cannot overwrite the original failure class. Tool results no longer wait for audit disk persistence; events are privacy-projected before transfer, batched, queue-bounded, cross-process serialized, and exposed through health/queue/drop diagnostics. Persistent audit failures emit rate-limited warnings with suppressed-count reporting rather than one warning per tool call.
|
|
768
|
+
- Reduce audit Worker message amplification by acknowledging each persisted batch once instead of sending one duplicate snapshot per record. The existing bounded SHA-256 chain, owner-only state, tamper detection, and prohibition on command text, paths, values, and results remain intact.
|
|
769
|
+
- Add the fast-plan `control-plane-resilience:test` gate and deterministic regressions for local event-loop stalls versus genuine relay silence, capture-before-signal ordering, asynchronous process-tree supervision, draining-process visibility, end-to-end Worker/local reserved control capacity, non-blocking audit dispatch, audit warning suppression, batch persistence, and privacy-safe audit projection.
|
|
770
|
+
- Bound headless OAuth browser startup, DevTools HTTP discovery, WebSocket connection, and individual CDP commands. A wedged Chrome process under extreme host pressure now fails with bounded diagnostics instead of hanging release verification indefinitely.
|
|
771
|
+
- Refactor heartbeat, call-capacity, process signaling/supervision/snapshotting, and audit dispatch/storage/warnings into focused modules. Architecture line budgets and import-direction checks were retained rather than relaxed.
|
|
772
|
+
|
|
773
|
+
## 3.0.0-beta.26 - 2026-07-29
|
|
774
|
+
|
|
775
|
+
### Explicit GitHub publication ownership
|
|
776
|
+
|
|
777
|
+
- Require GitHub tag, Release, prerelease, and backfill writes to present TTY-backed stdin/stdout/stderr plus the explicit `--owner-terminal-confirm` flag. Background MCP calls, managed jobs, CI, redirected sessions, and ordinary automation fail before repository fetch, verification, tag creation, or remote mutation. This is an anti-accident workflow boundary, not cryptographic human-presence proof against arbitrary same-user code.
|
|
778
|
+
- Serialize GitHub publication through an owner-only process-identity lock at the common Git state path, so the main checkout and linked worktrees share one owner. A second publication attempt fails while the first process is alive, and a stale lock is reclaimed only after PID/start-time verification.
|
|
779
|
+
- Convert release-script failures to exceptions so the publication lock is released on every ordinary failure path instead of being abandoned by `process.exit()`.
|
|
780
|
+
- Add deterministic guard, non-interactive rejection, linked-worktree path, live contention, stale-owner reclamation, callback-failure release, package-manifest, architecture, and critical-coverage tests. npm publication remains a separate owner operation and is not attempted by this change.
|
|
781
|
+
- Label top-level local self-test phases so a transient process, service, shell, or Worker-source failure identifies its causal test boundary instead of surfacing only a low-level timeout stack.
|
|
782
|
+
- Keep the fail-closed common-Git-directory probe bounded but raise its local metadata deadline from 5 to 30 seconds, and give self-test process/CLI success fixtures scheduler-tolerant 30–60 second budgets; explicit timeout/cancellation tests retain their short deadlines.
|
|
783
|
+
- Make the managed-job descendant cleanup test wait for the fixture PID checkpoint before judging timeout cleanup, and use bounded scheduler-tolerant observation windows; this preserves the production timeout/tree-kill contract while eliminating an ENOENT race.
|
|
784
|
+
- Give `diagnose_runtime` direct-process and shell health probes an explicit 30-second diagnostic budget, separate from user command deadlines and from the short timeout/cancellation fixtures, so temporary scheduler starvation is reported only after a meaningful bounded observation window.
|
|
785
|
+
- Remove the hidden 10-second Git repository-root subdeadline beneath 30-60 second Git operations: read-only `rev-parse --show-toplevel` metadata detection and runtime Git success fixtures now use a bounded 30-second budget, while command failure remains fail-closed.
|
|
786
|
+
- Make the shell process-tree cleanup fixture observe a descendant-PID readiness checkpoint before its timeout path, with bounded 25-30 second coverage-tolerant windows; the separate 50 ms timeout fixture still verifies immediate timeout classification.
|
|
787
|
+
- Give the direct-argv isolation success fixture a named 30-second process budget so V8 coverage and host scheduling cannot turn an argv/shell-boundary assertion into an unrelated 10-second timeout; dedicated timeout tests remain unchanged.
|
|
788
|
+
- Replace the maintenance-lock test's 1.2-second time-based holder with a parent-controlled stdin handshake. The child holds the lock until assertions finish and releases on explicit `release` or pipe closure, so scheduler delay cannot erase the contention state under test.
|
|
789
|
+
- Prevent V8 coverage from recursively instrumenting process-lock helper processes. Node propagates `NODE_V8_COVERAGE` to children even when the variable is deleted, so the fixture spawn boundary now sets it explicitly to an empty value and verifies the helpers remain uninstrumented; only the top-level test contributes coverage.
|
|
790
|
+
- Keep the atomic-exclusive process test cross-process but use four simultaneous contenders instead of twelve. Four independently spawned processes are sufficient to prove the single-winner invariant, while avoiding a 3x Node cold-start amplification that can dominate the test under unrelated host saturation.
|
|
791
|
+
- Apply the same explicit coverage isolation to daemon-takeover fixtures and give readiness plus successful stop/takeover paths a named 30-second budget. The 100 ms foreground-owner refusal and 20 ms force-escalation trigger remain intentionally short and independently asserted.
|
|
792
|
+
- Keep managed-job runner coverage intact while explicitly disabling profiler inheritance for trivial marker-writing business steps. Those success fixtures now use a named 120-second step budget; the independent timeout, cancellation, and process-tree tests keep their short semantic deadlines.
|
|
793
|
+
- Apply the same named 120-second success-step budget across managed-job approval markers, resource validation/redaction, bounded-output, discard-output, and cleanup/recovery markers. The managed-job process-tree fixture uses a 180-second timeout and a 150-second descendant-readiness window so the resistant descendant exists before timeout/tree-kill is judged; cancellation behavior remains independently asserted; the aggregate-output fixture uses four steps and a 600-second observer, exceeding its legal plan upper bound without multiplying cold starts.
|
|
794
|
+
- Raise the ordinary managed-job test observer to 480 seconds so it exceeds the longest three-phase 3×120-second success/cleanup plan plus startup margin. This changes only test observation; production timeout semantics, the 180-second managed-job tree timeout, and cancellation behavior remain independently tested.
|
|
795
|
+
- Give managed-job CLI list/inspect/submit/read success and rejection fixtures a separate 120-second subprocess budget and structured status/signal/error diagnostics. Their purpose is CLI/state validation, not a 60-second latency contract; production job step deadlines and explicit timeout tests remain unchanged.
|
|
796
|
+
- Prevent those local-self managed-job CLI subprocesses from inheriting V8 coverage. The top-level local-self remains instrumented, while dedicated CLI-entrypoint and managed-job fixtures provide the relevant module evidence without recursively profiling each detached CLI probe.
|
|
797
|
+
- Treat a POSIX zombie child as exited-but-awaiting-event-drain instead of timing it out. Managed-job settlement now re-reads the real exit code during the bounded fallback, preventing scheduler-starved `exit`/`close` delivery from converting a completed cleanup step into a false timeout.
|
|
798
|
+
- Close a managed-job launch/recovery race: the parent now publishes an owner-only provisional PID plus one-time launch token immediately after spawn, and the runner must verify that claim before executing or atomically upgrading it to an exact start-time identity. A queued job can no longer be misclassified as interrupted merely because V8 startup exceeds the ten-second recovery grace period; conflicting claims fail closed and terminate the unowned child.
|
|
799
|
+
- Give browser-broker fixture HTTP, WebSocket open/message/close, rejection, handshake, and state-convergence observations a named 30-second scheduler-tolerant budget. Product request deadlines remain unchanged, including the one-second timeout regression and the normalized two/four-second browser operation parameters.
|
|
800
|
+
|
|
801
|
+
## 3.0.0-beta.25 - 2026-07-29
|
|
802
|
+
|
|
803
|
+
### MCP 2026-07-28 dual-era protocol architecture
|
|
804
|
+
|
|
805
|
+
- Make MCP `2026-07-28` the primary protocol while retaining `2025-11-25` behind an explicit legacy adapter. Modern requests are stateless, carry protocol version and client capabilities in every request `_meta`, use `server/discover`, never mint `Mcp-Session-Id`, and do not enter the legacy resumable-SSE store.
|
|
806
|
+
- Split Worker and stdio dispatch into modern and legacy paths. Per-request metadata takes precedence over method names when selecting the era, so a modern `initialize` request is rejected with HTTP 404 / JSON-RPC `-32601` instead of accidentally entering the legacy handshake.
|
|
807
|
+
- Implement modern Streamable HTTP mirrored-header validation for `MCP-Protocol-Version`, `Mcp-Method`, `Mcp-Name`, and schema-declared `Mcp-Param-*` values, including Base64 sentinel decoding, case-sensitive value comparison, required dual-media `Accept`, and `-32020 HeaderMismatch` precedence over unsupported-version handling.
|
|
808
|
+
- Add modern `subscriptions/listen` acknowledgment, subscription-ID correlation, strict notification-filter validation, and graceful completion. The server advertises no dynamic list notifications and therefore acknowledges only the supported subset rather than fabricating capability.
|
|
809
|
+
- Separate modern request-scoped streams from legacy durable recovery. Modern response streams have no event IDs or `Last-Event-ID` replay. The outer Worker makes one direct Durable Object request, forwards bounded SSE heartbeats, and uses a stream-scoped private cancellation control when the public response closes; it never creates a prepare/subscribe descriptor or retains a cross-event terminal Promise. Legacy session-bound GET recovery remains compatibility-only.
|
|
810
|
+
- Remove token-wide modern JSON-RPC request identity. Two clients sharing one OAuth token may concurrently reuse the same request ID without collision; request IDs remain scoped to the individual modern request/stream, while legacy and stdio cancellation retain their transport-appropriate indexes.
|
|
811
|
+
|
|
812
|
+
### Capability routing and context efficiency
|
|
813
|
+
|
|
814
|
+
- Add bounded set-level execution routing to `resolve_task_capabilities`. It ranks compatible route bundles—registered commands, direct Bash/argv, interactive processes, durable jobs, workspace/Git operations, browser, applications, protected resources, and diagnostics—rather than pretending every tool is an independent island. The output includes a primary route, alternatives, ambiguity, fallback routes, and failure-aware guidance. It is advisory only: `exec_command` remains the convenient general escape hatch whenever the effective policy allows shell execution.
|
|
815
|
+
- Fix an account-authority privacy gap in capability discovery. Application inventory and browser metadata now use the authenticated account/daemon policy intersection rather than the daemon's global ceiling; a reviewer connected to a full daemon can no longer learn or receive recommendations for application, browser, shell, or write surfaces outside the role-visible catalog.
|
|
816
|
+
- Add conditional capability-context reuse. A caller may return `refresh.fingerprint` as `known_refresh_fingerprint`; when the target, scope, instruction provenance/precedence, skills, and complete registered-command definitions are unchanged, the resolver still recomputes task-specific matches and routing but omits the repeated static instruction payload. Calls that omit the fingerprint retain the previous complete response.
|
|
817
|
+
- Rewrite the highest-collision tool descriptions with explicit positive selection boundaries: registered project command versus direct argv versus Bash composition; raw DOM source versus semantic browser inspection; tab inventory versus tab mutation; repository overview versus live relay/authority status; context inventory versus task-specific routing.
|
|
818
|
+
- Extend privacy-safe routing telemetry with only the primary route, ambiguity class, and score gap. Raw task text remains absent and the existing runtime-keyed HMAC fingerprint remains the only task correlation value.
|
|
819
|
+
- Add bilingual routing regression cases and critical coverage for shell, registered commands, interactive processes, managed jobs, Git, workspace edits, browser, applications, diagnostics, and protected resources. Package checks require the new routing module. Route envelopes are schema-versioned and state that scores are relative ranks, not probabilities or cross-version metrics.
|
|
820
|
+
- Keep per-task routing lightweight: it reads frozen name/title/description records from the policy-visible catalog instead of deep-cloning all 51 input schemas on every resolver call. Architecture tests reject reintroducing the full-catalog clone.
|
|
821
|
+
|
|
822
|
+
### Protocol and schema correctness
|
|
823
|
+
|
|
824
|
+
- Require `resultType` and server identity metadata on every modern successful result. Preserve `structuredContent` for every JSON value, including arrays, strings, numbers, booleans, and `null`, instead of silently discarding non-object values.
|
|
825
|
+
- Add a bounded shared JSON Schema 2020-12 argument validator. Worker dispatch and the local runtime enforce the same catalog constraints before side effects; unsupported dialects or keywords, including automatic network `$ref` dereference, fail at catalog compilation instead of being ignored.
|
|
826
|
+
- Bound schema depth, node count, validation issue count, regular-expression length, and total runtime validation work. Array items and every own object property consume the same budget, so a high-cardinality object cannot force an unbounded `Object.keys()` allocation or traversal. Validation errors expose only instance paths, keywords, and constraint messages—never argument values.
|
|
827
|
+
- Move one shared role-aware tool-call inspection boundary ahead of both modern and legacy dispatch. Missing/hidden tools, non-object arguments, and schema-invalid values return protocol-level `-32602` with `side_effects_started=false`; legacy SSE rejects them before allocating resumable state or contacting the daemon.
|
|
828
|
+
- Validate modern `_meta` key syntax, client capability objects, extension identifiers/settings, progress tokens, log levels, optional client identity/icon URIs, subscription filters, strict HTTP quality values, and header/body version ordering. Open metadata/extension trees share a fixed 4,096-node, 32-level, bounded-key structure budget; resource subscriptions are capped at 256 bounded strings. Header mismatch and unknown-input errors no longer reflect caller-controlled names, URIs, metadata keys, or parameter values.
|
|
829
|
+
- Validate `Origin` on actual `/mcp` requests as required by Streamable HTTP while leaving OAuth navigation semantics unchanged. CORS preflight allows only the fixed protocol headers plus exact catalog-declared `Mcp-Param-*` names, with bounded count/bytes instead of reflecting arbitrary parameter headers.
|
|
830
|
+
- Treat the random private modern stream ID as an internal cancellation capability. The outer Worker strips caller-supplied control headers, the Durable Object handles cancel before OAuth/DPoP replay validation, and the internal cancel request carries no Authorization or DPoP header; closing a DPoP-bound stream therefore cannot fail because its original proof JTI was already consumed.
|
|
831
|
+
|
|
832
|
+
### Conformance and verification
|
|
833
|
+
|
|
834
|
+
- Add protocol-contract, tool-schema, modern stdio, modern Worker, same-ID concurrency, malformed-call non-dispatch, subscription validation, arbitrary structured-content, and request-scoped stream-cancellation coverage while preserving the complete legacy integration suite.
|
|
835
|
+
- Make the process-tree timeout fixture readiness-driven under coverage load. The test starts the real timeout operation, waits within a fixed bound for a valid descendant PID publication, then verifies the timeout result and descendant exit; it no longer assumes Node startup and child creation finish within 200 ms. Add direct valid/invalid/unknown-tool coverage for the Worker catalog validator rather than lowering its 95% function threshold; the module now reaches 100% function coverage.
|
|
836
|
+
- Derive the resistant-descendant escalation assertion from the exported two-second graceful-termination interval and three-second ownership-verification budget, plus a bounded scheduling margin. The former exact five-second assertion could race the final identity probe under release-candidate load even though the forced kill was still pending; production termination timing is unchanged.
|
|
837
|
+
- Make managed-job integration waits distinguish the persisted terminal checkpoint from confirmed private-artifact cleanup. A terminal status with `artifact_cleanup_pending=true` is intentionally recoverable but does not yet prove that runtime resource copies, temporary files, the plan, or PID claim are gone; deterministic boundary assertions and ten repeated integration runs cover the distinction without changing the production two-phase protocol.
|
|
838
|
+
- Add an opt-in driver for the official MCP conformance checkout. It uses a test-only loopback proxy to inject a short-lived test bearer token without weakening production OAuth or adding the alpha conformance package to the project dependency graph. The proxy accepts only its relative `/mcp` endpoint, maps it to the exact configured upstream path, rejects absolute/scheme-relative or alternate same-origin targets, bounds request bodies, settles aborted uploads, and reclaims the complete child process tree on timeout.
|
|
839
|
+
- Pass the official `http-header-validation` scenario. Pass `server-stateless` and `caching` with check-scoped expected-failure entries only for production capabilities the server intentionally does not expose: conformance-only diagnostic tools and absent prompt/resource feature families. Any unrelated failure or stale baseline still fails the run.
|
|
840
|
+
- Advance the exact production Wrangler runtime from `4.114.0` to `4.115.0` and Miniflare from `4.20260722.0` to `4.20260722.1`. The reviewed workerd build remains `1.20260722.1`, so its exact lifecycle-script allowlist does not change. Wrangler now applies bounded `429` retry handling, honors reasonable `Retry-After` values, and exposes `retry_after_ms` in its machine-readable failure record, improving candidate deployment diagnosis without adding an unbounded wait.
|
|
841
|
+
- Make candidate activation compare the pending manifest's promotion-content digest with the current source before tarball verification, npm installation, Worker deployment, or service mutation. A candidate becomes unusable immediately after any packaged-source change instead of remaining internally self-consistent but stale.
|
|
842
|
+
- Add the modern protocol, shared subscriptions, bounded schema validator, role-aware tool input boundary, modern proxy/controller, and candidate-source guard to fast/full behavior and critical coverage gates. The npm package manifest now requires every new shared and Worker protocol module and still excludes tests, generated Worker types, local candidates, logs, and secret-shaped artifacts.
|
|
843
|
+
- Add a first-party `sbom:test` release gate that invokes the pinned npm CLI directly, validates bounded CycloneDX 1.5 JSON, confirms the current package identity and root dependency graph, and rejects local filesystem paths. This avoids ambiguous unscoped helper packages and makes SBOM generation part of candidate verification rather than an operator-only command.
|
|
844
|
+
- Advance the unreleased working version to `3.0.0-beta.25`; immutable beta.24 GitHub artifacts are not reused. No npm package is published by this change.
|
|
845
|
+
|
|
846
|
+
## 3.0.0-beta.24 - 2026-07-28
|
|
847
|
+
|
|
848
|
+
### Candidate activation authentication convergence
|
|
849
|
+
|
|
850
|
+
- Treat a current-version Worker health response and successful upload as necessary but insufficient activation evidence. The exact candidate must also complete device preflight, challenge authentication, and end-to-end relay readiness before service handoff.
|
|
851
|
+
- Recover one explicit candidate device-authentication rejection by redeploying the same Worker exactly once with the already selected device identity. The repair never rotates credentials, never changes the Worker name, and is bounded to three candidate starts with exponential delay.
|
|
852
|
+
- Prevent split-version recovery after a remote transition. If remote preparation has changed or verified the candidate Worker but activation later fails, cleanup installs and starts the compatible candidate service definition instead of reviving an older daemon that cannot authenticate to the current Worker. Failures remain explicit, and cleanup errors are aggregated rather than hidden.
|
|
853
|
+
- Report whether activation used the authentication-repair deployment in structured output. The operator warning contains only the failure class and repair action; it does not expose device identifiers, public keys, Worker endpoints, or credentials.
|
|
854
|
+
- Require persistent-service state, not merely a successful service-manager command. Candidate activation now consumes verified stop/restore evidence on launchd, systemd, and Windows; systemd activating/reloading states retain restoration intent while unknown/maintenance states fail before mutation, and a Windows task that exits successfully without remaining active is reported as `completed_without_persistence`.
|
|
855
|
+
- Bind the machine-global service definition to an owner-only `service-owner.json` record containing the canonical workspace, state root, exact runtime entrypoint, and package version. Installation writes `pending` before provider mutation and commits only after the definition succeeds; ambiguous or partial installation remains pending so start/restart fail closed instead of trusting an obsolete owner.
|
|
856
|
+
- Make daemon readiness a token-protected, monotonic checkpoint in the daemon process lock. A login service is accepted only after the exact service-mode process completes device authentication, relay probe, and `ready_ack`; provider-active samples alone are no longer treated as runtime truth.
|
|
857
|
+
- Serialize every machine-global service mutation with one fixed user-level lock and acquire it before any workspace startup lock. Foreground takeover releases the machine-service lock after service/daemon ownership is established, while activation retains it through the complete persistent handoff; daemon-only service children never re-enter the parent transaction lock.
|
|
858
|
+
- Keep the ordinary profile state root and machine-service control root distinct on every platform. POSIX defaults to `~/.local/state/machine-bridge-mcp`, while the global service lock/owner ledger uses the sibling `machine-bridge-mcp-control`; XDG and Windows APPDATA preserve the same application-versus-control separation. This prevents the standard candidate command from installing its runtime into the control directory and then failing state-schema initialization.
|
|
859
|
+
- Reject a foreground or unverifiable daemon before any launchd/systemd/Task Scheduler mutation. Pre-remote recovery of an older compatible service also requires the same version and entrypoint to reappear as a verified service daemon; post-remote recovery continues forward with the candidate owner/readiness contract.
|
|
860
|
+
- Remove the candidate wrapper's outer hard kill around the activation transaction. Deployment, health, relay, service-manager, and convergence stages retain their own bounded deadlines, while service-manager commands now have an explicit 30-second hard boundary; the wrapper cannot bypass lock release and compensation with an unrelated global timeout.
|
|
861
|
+
- Fail closed before POSIX forced escalation when no process ownership snapshot was captured, and require exact process start-time continuity instead of accepting adjacent-second identities. This favors a diagnosable surviving descendant over signaling a possibly reused process group.
|
|
862
|
+
- Make synchronous helper deadlines real. Process-tree and process-identity probes, delegated sandbox checks, macOS trust-broker commands, candidate activation, published-prerelease installation, and synchronous verification helpers now use `SIGKILL` on `spawnSync` timeout; the Node default `SIGTERM` can otherwise be ignored while the caller remains blocked indefinitely. Trust-broker `ETIMEDOUT` is classified before signal-based signing diagnostics.
|
|
863
|
+
- Bound managed-job and foreground-shell process-tree shutdown under macOS process-table stalls. Darwin ownership capture and revalidation now query only the target process group with `ps -g <PGID>` instead of scanning the complete process table; other full and targeted probes still share one three-second monotonic budget instead of multiplying a three-second timeout by every captured descendant. This prevents an overloaded full-table snapshot from yielding empty fail-closed ownership and leaving an anti-`SIGTERM` descendant alive. If libuv reports `exit` but omits the final `close` event, the runner waits one second for output drain, then destroys residual stream handles and settles through the same terminal path.
|
|
864
|
+
|
|
865
|
+
### Verification
|
|
866
|
+
|
|
867
|
+
- Add fault-injection coverage for service-stop refusal, ambiguous provider results, daemon-lock takeover denial, malformed version/wait/repair inputs, missing lock-release contracts, invalid retry budgets, first-attempt authentication rejection, exactly one same-identity repair deployment, bounded repeated rejection, compatible-service forward recovery, cleanup aggregation, normal foreground-to-service convergence, and cross-platform separation of default profile state from the machine-service control root.
|
|
868
|
+
- Keep the runtime-diagnostics composition test platform-correct: macOS must classify the injected `utun` route as VPN/TUN interception, while Linux and Windows must skip the macOS-only fixed route probe with `unsupported_platform`. Dedicated route tests cover both contracts independently.
|
|
869
|
+
- Canonicalize service-owner workspace, state-root, and entrypoint paths with the native filesystem resolver used by the state layer. This prevents Windows 8.3 short-path aliases such as `RUNNER~1` from diverging from long-path state identity while retaining exact real-file ownership.
|
|
870
|
+
- Remove a service-platform test lifecycle race: create owner-test directories synchronously before canonicalization instead of starting unawaited `mkdir()` promises that could race both owner creation and teardown. Temporary-tree cleanup also uses a fixed retry budget and still fails closed after that budget.
|
|
871
|
+
- Make the Worker integration daemon-message waiter protocol-aware: while waiting for a subsequent `tool_call` or `cancel_call`, it may skip an asynchronously interleaved `tool_result_ack`; handshake, error, and every other unexpected message remain strict failures.
|
|
872
|
+
- Track every Worker integration HTTP request from creation through settlement. Deferred requests receive an immediate rejection observer, successful completion requires the request set to drain to zero, and failure cleanup closes Wrangler before a bounded all-settled drain; a late connection refusal can no longer bypass the test error path as a process-level unhandled rejection.
|
|
873
|
+
- Add deterministic child-settlement tests, process-snapshot budget accounting, repeated managed-job timeout/descendant termination runs, and an explicit assertion that the detached runner exits after terminal persistence.
|
|
874
|
+
- Reject non-numeric, fractional, zero, negative, non-finite, or over-limit remote `timeout_seconds` values before daemon dispatch; generated schemas and runtime enforcement now share the exact 1–85 second integer contract.
|
|
875
|
+
- Add strict checked-JavaScript contracts for child settlement, process-tree ownership, and system-route classification, plus a dedicated child-settlement coverage threshold of 100% functions and 85% branches.
|
|
876
|
+
- Add `runtime-activation.mjs` to the critical coverage gate. The module reaches 100% function coverage and 80% branch coverage in the current suite.
|
|
877
|
+
- Block beta.23 from acceptance, publication, or promotion because owner-machine activation exposed the authentication-convergence and split-version recovery defects after the Worker had already advanced.
|
|
878
|
+
|
|
879
|
+
## 3.0.0-beta.23 - 2026-07-28
|
|
880
|
+
|
|
881
|
+
### Workflow closeout continuity
|
|
882
|
+
|
|
883
|
+
- Correct the remote foreground timeout contract instead of silently shortening a caller-declared 120–600 second operation. The Worker-specific catalog now advertises an 85-second maximum while preserving 30- or 60-second tool defaults for configurable foreground process, shell, browser, and application tools. A larger request is rejected before daemon dispatch with `side_effects_started=false`, so a mutation cannot complete locally and then appear to fail only when validation loses its response.
|
|
884
|
+
- Direct long work to process sessions or managed jobs. Initialization instructions now require mutation and validation to be independently terminal, and describe a bounded output/status-file fallback for hosts that omit durable tools.
|
|
885
|
+
- Add a fixed macOS default-route diagnostic. `diagnose_runtime` and `doctor` report only a coarse `tunnel-or-vpn`, `physical-or-other`, `loopback`, or `other` route class plus an interception boolean; they never return interface names, addresses, DNS answers, proxy endpoints, or credentials. This distinguishes application proxy selection from an operating-system VPN/TUN that Machine Bridge cannot repair.
|
|
886
|
+
- Preserve architecture limits by extracting route inspection into its own boundary module, then add line budgets and critical coverage thresholds for the new route module and the Worker timeout/catalog projection.
|
|
887
|
+
|
|
888
|
+
### Verification
|
|
889
|
+
|
|
890
|
+
- Add direct timeout-unit tests and a real Wrangler integration proving an over-limit request produces no daemon `tool_call`. Add macOS-route success, unsupported-platform, and fixed-command failure coverage. Refresh architecture, operations, logging, threat-model, client, testing, upgrading, and audit contracts.
|
|
891
|
+
- Refresh the exact development-only pins for `@types/node`, ESLint, and `globals` to their current patch releases; the production dependency graph is unchanged and `npm audit` reports zero known vulnerabilities.
|
|
892
|
+
|
|
893
|
+
## 3.0.0-beta.22 - 2026-07-28
|
|
894
|
+
|
|
895
|
+
### ChatGPT call continuity and terminal delivery
|
|
896
|
+
|
|
897
|
+
- Add an explicit daemon-result acknowledgement. The local runtime retains every terminal result after WebSocket queueing, replays unacknowledged results after reconnect and on heartbeat, and removes them only after the Worker confirms that the generation-guarded terminal transaction committed. This closes the loss window between local `send()` acceptance and Durable Object persistence that could leave a completed local command as a ghost Worker call.
|
|
898
|
+
- Make durable settlement fail closed. A terminal-storage exception is observable and retryable instead of being reported as a completed call; stale connection generations remain unacknowledged, while duplicate results for an already terminal call are acknowledged idempotently so replay converges.
|
|
899
|
+
- Stop treating one tool deadline as proof that the complete daemon socket is dead. Tool timeout now cancels only that call; the independent 90-second daemon-liveness alarm remains the sole connection-invalidating authority.
|
|
900
|
+
- Bound remote foreground execution to 85 seconds plus five seconds of relay overhead, below the observed hosted-client request ceiling. The local process APIs retain their 600-second schema range, but work expected to exceed the interactive budget must use process sessions or managed jobs rather than one foreground ChatGPT call.
|
|
901
|
+
- Tail-trim background daemon logs every 15 minutes as well as before startup, reusing the existing owner-only, no-follow, single-link, schema-checked, UTF-8 line-safe maintenance path.
|
|
902
|
+
|
|
903
|
+
### Verification
|
|
904
|
+
|
|
905
|
+
- Add acknowledgement-loss/replay, persistent-terminal-write failure, stale generation, hosted-client deadline, runtime log-maintenance, and real Wrangler acknowledgement coverage. Type checking, lint, architecture, privacy, structured logging, security properties, SARIF, critical coverage, local self-test, Worker infrastructure, and Worker OAuth/MCP integration pass.
|
|
906
|
+
|
|
907
|
+
## 3.0.0-beta.21 - 2026-07-27
|
|
908
|
+
|
|
909
|
+
### Relay continuity and stable MCP catalog
|
|
910
|
+
|
|
911
|
+
- Keep `tools/list` stable for an authenticated account role instead of withdrawing almost every tool whenever the local relay is briefly unavailable. The Worker still fails every execution closed against the live daemon capability ceiling, and `server_info` now distinguishes the stable advertised catalog from the currently effective daemon/account intersection.
|
|
912
|
+
- Persist streamed daemon-call ownership, request correlation, operation deadlines, reconnect deadlines, and result transformation metadata in Durable Object storage. A hibernated or restarted Worker can recover the active call, a verified same-instance daemon can reclaim it, and a per-WebSocket connection generation prevents stale close events or delayed results from mutating the rebound call. Active-record expiry advances monotonically across repeated detach/rebind cycles instead of being capped by the original single-reconnect window.
|
|
913
|
+
- Make Durable Object alarms the sole deadline owner for persisted streamed calls while retaining the existing Promise/timer path for bounded JSON-only calls. A FIFO admission gate computes one combined 32-call ceiling across both paths. Cancellation, send failure, operation timeout, reconnect-grace expiry, daemon replacement, and successful completion all converge through one guarded terminal write.
|
|
914
|
+
- Classify Worker-requested transport and liveness invalidation as retryable relay recovery instead of a permanent protocol mismatch. The daemon now terminates only the affected socket, preserves ordinary disconnect cleanup, and reconnects automatically; Worker transient invalidation uses WebSocket 1012, while unknown protocol messages, authentication failure, and identity/version mismatch remain fatal. Close-only delivery is also classified from bounded reasons so loss of the preceding error frame cannot restart the daemon. A failed daemon `hello` send and a readiness-probe result lost to an ending relay generation are likewise transport races, not authentication or protocol violations.
|
|
915
|
+
- Add red-green persistence, stale-generation, exactly-once, stable-catalog, disconnected-execution, reconnect, cancellation, timeout, transient Worker-error/close-only recovery, and real Wrangler OAuth/MCP integration coverage.
|
|
916
|
+
- Repair POSIX process-tree escalation after workflow-level repeated full verification exposed a surviving anti-`SIGTERM` descendant. Ownership is refreshed immediately after graceful termination, and escalation falls back to targeted PID/start-time/PGID checks when a full process-table snapshot is unavailable under load; PID reuse still fails closed.
|
|
917
|
+
- Extend post-deployment Worker health convergence for edge propagation, and treat an already recorded current deployment fingerprint as verification-only unless `--force-worker` is explicitly supplied. Persistent candidate activation now compensates an early failure by restarting a service that was active before the transaction, after candidate and lock cleanup; restoration failures remain aggregated with the primary failure.
|
|
918
|
+
|
|
919
|
+
### Audit and documentation
|
|
920
|
+
|
|
921
|
+
- Re-audit the relay lifecycle, tool-advertisement contract, pending-call accounting, storage validation, state-machine boundaries, privacy-safe diagnostics, and obsolete event-settlement code. Synchronize architecture, operations, logging, testing, security, privacy, upgrading, and audit documentation with the implemented continuity model and its residual failure boundaries.
|
|
922
|
+
|
|
923
|
+
## 3.0.0-beta.20 - 2026-07-26
|
|
924
|
+
|
|
925
|
+
### Fixed
|
|
926
|
+
|
|
927
|
+
- Rewrite the bounded Worker error-cause traversal with an explicit object type guard and `WeakSet<object>` cycle tracking. This preserves the eight-level/cycle-safe classification behavior while eliminating the CodeQL `js/comparison-between-incompatible-types` finding; the existing cyclic-cause regression test continues to enforce non-duplication.
|
|
928
|
+
|
|
929
|
+
## 3.0.0-beta.19 - 2026-07-26
|
|
930
|
+
|
|
931
|
+
### Fixed
|
|
932
|
+
|
|
933
|
+
- Restore the documented `account revoke-client CLIENT_ID` CLI command. The action was implemented end to end, but its positional-argument limit was omitted, so every valid client ID was rejected as an extra positional argument before the signed administration request could be sent. Add direct parser regression coverage for both `account clients` and `account revoke-client`.
|
|
934
|
+
|
|
935
|
+
## 3.0.0-beta.18 - 2026-07-26
|
|
936
|
+
|
|
937
|
+
### Fixed
|
|
938
|
+
|
|
939
|
+
- Prevent intermittent hosted-client account loss during refresh-token rotation. A consumed refresh token may now recover at most two same-client, same-resource, same-scope, same-DPoP retries inside a 30-second concurrency window. Both retries reproduce the original deployment-keyed HMAC replacement pair without creating another credential branch or extending expiration; retries beyond that bound return `temporarily_unavailable`, while replay after the window still revokes the complete family. Schema-2 refresh state migrates in place to schema 3.
|
|
940
|
+
- Normalize unexpected outer-Worker failures to a structured retryable `502 worker_gateway_error` instead of allowing `scriptThrewException`/Cloudflare 1101 to surface as a generic account connection failure. Logged error classes contain only error names/codes, never exception messages.
|
|
941
|
+
- Retry an internal terminal WebSocket subscription with bounded delays after transport closure or retryable 429/5xx responses. Normal streamed calls retain the fixed two-request Durable Object path; failure recovery is capped at three subscription attempts.
|
|
942
|
+
- Stop reading request bodies immediately after a declared or observed size violation instead of draining attacker-controlled bytes. Permission and I/O failures during write-path and workspace traversal checks now propagate rather than being misclassified as missing files.
|
|
943
|
+
- Make partial application and skill discovery explicit through bounded path-projected warnings and coarse error classes. Optional `session_bootstrap` failure remains non-fatal but is now visible in Worker observability.
|
|
944
|
+
- Bound account-administration responses to one MiB, cancel oversized bodies, and require successful replies to be JSON objects. Generated SSH key registration now attempts both cleanup targets and reports incomplete rollback instead of silently leaving an unregistered private key.
|
|
945
|
+
- Add a fixed browser-extension error boundary, remove raw debugger details from successful fallback results, and enforce the 32-operation concurrency ceiling independently inside the extension. Error-cause inspection is cycle-aware and capped at eight levels.
|
|
946
|
+
|
|
947
|
+
### Quota and deployment hardening
|
|
948
|
+
|
|
949
|
+
- Serve all public discovery metadata and unknown-path 404 responses in the outer Worker. Only an exact stateful route-and-method allowlist can reach the rate limiter and Durable Object; invalid methods are rejected at the stateless edge.
|
|
950
|
+
- Add a Cloudflare Rate Limiting binding before Durable Object dispatch. Binding failure is fail-open because it is a quota guard rather than an authorization boundary; OAuth, session, and role checks remain inside the Durable Object.
|
|
951
|
+
- Coalesce Durable Object alarms: an already scheduled earlier alarm is reused instead of being rewritten on every daemon heartbeat, and empty alarm state avoids redundant deletes.
|
|
952
|
+
- Report refresh outcomes, estimated resumable-stream row writes, and alarm set/delete/no-op counters in Worker observability. Regression tests hold a normal stream to four storage-row writes before expiry cleanup.
|
|
953
|
+
- Rate-limit repeated edge degradation logs and report suppressed-event counts, while redacting sensitive field names. Remove duplicate `waitUntil` registration for one streamed terminal operation.
|
|
954
|
+
- Add hard critical-coverage thresholds for every new OAuth, stream, metadata, quota, edge-logging, and filesystem-state module rather than relying only on line-count architecture checks.
|
|
955
|
+
- Split OAuth refresh exchange, token issuance, terminal subscription, public metadata, and edge quota guards into focused modules rather than raising architecture limits.
|
|
956
|
+
|
|
957
|
+
## 3.0.0-beta.17 - 2026-07-26
|
|
958
|
+
|
|
959
|
+
### Fixed
|
|
960
|
+
|
|
961
|
+
- Serve `/healthz`, `/`, and CORS preflight from the outer Worker so activation and doctor checks no longer consume Durable Object free-tier request volume. Durable Object free-tier exhaustion now returns a structured `503 durable_object_quota_exceeded` instead of Cloudflare error 1101.
|
|
962
|
+
|
|
963
|
+
### Durable Object stream request amplification fix
|
|
964
|
+
|
|
965
|
+
- Replace the outer Worker's time-proportional internal Durable Object poll loop with a fixed two-request terminal path: one authenticated descriptor `prepare`, then one hibernatable WebSocket `subscribe`.
|
|
966
|
+
- Add `mcp-stream-channel.ts` so `BridgeRoom` accepts a single stream subscriber through `DurableObjectState.acceptWebSocket()`, replaces stale resume subscribers, rechecks storage after registration to close the completion race, and pushes exactly one terminal JSON-RPC message.
|
|
967
|
+
- Persist-ready notifications are fire-and-forget from `McpResumptionStore`; if persistence fails, the current online subscriber can still receive the transient terminal result while recovery storage keeps failure semantics.
|
|
968
|
+
- Keep daemon candidate cleanup from treating stream-subscriber sockets as daemon candidates, and reject client-to-DO data on receive-only stream subscribers.
|
|
969
|
+
- Fix the outer subscription waiter so invalid terminal payloads reject instead of leaving the SSE completion Promise permanently unsettled.
|
|
970
|
+
- Extend deterministic infrastructure coverage for the fixed two-request budget, obsolete poll-mode rejection, subscriber replacement, registration races, immediate-completion paths, protocol errors, and non-daemon socket isolation. Update architecture, engineering, testing, audit, and operations contracts to describe subscribe push delivery instead of short pending/terminal polls.
|
|
971
|
+
|
|
972
|
+
## 3.0.0-beta.16 - 2026-07-25
|
|
973
|
+
|
|
974
|
+
### Pending-call recovery and verified handover
|
|
975
|
+
|
|
976
|
+
- Separate the upstream MCP host/connector shard-mapper incident from Machine Bridge evidence. The exact temporary-keyspace error never appeared in Worker or daemon diagnostics and did not increment Worker server-error counters, so it is documented as an external boundary failure with unknown platform ownership rather than misclassified as a local daemon, OAuth, Git, or Cloudflare defect.
|
|
977
|
+
- Close the Machine Bridge failure-amplification path discovered after recovery. Pending calls now retain monotonic operation and reconnect deadlines, schedule the earliest deadline through the Durable Object alarm, and run a compensating overdue sweep on every HTTP/WebSocket event. In-memory timers remain the fast path; a transient alarm-storage error is observable without converting already-dispatched work into a false terminal failure.
|
|
978
|
+
- Make verified same-instance daemon handover atomic with respect to in-flight calls. Both attached and detached records move to the replacement before the incumbent closes, the complete `resume_calls` set is sent, remaining operation timeout is preserved, and failed replacement acknowledgement restores ownership to a still-open incumbent.
|
|
979
|
+
- Add deterministic disabled-timer deadline tests, direct runtime-alarm scheduling/failure tests, and a real Wrangler/workerd race regression that connects a same-instance replacement while the incumbent still owns an active call. The call remains active rather than detached and completes through the verified replacement.
|
|
980
|
+
- Use null-prototype dictionaries for managed-job `env` and `env_resources`, so valid variable names such as `__proto__`, `constructor`, `toString`, and `valueOf` remain ordinary own data instead of mutating JavaScript object prototypes. Add behavior coverage without weakening duplicate-variable rejection.
|
|
981
|
+
- Correct architecture and operations documentation that still described Durable Object `waitUntil` ownership or direct rejection during socket replacement. Document the three deadline enforcement paths, stale-pending diagnosis, host/connector internal-storage error triage, and the exact test evidence.
|
|
982
|
+
|
|
983
|
+
## 3.0.0-beta.15 - 2026-07-25
|
|
984
|
+
|
|
985
|
+
### Event-driven streamed-call settlement
|
|
986
|
+
|
|
987
|
+
- Block `3.0.0-beta.14` after exact owner-machine activation and repeated production verification. Version, launchd identity, private candidate runtime, status, doctor, sequence-zero delivery, session isolation, disconnect recovery, and terminal acknowledgement all converged, but a concurrent `server_info` still timed out while the original SSE remained open; session-scoped cancellation therefore could not enter. Beta.14 has no acceptance record and must not be pushed, published, or promoted.
|
|
988
|
+
- Remove the last cross-event terminal Promise from streamed `tools/call` initiation. `BridgeRoom` now commits the recovery record, registers an event-settled pending call, sends the daemon envelope, and returns the descriptor without retaining a Promise for the daemon result. The later daemon WebSocket `tool_result`, explicit cancellation request, timeout, send failure, or reconnect-grace expiry owns terminal settlement and persistence.
|
|
989
|
+
- Preserve ordinary JSON-only calls with the existing Promise-based request path while adding a separate event settlement mode to `PendingCallRegistry`. Same-instance daemon reconnect still detaches and rebinds both modes; terminal settlement removes request keys, closes observability, and writes exactly one resumable JSON-RPC result.
|
|
990
|
+
- Replace the resumption store's live Promise map with an active-stream set plus a bounded transient terminal map used only when persistence fails. A pending persisted record without matching active state still produces the existing restart-ambiguity error instead of inventing completion.
|
|
991
|
+
- Add deterministic event-lifecycle regressions that prove stream initiation returns before any terminal event, then exercise success, daemon rejection, cancellation, timeout, send failure, result transformation, persistence failure, and same-instance reconnect. Architecture checks forbid `dispatchJsonRpc` terminal Promises, `resumption.attach`, and Durable Object `waitUntil` from returning to the stream initiation path.
|
|
992
|
+
|
|
993
|
+
## 3.0.0-beta.14 - 2026-07-25
|
|
994
|
+
|
|
995
|
+
### Concurrent MCP control during streamed delivery
|
|
996
|
+
|
|
997
|
+
- Block `3.0.0-beta.13` after exact owner-machine activation. Live recovery itself succeeded—sequence zero, session isolation, disconnect recovery, and one-time terminal acknowledgement all worked—but a production Cloudflare Durable Object that directly owned the open SSE response did not accept concurrent `server_info` or `notifications/cancelled` requests until that stream ended. Beta.13 has no acceptance record and must not be published or promoted.
|
|
998
|
+
- Move public SSE ownership to the stateless outer Worker. `BridgeRoom` now authenticates and binds the request, commits the resumable record, dispatches local work, and returns only a bounded internal descriptor. The outer Worker emits sequence zero/keepalives/sequence one and polls the Durable Object with short immediate requests for pending or terminal state, so no Durable Object request remains open while a client stream is active.
|
|
999
|
+
- Strip all internal stream-control headers from public requests before forwarding, then add them only on the trusted service-binding path. OAuth/DPoP, signed MCP-session, token/session replay isolation, explicit cancellation, bounded persistence, and acknowledged-terminal suppression remain enforced by `BridgeRoom`.
|
|
1000
|
+
- Extend real Wrangler integration to hold an SSE call open while a concurrent `server_info` succeeds and a session-scoped cancellation reaches the exact daemon call. Transport tests now parse complete SSE events rather than assuming one network chunk equals one event.
|
|
1001
|
+
|
|
1002
|
+
## 3.0.0-beta.13 - 2026-07-25
|
|
1003
|
+
|
|
1004
|
+
### Resumable MCP result delivery and outage closure
|
|
1005
|
+
|
|
1006
|
+
- Complete the Streamable HTTP recovery contract. Every streamed `tools/call` now emits a sequence-zero SSE event identifier before local execution can complete, persists a token- and MCP-session-bound delivery record, emits the terminal result as sequence one, and accepts authenticated `GET /mcp` recovery with `Last-Event-ID`. Reusing sequence one returns an empty completed stream instead of delivering the terminal response twice.
|
|
1007
|
+
- Separate execution continuity from result-delivery continuity. An HTTP/SSE disconnect does not cancel the daemon call; only session-scoped `notifications/cancelled` does. A new POST always starts a new request, while GET only resumes a previously issued stream identifier, preventing retry semantics from being conflated with replay.
|
|
1008
|
+
- Bound Durable Object recovery state to 64 streams, two minutes, and 1.5 MiB per persisted terminal message. A compact metadata index avoids scanning stored result bodies. Result records carry SHA-256 integrity metadata, are isolated by OAuth token and MCP session, evict expired or oldest completed entries first, and return explicit errors for oversized replay data, lost in-memory execution after Worker restart, or stored-result corruption.
|
|
1009
|
+
- Preserve online delivery when persistence fails transiently, fail before side effects when a new recovery record cannot be admitted, and allow browser DPoP/resumption preflights by advertising both `DPoP` and `Last-Event-ID` in CORS.
|
|
1010
|
+
- Promote the recovery summary for an already-warned relay outage to `warn`, while brief self-healing interruptions remain debug-only. Default background-service logs now contain both outage start and recovery closure without exposing raw close reasons.
|
|
1011
|
+
- Add direct store fault/tamper/capacity tests, SSE framing tests, and live Wrangler integration that disconnects after sequence zero, completes the daemon call, rejects another session, recovers through GET, and proves the acknowledged terminal event is not duplicated.
|
|
1012
|
+
- Refresh the locked development-only `brace-expansion` transitive dependency from 5.0.7 to 5.0.8 after the mandatory pre-candidate registry audit reported GHSA-mh99-v99m-4gvg. Both complete and production-only audits must be clean before beta.13 candidate preparation.
|
|
1013
|
+
- Integrate Dependabot PR #56 into the complete beta.13 candidate rather than merging its incomplete two-file update. Wrangler advances to 4.114.0, Miniflare/workerd to the 2026-07-22 build, the exact `workerd@1.20260722.1` postinstall approval is reviewed and updated, and the existing patched `sharp@0.35.3` override remains authoritative.
|
|
1014
|
+
|
|
1015
|
+
## 3.0.0-beta.12 - 2026-07-23
|
|
1016
|
+
|
|
1017
|
+
### ChatGPT Streamable HTTP task continuity
|
|
1018
|
+
|
|
1019
|
+
- Fix remote `tools/call` handling so an HTTP/SSE connection closing is no longer interpreted as MCP cancellation. Only an explicit session-scoped `notifications/cancelled` request may remove the pending request key and send `cancel_call` to the daemon.
|
|
1020
|
+
- Negotiate `text/event-stream` for clients that advertise it, prime the response immediately, send a bounded ten-second keepalive comment while work is active, and deliver the terminal JSON-RPC result as an SSE message. This prevents a long-running local operation from leaving the ChatGPT-to-Worker HTTP path completely idle.
|
|
1021
|
+
- Preserve the underlying Durable Object operation with `waitUntil` when the response stream is no longer writable, so transport disposal cannot silently terminate local work. JSON-only clients retain the existing single-response behavior.
|
|
1022
|
+
- Replace duplicated relay timing literals with one shared contract. Same-daemon reconnect recovery is extended from thirty seconds to two minutes, and the Worker pauses only the remaining normal call deadline while detached, avoiding both premature expiry during recovery and inflated timeouts while the daemon is healthy.
|
|
1023
|
+
- Add deterministic and live Worker regressions for SSE negotiation, immediate priming, keepalives, terminal result delivery, HTTP abort without cancellation, explicit cancellation after disconnect, shared timeout ceilings, and same-instance recovery timing.
|
|
1024
|
+
|
|
1025
|
+
## 3.0.0-beta.11 - 2026-07-23
|
|
1026
|
+
|
|
1027
|
+
### External-review verification and observability hardening
|
|
1028
|
+
|
|
1029
|
+
- Share one portable content-redaction implementation between local and Worker logs. Worker string fields now redact embedded bearer/API tokens, credential URLs, email addresses, private-key headers, and user-home paths even when the field name itself is not sensitive.
|
|
1030
|
+
- Prevent caller-supplied local or Worker fields from replacing authoritative `timestamp`, `level`, `component`, `message`, or `event` metadata, and add regression coverage for both value leakage and metadata forgery.
|
|
1031
|
+
- Make the automatic execution model explicit in authenticated `server_info` authority snapshots and `machine-mcp doctor`: operations inside effective authority do not use per-operation prompts, and remote owner shell/browser/application actions have the daemon OS user's ambient authority.
|
|
1032
|
+
- Extract local-resource reads and SSH-resource registration into `runtime-resource-service.mjs`, reducing `LocalRuntime` from 697 to 653 lines while retaining the existing zero-extra-step browser/application resource path and public result contract.
|
|
1033
|
+
- Re-verify review claims against the repository invariants. The default `full` profile, single-maintainer release controls, Node 26/npm 12 baseline, packaged deployment/release helpers, systemd-user support, and cross-platform behavior suites remain intentional; none is weakened or removed merely to reduce surface area or ceremony.
|
|
1034
|
+
- Refresh the exact Wrangler runtime from 4.112.0 to 4.113.0 and advance the reviewed npm install-script allowlist to its exact `workerd 1.20260721.1`; a clean install must not depend on an unreviewed or locally cached postinstall.
|
|
1035
|
+
|
|
1036
|
+
## 3.0.0-beta.10 - 2026-07-22
|
|
1037
|
+
|
|
1038
|
+
### Published prerelease activation repair
|
|
1039
|
+
|
|
1040
|
+
- normalize npm 12 single-result JSON arrays for version, integrity, SHA-1, dist-tags, and publication timestamps;
|
|
1041
|
+
- unblock exact registry-backed prerelease installation and soak activation without weakening integrity or dist-tag verification;
|
|
1042
|
+
- add a regression fixture matching the real npm 12 response shape that blocked beta.9 activation.
|
|
1043
|
+
|
|
1044
|
+
## 3.0.0-beta.9 - 2026-07-22
|
|
1045
|
+
|
|
1046
|
+
### Cross-platform release-gate repair
|
|
1047
|
+
|
|
1048
|
+
- Block `3.0.0-beta.8` after owner activation and acceptance because pull-request CI found three release-blocking defects that local macOS verification could not establish: the Windows trusted-Git regression forced Linux permission semantics onto NTFS, Ubuntu coverage did not execute the macOS delegated-sandbox behavior probe, and CodeQL rejected an unused cleanup-path assignment.
|
|
1049
|
+
- Make trusted-Git regression coverage use the actual host platform while retaining POSIX group-writable rejection on Unix. Make macOS sandbox availability accept explicit platform and executable-presence probes for deterministic cross-platform tests, and exercise the complete read/write/outside-path/Keychain behavior matrix with a synthetic process boundary.
|
|
1050
|
+
- Remove the unused activation cleanup assignment rather than adding a CodeQL exception. These changes require a new exact candidate, live activation, acceptance, and full prerelease gate.
|
|
1051
|
+
|
|
1052
|
+
## 3.0.0-beta.8 - 2026-07-22
|
|
1053
|
+
|
|
1054
|
+
### Candidate repository hygiene correction
|
|
1055
|
+
|
|
1056
|
+
- Block `3.0.0-beta.7` after owner-machine acceptance. A full staged-tree `git diff --cached --check` exposed an extra blank line at EOF in the newly added Worker device-session verifier; the earlier working-tree-only check did not inspect that untracked file, so the reported hygiene result was incomplete.
|
|
1057
|
+
- Remove only the extraneous EOF blank line. Runtime behavior, protocol behavior, activation logic, and the beta.7 live conclusions are unchanged.
|
|
1058
|
+
- Assign a new prerelease version and regenerate the exact candidate because even this packaged-source change invalidates the accepted beta.7 package and promotion digests.
|
|
1059
|
+
|
|
1060
|
+
## 3.0.0-beta.7 - 2026-07-22
|
|
1061
|
+
|
|
1062
|
+
### Nested npm lifecycle PATH normalization
|
|
1063
|
+
|
|
1064
|
+
- Block `3.0.0-beta.6`. Its exact Worker and daemon activated successfully, but live launchd inspection still found repository `node_modules/.bin` entries and npm's private `node-gyp-bin`. The packaged beta.6 function was present and produced a clean PATH when called directly; the failure was caused by nested activation: the existing daemon PATH already contained one npm run-script prefix, and invoking `npm run release:candidate:activate` prepended a second. Beta.6 removed only through the first marker and therefore persisted the complete inner prefix.
|
|
1065
|
+
- Normalize through the last npm run-script marker, removing every nested lifecycle prefix while retaining the current Node/package directories, the operator PATH after the innermost marker, and platform defaults. Inactive candidate-runtime entries remain excluded.
|
|
1066
|
+
- Expand Unix and synthetic Windows regressions to two complete npm prefix/marker layers followed by a stale candidate and a user bin. Both layers must be removed; ordinary non-lifecycle `node_modules/.bin` entries remain supported.
|
|
1067
|
+
|
|
1068
|
+
## 3.0.0-beta.6 - 2026-07-22
|
|
1069
|
+
|
|
1070
|
+
### Reproducible background service environment
|
|
1071
|
+
|
|
1072
|
+
- Block `3.0.0-beta.5`. Its exact candidate activated successfully on the owner machine: the same-version Worker and single launchd daemon reached readiness, `project_overview` reported distinct effective and daemon-ceiling authority, fixed Git metadata succeeded, `service start` preserved the existing PID, and detached `service restart` replaced the PID and returned to readiness with no pending calls. Post-activation inspection nevertheless found that the launchd `PATH` captured npm lifecycle injection from the activation command, including project `node_modules/.bin` prefixes, npm's private `node-gyp-bin`, and the beta.4 candidate runtime that activation immediately pruned.
|
|
1073
|
+
- Make service `PATH` construction reproducible across ordinary installation and prerelease activation. The current Node directory and current package bin are always added explicitly. When npm's `@npmcli/run-script` marker is present, the lifecycle-injected prefix is removed before inheriting the operator PATH. Any other entry below the candidate runtime store is rejected while the current candidate bin remains available. Ordinary user-supplied `node_modules/.bin` entries are retained when they were not injected by an npm lifecycle.
|
|
1074
|
+
- Add a cross-platform regression that reproduces the exact activation topology: npm project bins before the lifecycle marker, a stale prior candidate runtime after the marker, an inherited user bin, and the current runtime entry. The service definition must retain Node/current runtime/user tools, reject npm-private and stale candidate entries, preserve absolute-only deduplication, and continue to embed the sanitized value in launchd and systemd definitions.
|
|
1075
|
+
|
|
1076
|
+
## 3.0.0-beta.5 - 2026-07-22
|
|
1077
|
+
|
|
1078
|
+
### Relay resilience, lifecycle correctness, and fail-closed state hardening
|
|
1079
|
+
|
|
1080
|
+
- Block `3.0.0-beta.4`. Live observation showed that the daemon process and launchd job could remain healthy while the authenticated WebSocket disappeared and later recovered with the same PID. The affected route was carried through the machine's system VPN/TUN; Machine Bridge cannot prove which internal VPN hop failed, but it can now distinguish application-level proxy selection from the operating-system network stack instead of reporting the misleading label `direct`.
|
|
1081
|
+
- Cap relay reconnect backoff at 15 seconds instead of 60 seconds. Add bounded outage count/start/duration, last close category/code, transport error class, last disconnect/ready timestamps, ready duration, and next-retry timing to `server_info` and `diagnose_runtime`. Emit timestamped `relay.outage.active` and `relay.outage.recovered` events without exposing close reasons, proxy endpoints, page data, tool arguments, or results.
|
|
1082
|
+
- Make `service start` idempotently ensure a running service and reserve explicit replacement for `service restart`. Require verified state/workspace ownership before touching the machine-global service, use detached restart handoff where behavior is verified, and fail closed on in-process Windows restart rather than risking a Task Scheduler `/End` operation that also kills the restart helper.
|
|
1083
|
+
- Replace raw launchd/systemd status dumps with structured summaries. Service status no longer exposes the user's home path, complete PATH, SSH agent socket, environment, or provider diagnostics. Autostart log schema migration now validates both owner-only log files before mutation, rejects symbolic or multiple-hard-link paths, writes schema 4 strictly, and aborts startup on incomplete migration instead of mixing text and NDJSON.
|
|
1084
|
+
- Treat a tool result, public error, Worker pong/welcome, browser response, and extension keepalive as explicit serialization/delivery boundaries. Circular values, BigInt, oversized structures, half-closed sockets, and send failures terminate only the affected request or transport and no longer crash or silently strand the whole relay.
|
|
1085
|
+
- Prevent delayed process-tree escalation from signaling a reused PID or process group while still cleaning descendants that survive their parent. Snapshot process identity before graceful termination, verify it before SIGKILL, bind escalation timers to tracker/session lifecycle, and cover parent-exits-first and resistant-descendant cases.
|
|
1086
|
+
- Pin implementation-owned Git and release-control commands to absolute, executable, non-group-writable binaries outside the workspace, state root, runtime root, and user home. Fixed metadata probes remain no-shell and minimal-environment; npm lifecycle PATH and workspace shims cannot replace `git` or `gh` in security/release decisions.
|
|
1087
|
+
- Pin the browser broker to the repository extension ID derived from `manifest.key`, verify both WebSocket Origin and `chrome.runtime.id`, split extension and runtime credentials, and migrate legacy pairing state under the maintenance lock. The extension now cleans per-socket keepalive timers and active requests on replacement, disables stale reconnect, rejects duplicate request IDs, and closes half-dead sockets on response-delivery failure.
|
|
1088
|
+
- Make corrupt workspace trust state persistently fail closed. Only a current-schema state envelope with matching workspace hash, canonical state-root/profile/state paths, and required policy/worker/resource objects can clear `recovery-required`; recovery markers are read once and strictly validate their bounded backup name and timestamp.
|
|
1089
|
+
- Make managed-job terminal persistence recoverable. Result, terminal status, private runtime/plan/PID/cancel cleanup, and cleanup confirmation form an ordered protocol. Result-write, status-write, and artifact-cleanup failures remain visible; status reconstruction from a valid terminal result prevents duplicate finally execution, while leftover secret/resource copies are retried by read/list/prune.
|
|
1090
|
+
- Give security-audit and legacy authorization state true cross-process locks. State removal also detects those locks plus managed-job transition/recovery locks, preventing uninstall from deleting a profile during an active mutation. Concurrent audit writers retain every event and a continuous hash chain.
|
|
1091
|
+
- Reject multiple-hard-link inodes at owner-only state, autostart logs, runner diagnostics, and path-based existing-file reads. Atomic overwrite remains safe because it replaces the workspace directory entry rather than modifying a shared inode.
|
|
1092
|
+
- Upgrade delegated macOS sandbox enablement from executable-presence testing to a behavior matrix that proves workspace access and denies outside reads/writes. Current hosts where the matrix fails remain fail closed; Keychain isolation is no longer claimed without an independently verified boundary.
|
|
1093
|
+
- Bound detached managed-job credentials and staging lifetime. Minimal plans launch the runner with a minimal control environment, explicit full-environment plans retain that choice, and unexecuted sensitive plans expire after 24 hours instead of remaining for the seven-day result-retention period.
|
|
1094
|
+
- Preserve both primary and cleanup failures for Secure Enclave enrollment and persistent candidate activation. Local cleanup failure is returned as an `AggregateError`; transactional rollback of an already updated Cloudflare Worker and local service definition remains an explicit operational residual rather than a false guarantee.
|
|
1095
|
+
- Add explicit 32-call stdio admission control, refresh-family revocation before replay-marker capacity eviction, constant-memory unauthorized-request body draining before rejection, trusted Windows PowerShell literal tests, browser broker load counters, function-complexity/module-size gates, and risk-directed coverage for every new boundary.
|
|
1096
|
+
|
|
1097
|
+
## 3.0.0-beta.4 - 2026-07-22
|
|
1098
|
+
|
|
1099
|
+
### Explicit daemon-ceiling reporting and fixed internal metadata execution
|
|
1100
|
+
|
|
1101
|
+
- Mark `3.0.0-beta.3` as blocked. Its owner activation, persistent daemon handoff, relay readiness, service restart, and ordinary owner tool calls succeeded, but live verification exposed two delegated-account defects before publication: `project_overview` could report the request-effective `custom` policy as the daemon ceiling, and reviewer/editor Git metadata calls were routed through the arbitrary-process sandbox boundary.
|
|
1102
|
+
- Return request-effective `policy`/`tools` and daemon-ceiling `daemonPolicy`/`daemonTools` as separate local fields. The Worker now consumes the explicit ceiling fields and retains a compatibility fallback for older daemon responses, preventing a second interpretation of an already-intersected policy.
|
|
1103
|
+
- Add a fixed internal process path for bounded implementation-owned metadata probes. It uses validated argv, no shell, an isolated minimal environment, the existing timeout/output/cancellation/process-tree accounting, and never inherits the daemon full environment. Git status, diff, log, show, and project-root detection use this path; user-selected `run_process`, registered commands, and `exec_command` remain subject to the delegated sandbox and ordinary role ceilings.
|
|
1104
|
+
- Add real `LocalRuntime` regressions for editor project snapshots and reviewer Git metadata, a process-layer regression proving the internal path is not wrapped as delegated arbitrary execution, and Worker integration coverage that supplies distinct effective and daemon fields.
|
|
1105
|
+
- Prevent foreground startup in an unrelated workspace or isolated state root from unloading the machine-global autostart service. Platform service control now requires a live, verified `service` daemon lock for the exact state/workspace; the installed-package smoke test traps service-manager calls and proves zero-argument startup cannot stop the operator's real daemon. This fixes the repeated relay outages observed when the full verification plan reached `install:test`.
|
|
1106
|
+
- Make `--log-format json` authoritative for the complete logger surface. Direct `debug`/`info`/`success`/`warn`/`error` calls and persistent daemon readiness now emit one timestamped, redacted JSON object per line instead of silently falling back to unstructured text. Add regressions for stream routing, normalized levels, timestamps, and sensitive/path field redaction.
|
|
1107
|
+
- Override Wrangler/Miniflare’s transitive `sharp` dependency from vulnerable 0.34.5 to patched 0.35.3 after GHSA-f88m-g3jw-g9cj entered the audit database. Keep Wrangler itself pinned, update the npm script allowlist, and require full Worker/Miniflare integration plus zero-high-severity audit evidence for the override.
|
|
1108
|
+
|
|
1109
|
+
## 3.0.0-beta.3 - 2026-07-21
|
|
1110
|
+
|
|
1111
|
+
### Provisioned Secure Enclave broker boundary
|
|
1112
|
+
|
|
1113
|
+
- Mark `3.0.0-beta.2` as blocked. Its live activation restored version 2 device-ID compatibility, but then attempted to create a persistent Secure Enclave key from a runtime-compiled, ad-hoc-signed command-line helper. Modern macOS routes Secure Enclave keys through the data-protection Keychain and rejected that helper with `errSecMissingEntitlement` (`-34018`) before Worker deployment or daemon handoff.
|
|
1114
|
+
- Stop treating a source-built ad-hoc helper as a production trust anchor. Without an explicitly configured provisioned broker, macOS retains or creates the owner-only portable P-256 root, performs no Keychain operation, requests no user-presence prompt, and proceeds with the coordinated version 3 upgrade.
|
|
1115
|
+
- Add opt-in Secure Enclave enrollment through `MBM_MACOS_TRUST_BROKER`. The configured absolute path must resolve to a regular executable that is not group/other writable, has a strict valid Apple code signature, carries a stable signing identifier and Team ID, and passes an end-to-end probe that creates and deletes a temporary Secure Enclave key. The enrolled root binds the canonical broker path, signing identifier, Team ID, protocol version, key tag, and public key; every later public-key check or signature revalidates that binding.
|
|
1116
|
+
- Keep the packaged Swift source and ad-hoc build only as a development and protocol-conformance fixture. It is intentionally rejected by the production broker validator. Add cross-platform provider-selection tests, macOS signature/binding/probe regressions, and truthful `server_info` provider metadata.
|
|
1117
|
+
|
|
1118
|
+
## 3.0.0-beta.2 - 2026-07-21
|
|
1119
|
+
|
|
1120
|
+
### Version 2 device-identity compatibility
|
|
1121
|
+
|
|
1122
|
+
- Restore the stable RFC-style P-256 JWK member order (`crv`, `kty`, `x`, `y`) used by version 2 device identifiers. The initial beta accidentally reordered those members through a new shared canonicalization helper, causing an intact version 2 portable identity to fail before Worker or daemon handoff.
|
|
1123
|
+
- Add an explicit backward-compatibility regression that validates a persisted version 2 identifier and rejects the incorrect beta.1 ordering. Beta.1 is blocked and must not be activated or promoted.
|
|
1124
|
+
|
|
1125
|
+
## 3.0.0-beta.1 - 2026-07-21
|
|
1126
|
+
|
|
1127
|
+
### Request-scoped authority, trusted clients, and zero-routine-prompt security
|
|
1128
|
+
|
|
1129
|
+
- Replace delegated terminal approval IDs and broad capability leases with a request-scoped authority intersection. Every remote request now evaluates the daemon capability ceiling, the authenticated account role ceiling, the OAuth client and refresh-token family, automatic safety invariants, and object ownership. A grant can no longer expand a reviewer, editor, or operator beyond its canonical role. Owner/full automation remains uninterrupted, but owner requests are still risk-classified and audited.
|
|
1130
|
+
- Bind retained process output, interactive process sessions, and managed jobs to account ID, account version, OAuth client, and refresh-token family. Cross-account or stale-session reads, input, cancellation, and output access fail closed. Protected local resources cannot be smuggled into delegated managed jobs, and non-owner accounts cannot create durable execution plans.
|
|
1131
|
+
- Enforce request-specific path visibility, unrestricted-path authority, absolute-path disclosure, and child-process environment selection throughout file, Git, Agent-context, process, and job services. Generic path-based file tools cannot read or write Machine Bridge control-plane state even under owner/full; arbitrary owner shell execution remains equivalent to the OS user and is documented as a residual risk. Delegated process execution requires a behavior-verified OS workspace sandbox; platforms where the sandbox merely exists but fails a deny-default launch probe reject delegated execution rather than silently running with local-user authority. Owner execution is unchanged.
|
|
1132
|
+
- Remove terminal-based operation authorization from the normal CLI and runtime. OAuth client authorization is the low-frequency trust event; ordinary operations run automatically within the account ceiling. Legacy leases are ignored by runtime and remain visible only for incident-response revocation. Trusted clients bind to one account and can be listed or revoked independently without rotating every account credential.
|
|
1133
|
+
- Propagate refresh-token family identity to the local daemon and reject relay envelopes without it. Access tokens remain fifteen minutes and rotating refresh families remain bounded. Client trust, account version, role, and family identity participate in authorization and object ownership.
|
|
1134
|
+
- Add a privacy-preserving chained security audit. It records tool, coarse risk category, result, duration, byte counts, target digest, and keyed principal references without storing command text, paths, file contents, form values, or output. Hash-chain verification detects local corruption or alteration and is exposed through runtime diagnostics without blocking ordinary work when the audit sink is unavailable.
|
|
1135
|
+
- Stop nonce-capacity handling from evicting live replay markers. A full replay cache now rejects new signed requests until entries expire instead of reopening the replay window.
|
|
1136
|
+
- Replace the long-lived file-backed device signer with a root-certified ephemeral session hierarchy. macOS prefers a non-exportable Secure Enclave P-256 root protected by user presence; one root signature per daemon start certifies a 24-hour in-memory session key used for preflight, challenge authentication, reconnect, and account administration. Root migration and rotation are two-phase: a pending public key is deployed and health-verified before local promotion.
|
|
1137
|
+
- Remove `ACCOUNT_ADMIN_SECRET` from local state and Worker secrets. Account/client administration now uses the same root-certified ephemeral P-256 session, with each request bound to origin, method, path, body hash, key ID, timestamp, and nonce. Add optional DPoP ES256 token binding for compatible clients while preserving Bearer interoperability. DPoP proof verification no longer consumes replay capacity before OAuth credential validation, preventing unauthenticated cache exhaustion; unsupported critical JWS headers are rejected.
|
|
1138
|
+
- Remove the terminal `job approve` execution path. `stage_job` remains a validated non-running draft; execution requires trusted owner `start_job` authority or an explicit local `machine-mcp job submit PLAN.json` action.
|
|
1139
|
+
- Add behavior-level regressions for canonical-full daemon versus delegated-role boundaries, cross-account process/job ownership, control-plane path protection, token-family binding, nonce saturation, chained audit tampering, and delegated sandbox capability probing. Expand critical-module coverage and rewrite authorization, operations, upgrade, security, and threat-model documentation around the zero-routine-prompt model.
|
|
1140
|
+
- This is a coordinated Worker, daemon, state, and browser-extension protocol upgrade. Version 3 components must converge together; existing remote clients must authorize once again because the relay principal now requires refresh-family and trusted-client binding.
|
|
1141
|
+
- Replace the direct-to-stable release path with mandatory `dev`/`beta`/`rc` channels, registry-verified soak, and content-preserving stable promotion. Major, minor, and patch releases require at least seven days, three days, and one day respectively. A blocking fix increments the prerelease and restarts the interval.
|
|
1142
|
+
- Add one persistent candidate activation command that verifies the exact tarball, updates the same-name Worker, proves candidate relay readiness, hands off to the login daemon, verifies the background version, and exits while the service remains active. Add exact prerelease npm/GitHub channel checks, published-package activation records, tracked soak evidence, promotion-content digests, and stable push/release/publication gates.
|
|
1143
|
+
- Remove the remaining internal APIs that could create version 2 capability leases. Only migration cleanup (`list`, `revoke`, `clear`) remains.
|
|
1144
|
+
|
|
3
1145
|
## 2.0.0 - 2026-07-21
|
|
4
1146
|
|
|
5
1147
|
### Device identity and usable local transaction authorization
|