diff --git a/docs/validation/extensions-compatibility-20260922.json b/docs/validation/extensions-compatibility-20260922.json new file mode 100644 index 000000000..dfad033b6 --- /dev/null +++ b/docs/validation/extensions-compatibility-20260922.json @@ -0,0 +1,414 @@ +{ + "source_revision": "79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa", + "source_tree": "1205687f3c4a60a30565efcc94592d78e50f9ddc", + "source_sha256": { + "CHANGELOG.md": "2f99f5088cb3363d5c157bb82451b2cde37ebf9291cdef5259b97204f0d14dd9", + "__tests__/cli-version.test.ts": "7f2263a10cbee34d67ca44d514abb0c0da13d165b30fe8698fdc2969982aabc3", + "__tests__/extension-releases.test.ts": "3dda48db9b97b4ac9ea437d62d1f503e91f2f8ea5ec8592f2230843cfb2197db", + "docs/extensions/authoring.md": "224c5c8652a469c98857bafeefd69894e69709e302cc58eff50f8d399ba8c88b", + "marketplace/public/app.js": "c7a8681945d82de27c2e46f8c76f08cdd616a54ab7aaae118091be8b7bc2fdea", + "scripts/validation/extensions-compatibility.cjs": "e6b9a6dfdb27f59a9398f88f6df7726bb6e2c850581849aeb536add7878d5194", + "scripts/validation/marketplace-browser.cjs": "76194905d863800ad7d173d54137eb0195038fde2bae9a1eb450d6f2c0be3153", + "src/bin/codegraph.ts": "021b46718a6aa45a4edc01a001bfaa912f3d98dd515a5a704fdf866aa60bc23c", + "src/plugins/bridge.ts": "2a8f7b86e480a58d87e9f081c3292ec22885b597107b2c26b76a6d89fb9e86f8", + "src/plugins/cli.ts": "9af94178b540ea4975d5a7b715730132c69409004f8dcd09f99bd84f936aea00", + "src/plugins/manager.ts": "7c24442476b5fc63f84fe047df3f4e371059e1973bdbc5b35a9e45e6e5d97134", + "src/plugins/marketplace.ts": "605dc8c53abf67d55a0a4b04ef305535ff3dc3456bf7fa2b6cb184ce49cb0e92", + "src/plugins/releases.ts": "96988d116ea6aa0c106c0a9dcfc2031f9da969888e75e9f60cedc3882a8cec97" + }, + "checks": [ + { + "command": [ + "npm", + "run", + "build" + ], + "cwd": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph", + "started_at": "2026-09-22T03:09:27.479283+00:00", + "revision": "eab93c311434e1a5878c680a52b8c072da5ff772", + "working_tree": " M __tests__/cli-version.test.ts\n M marketplace/public/app.js\n M scripts/validation/extensions-compatibility.cjs\n M src/bin/codegraph.ts\n", + "exit_code": 0, + "seconds": 32.724, + "finished_at": "2026-09-22T03:10:00.203028+00:00", + "summary": [], + "receipt_path": ".qa/recovery/compat-cli-fix-build.json", + "log_path": ".qa/recovery/compat-cli-fix-build.log", + "log_sha256": "3bba6fec83b4be911d5685d45371e7461b42e3c89143f2a21f998d2d6c5d7c3b" + }, + { + "command": [ + "npx", + "vitest", + "run", + "__tests__/extension-releases.test.ts", + "__tests__/extension-marketplace.test.ts", + "__tests__/extension-author.test.ts", + "__tests__/plugins.test.ts", + "__tests__/extension-explore.test.ts", + "__tests__/npm-sdk.test.ts", + "__tests__/cli-install-init.test.ts", + "__tests__/cli-version.test.ts", + "--maxWorkers=2", + "--minWorkers=1" + ], + "cwd": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph", + "started_at": "2026-09-22T03:10:54.157173+00:00", + "revision": "79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa", + "working_tree": "", + "exit_code": 0, + "seconds": 18.087, + "finished_at": "2026-09-22T03:11:12.244376+00:00", + "summary": [ + "Test Files 8 passed (8)", + "Tests 43 passed (43)", + "Duration 16.05s (transform 3.61s, setup 0ms, collect 10.08s, tests 12.62s, environment 3ms, prepare 1.32s)" + ], + "receipt_path": ".qa/recovery/compat-focused-final.json", + "log_path": ".qa/recovery/compat-focused-final.log", + "log_sha256": "3441fe1eb195e7a44a6f80476dd035880573d148b92ed7aeee7ab1fb7eace0e8" + }, + { + "command": [ + "node", + "--test", + "scripts/validation/extensions-runtime.test.cjs" + ], + "cwd": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph", + "started_at": "2026-09-22T03:11:13.854565+00:00", + "revision": "79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa", + "working_tree": "", + "exit_code": 0, + "seconds": 7.52, + "finished_at": "2026-09-22T03:11:21.374094+00:00", + "summary": [], + "receipt_path": ".qa/recovery/compat-workers.json", + "log_path": ".qa/recovery/compat-workers.log", + "log_sha256": "902d611c9e10018ba53ede698aec98d84bfc4d5cdd6f2e911f5b1300d08387d4" + }, + { + "command": [ + "node", + "scripts/validation/extensions-compatibility.cjs" + ], + "cwd": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph", + "started_at": "2026-09-22T03:10:06.389817+00:00", + "revision": "79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa", + "working_tree": "", + "exit_code": 0, + "seconds": 24.301, + "finished_at": "2026-09-22T03:10:30.691130+00:00", + "summary": [], + "receipt_path": ".qa/recovery/compat-e2e-verified.json", + "log_path": ".qa/recovery/compat-e2e-verified.log", + "log_sha256": "c3097f4ef12522a0248149e234e0ccaf9c6733f9c2df84c60a06ac67c6c24d07" + }, + { + "command": [ + "node", + "scripts/validation/marketplace-browser.cjs" + ], + "cwd": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph", + "started_at": "2026-09-22T03:11:38.183791+00:00", + "revision": "79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa", + "working_tree": "", + "exit_code": 0, + "seconds": 14.119, + "finished_at": "2026-09-22T03:11:52.303059+00:00", + "summary": [], + "receipt_path": ".qa/recovery/compat-browser-regression.json", + "log_path": ".qa/recovery/compat-browser-regression.log", + "log_sha256": "a75f9b58660eb4607daaf5c0df45fd5fec719f69f893f7c6925f296fc6409ed2" + } + ], + "compatibility": { + "checks": [ + "signed immutable versions; semantic catalog order independent of publication order", + "one browser Install selects 1.10.0 over incompatible 9.0.0 and preview; actual Python graph refreshed only in chosen destination", + "no-compatible browser selection/command fails usefully and preserves existing config/graph", + "headless automatic selection agrees; exact incompatible pin/no-compatible/missing update fail without mutation", + "prerelease requires explicit exact pin; automatic update refuses downgrade; explicit lower pin remains exact", + "compatible but broken update retains previous version and graph", + "browser and headless update to highest compatible stable; stale graph labels removed", + "exact artifact URL/file semantics preserved", + "removal cleans contributions; desktop/mobile display actual destination compatibility; no page errors" + ], + "releases": [ + { + "id": "compatible-demo", + "version": "1.10.0", + "engines": ">=1.6.0 <2", + "integrity": "d59f9b1e9bd7d027081de45ab004aefe3236708ddeb4fc7135c92502ce0866d8" + }, + { + "id": "compatible-demo", + "version": "1.9.0", + "engines": ">=1.6.0 <2", + "integrity": "07e64445b8c7205ec9a1d76c9e29affbd55d45e0817e9c3d92572b9f00486fcd" + }, + { + "id": "compatible-demo", + "version": "0.5.0", + "engines": ">=1.6.0 <2", + "integrity": "ad3c944ff2bea24feb81cb25839746b72e4845b9dae3cba3a4e2ce872855114d" + }, + { + "id": "compatible-demo", + "version": "20.0.0-beta.1", + "engines": ">=1.6.0 <2", + "integrity": "1a24723ecad51739315c4a6439227ff0a884700647ac505db74a12949fa99c82" + }, + { + "id": "compatible-demo", + "version": "9.0.0", + "engines": ">=9", + "integrity": "c3f802635737b02d15f6fe3e82cde56c41a1c83c8a9cc0858ef964b49be206c9" + }, + { + "id": "unavailable-demo", + "version": "1.0.0", + "engines": ">=9", + "integrity": "bc25c179402f994d59e586491cc0921d01ddc6dcf12bea9274982df745f42ef0" + }, + { + "id": "compatible-demo", + "version": "2.0.0", + "engines": ">=1.6.0 <2", + "integrity": "5b2f2099fbe51f94a4242f8e81570bacf3a7c16625e8439af3853adab1de65f1" + }, + { + "id": "compatible-demo", + "version": "3.0.0", + "engines": ">=1.6.0 <2", + "integrity": "e9f0eecbf6621e6f0ba7fc139d1eb91ffa2899548e0b5e615e3443a0496c8081" + } + ], + "commands": [ + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.665, + "log_path": ".qa/recovery/compatibility-verified/command-1.log", + "log_sha256": "64f1ac60c8ad25f6569563d24914759b70acf1b73e5cffeef4feb12ce4c226b9" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--version", + "9.0.0", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 1, + "seconds": 0.414, + "log_path": ".qa/recovery/compatibility-verified/command-2.log", + "log_sha256": "d93afb7d84337fce0fb443fb79883800bb478b4c94635140b8f67f9734ed2b26" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "update", + "unavailable-demo", + "--registry", + "http://127.0.0.1:43423", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 1, + "seconds": 0.32, + "log_path": ".qa/recovery/compatibility-verified/command-3.log", + "log_sha256": "78fff926f4f8969d8e1705c0a1271cbd63b822579f81d715c2042ad94c80ad45" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "unavailable-demo", + "--registry", + "http://127.0.0.1:43423", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 1, + "seconds": 0.435, + "log_path": ".qa/recovery/compatibility-verified/command-4.log", + "log_sha256": "83a7b90bfd2c211c6fb4afcf72e261ef7b42bfd6dc21cfb72d530fb970aef44a" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--version", + "20.0.0-beta.1", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.618, + "log_path": ".qa/recovery/compatibility-verified/command-5.log", + "log_sha256": "5a0ae6eb30e6659515338894feeb98ebeabbcd4f66e01f425110e75e83d7986d" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "update", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 1, + "seconds": 0.423, + "log_path": ".qa/recovery/compatibility-verified/command-6.log", + "log_sha256": "38c1d85e306b15c18732c81df087390b3dfbd3873bc8836e36be492a1fb8a7fa" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--version", + "1.9.0", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.607, + "log_path": ".qa/recovery/compatibility-verified/command-7.log", + "log_sha256": "74798a107028fa391113eb0b6fa7efac8bfee9c644dbb121892993443666f2f0" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "update", + "compatible-demo", + "--registry", + "http://127.0.0.1:43423", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.639, + "log_path": ".qa/recovery/compatibility-verified/command-8.log", + "log_sha256": "be1f77d7dd153abaab34b2a75bdd5c2d036b406fc11da38ee8d4362bd4c26387" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "http://127.0.0.1:43423/api/download/compatible-demo/1.9.0", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.767, + "log_path": ".qa/recovery/compatibility-verified/command-9.log", + "log_sha256": "fec96b4acb520e5ee4d8a42660e9a876f54f08d60c1fc98bcc7b1dcfd2ba6748" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "install", + "/tmp/cg-compatible-NzGUvq/pinned.cgext", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.608, + "log_path": ".qa/recovery/compatibility-verified/command-10.log", + "log_sha256": "f03135c33691b92a8cd0834b0ab07175f81eb68d071d2e495c7ef96f6cbb5e69" + }, + { + "command": [ + "/usr/local/bin/node", + "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/codegraph/dist/bin/codegraph.js", + "extensions", + "remove", + "compatible-demo", + "--path", + "/tmp/cg-compatible-NzGUvq/headless-python-project" + ], + "exit": 0, + "seconds": 1.68, + "log_path": ".qa/recovery/compatibility-verified/command-11.log", + "log_sha256": "303e141e174839575e69f0ae0ddf92ead0470e6dca049ac1edd45fb64b607bde" + } + ], + "engineVersion": "1.6.0", + "platform": "linux", + "browser": "153.0.8010.36" + }, + "browser_regression": { + "browser": "153.0.8010.36", + "platform": "linux", + "checks": [ + "real browser signed publisher upload", + "browser publisher ownership rejection", + "browser invalid-signature failure state", + "browser malformed-package rejection without publication", + "one-click selected-project install verified in SQLite", + "real postMessage wrong-window command ignored", + "failed browser update preserves working version and graph", + "browser update replaces stale graph contributions", + "browser disable/enable/remove verified in SQLite", + "mobile detail fits viewport", + "real postMessage wrong-origin command ignored" + ], + "pageErrors": [] + }, + "screenshots": { + "docs/validation/extensions-compatibility-20260922/mobile-selected.png": "e6d817201490ad00f572d65de913c09be5f77f1e179da7dc9b5f4972a44746b2", + "docs/validation/extensions-compatibility-20260922/desktop-selected.png": "6f1bf3961036fc1800c1aecf5329d5dad335ea0c4936e6ad65b310c2a0663cae" + }, + "environment": { + "platform": "Linux x86_64", + "node": "v22.23.2", + "engine": "1.6.0", + "extension_api": 1, + "PLAYWRIGHT_MODULE": "/data/workspace/Chats/109197f0a288be0afa6b7f8902925630f5a0bfde/browser-tools/node_modules/playwright", + "COMPAT_OUTPUT": ".qa/recovery/compatibility-verified", + "BROWSER_OUTPUT": ".qa/recovery/compat-browser-regression" + }, + "prior_failed_attempt": { + "receipt": ".qa/recovery/compat-e2e.json", + "log_sha256": "5fdb771ab70b656fe16e1fd381324adb979ec7e2d0c70730ed868d1d32b5f357", + "reason": "Root CLI --version intercepted extension exact-version pin, printing engine version and exiting zero. Fixed by scoped positional parsing in 79f2d9f." + } +} diff --git a/docs/validation/extensions-compatibility-20260922.md b/docs/validation/extensions-compatibility-20260922.md new file mode 100644 index 000000000..a4df53258 --- /dev/null +++ b/docs/validation/extensions-compatibility-20260922.md @@ -0,0 +1,135 @@ +# Compatible extension release acceptance — 2026-09-22 + +Scoped milestone on draft PR [#1911](https://github.com/colbymchenry/codegraph/pull/1911), +branch `feature/extensions-author-kit-20260922`. Source commits +`eab93c311434e1a5878c680a52b8c072da5ff772` and +`79f2d9f1cab2e19ad35fb99f4e215da8f9d5fdfa`. The latter is the clean revision used +by all final runtime/browser/focused checks. Subsequent evidence changes only +documentation. No merge, release, public npm publication or hosted deployment. + +## Behavior + +`src/plugins/releases.ts` provides one semantic-version selection policy. The +managed installer resolves using its own engine version and supported manifest +API, never a browser-supplied engine claim. Browser `resolve` and registry +install/update commands use that installer. The CLI opts into the same path with +`--registry`; an unqualified file or URL still means an exact artifact. + +Automatic selection chooses the highest compatible stable version regardless +of publication order. Invalid metadata, unsupported/missing API markers and +incompatible ranges are excluded. Prereleases require an explicit exact +`--version` pin, which never falls back. Automatic selection cannot downgrade +an installed version; that guard is also checked under the operation lock. +Exact pins may intentionally select an older compatible version. Equal semver +precedence (build metadata) has a deterministic lexical tie break. + +The catalog includes API metadata and sorts stable versions semantically before +previews; historical stored listings recover their API marker from immutable +package bytes. The browser shows the actual selected version, running engine, +API and destination. Selection is refreshed on connection, destination changes, +publication and installed-state changes. Installation binds the displayed version +and digest, resolves again locally, then checks the downloaded identity/version, +engine/API manifest and SHA-256 digest before changing configuration or graph. +A selection changed since display requires a refresh. No compatible release and +failed activation preserve the current configuration and graph. + +The original publisher identity, immutable release, bearer, local-host, origin +and window restrictions remain in force. Existing exact URL bridge commands +retain their pinned-artifact semantics. + +## Reproduction and receipts + +From this checkout, with installed development dependencies: + +```sh +npm run build +npx vitest run __tests__/extension-releases.test.ts __tests__/extension-marketplace.test.ts __tests__/extension-author.test.ts __tests__/plugins.test.ts __tests__/extension-explore.test.ts __tests__/npm-sdk.test.ts __tests__/cli-install-init.test.ts __tests__/cli-version.test.ts --maxWorkers=2 --minWorkers=1 +node --test scripts/validation/extensions-runtime.test.cjs +PLAYWRIGHT_MODULE=/absolute/path/to/playwright COMPAT_OUTPUT=.qa/recovery/compatibility-verified node scripts/validation/extensions-compatibility.cjs +PLAYWRIGHT_MODULE=/absolute/path/to/playwright BROWSER_OUTPUT=.qa/recovery/compat-browser-regression node scripts/validation/marketplace-browser.cjs +``` + +The browser scripts use local registries and Chrome (`/opt/google/chrome/chrome`) +on Linux. No paid resources or extra model sessions were used. This report's +[JSON receipt](extensions-compatibility-20260922.json) includes exact commands, +source hashes, exits, timestamps, durations, raw log hashes and every headless +subcommand's exit/log hash. Raw receipts/logs are under `.qa/recovery/` in the +saved checkout; output overrides keep earlier evidence intact. + +| Check | Result | Duration | +|---|---|---:| +| Final engine/assets/viewer build | exit 0 | 32.724 s | +| Focused installer/registry/author/runtime/retrieval/SDK/CLI tests | 8 files, 43 tests passed; exit 0 | 18.087 s | +| Compiled worker lifecycle, isolation and rollback | 2 tests passed; exit 0 | 7.520 s | +| Generated-extension browser/headless compatibility matrix | 9 acceptance checks, 11 CLI subprocess receipts; exit 0 | 24.301 s | +| Existing publisher/lifecycle/connection browser regression | 11 checks; exit 0 | 14.119 s | + +The build ran with the four changes later committed in `79f2d9f` still dirty; +its source bytes match that commit. Final focused, worker and both browser runs +used clean `79f2d9f`. The earlier first matrix attempt at `eab93c3` failed: +root `--version` swallowed an extension pin and printed `1.6.0` with exit 0. +Scoped positional parsing and a CLI regression test fixed this real failure. +That failed receipt/log remains `.qa/recovery/compat-e2e.{json,log}`; it is not +counted as passing evidence. Execution completed without task interruption. + +## Acceptance observations + +- Signed immutable releases were published in this order: `1.10.0`, `1.9.0`, + `0.5.0`, `20.0.0-beta.1`, `9.0.0` (requires engine `>=9`). The actual engine + is `1.6.0`, API 1. One browser Install after connection selected `1.10.0`. + Publication order and preview precedence did not override compatibility. +- The selected destination was a second Python project without `package.json`. + Its real graph contained `event:order.created → send_receipt`, with the + version-specific `Python event dispatch 1.10.0` edge label. The first + connected project had no extension contribution. +- An extension having only an engine `>=9` release produced a useful failure, + disabled Install, and preserved existing config and graph. Direct bridge + commands and the CLI also failed without mutation. +- Headless automatic installation selected the same `1.10.0`. Exact `9.0.0` + failed with a compatibility error; no version was substituted. Updating a + missing ID also failed. +- Explicit `20.0.0-beta.1` installed only when pinned. Automatic update from + that preview refused a downgrade and preserved config/graph. An explicit + `1.9.0` pin then selected exactly that lower version. +- A compatible but broken `2.0.0` update failed activation and retained + `1.10.0` and its graph. A valid `3.0.0` update succeeded in browser and CLI, + removed stale version labels and still skipped incompatible `9.0.0`. +- Exact artifact URL `1.9.0` and local file `1.10.0` installations remained + exact. Removal cleared their graph contributions. +- Unit checks reject wrong downloaded IDs/versions, unsupported APIs, + incompatible actual manifests, integrity mismatches, duplicate catalog + versions and stale preview bindings. They exercise disjoint engine ranges, + prerelease engine semantics, invalid catalog data and the under-lock + no-downgrade guard. +- The retained browser regression passed signed form publication, ownership, + invalid-signature/malformed-package failure states, selected-project install, + update rollback, stale cleanup, disable/enable/remove and real wrong-window/ + wrong-origin postMessage rejection. No browser page errors were recorded. + +Desktop and mobile screenshots were visually inspected; selected version, +compatibility and destination are visible and the mobile viewport does not +scroll horizontally. The capture includes local validation-only publisher data. + +![Desktop compatible selection](extensions-compatibility-20260922/desktop-selected.png) + +![Mobile installed compatible release](extensions-compatibility-20260922/mobile-selected.png) + +## Remaining gates + +This closes compatible registry resolution for the Linux/local preview, not +full product completion. Next bounded step: process-kill and stale-lock recovery, +including interrupted configuration/database transitions. Actual Windows/macOS, +hosted HTTPS-to-loopback acceptance, durable registry SQLite/artifact storage, +backup/restart checks and Vercel integration remain unverified. + +Drupal extraction/runtime source and the three-corpus evidence were unchanged +and reused: nine selected flow probes, deterministic rebuild and incremental +convergence; Express control graph unchanged. Drupal rebuild overhead remains +**22–30%** versus built-in in the measured runs, with limited samples and coverage. +No exhaustive precision/recall or agent A/B claim is made. Author-kit acceptance +at `8b30afb` remains separate from this generated-template compatibility matrix. +The **4,545 passed / 192 skipped** suite at `07b0a10` predates both later milestones +and is not a current whole-suite result. No hosted CI pass is claimed. + +Code-complete: full product partial. Validated: this Linux/local milestone passed. +Hosted preview-ready: unverified. Released: no. diff --git a/docs/validation/extensions-compatibility-20260922/desktop-selected.png b/docs/validation/extensions-compatibility-20260922/desktop-selected.png new file mode 100644 index 000000000..b2ccc3097 Binary files /dev/null and b/docs/validation/extensions-compatibility-20260922/desktop-selected.png differ diff --git a/docs/validation/extensions-compatibility-20260922/mobile-selected.png b/docs/validation/extensions-compatibility-20260922/mobile-selected.png new file mode 100644 index 000000000..9f9c25df6 Binary files /dev/null and b/docs/validation/extensions-compatibility-20260922/mobile-selected.png differ diff --git a/docs/validation/extensions-recovery-20260922.md b/docs/validation/extensions-recovery-20260922.md index 1aceb22bb..bf666c168 100644 --- a/docs/validation/extensions-recovery-20260922.md +++ b/docs/validation/extensions-recovery-20260922.md @@ -214,8 +214,10 @@ Per-repository records, hashes and all nine raw responses are under author tests and a fresh generated-extension publish/install/removal exercise. See [author acceptance](extensions-author-20260922.md) for its separate evidence and limits; the original recovery scripts alone did not satisfy this gate. -- The catalog selects the most recently published release. Installation rejects - incompatible engine ranges but does not resolve an older compatible release. +- The compatible-version gap was subsequently closed for Linux/local in + `79f2d9f`: browser and headless registry installs select the highest compatible + stable semver; exact pins and automatic no-downgrade updates are verified. + See [compatible release acceptance](extensions-compatibility-20260922.md). - Exception rollback is tested. Process termination between config/database writes and stale `operation.lock` recovery are not completed crash guarantees. - Only Linux was exercised. Native Windows/macOS installation, worker loading,