Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 110 additions & 28 deletions vs-code-terraphim-it/scripts/verify_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ class NotIndexed(ValueError):
"""The exact qualified version is not yet offered in this catalog."""


class CatalogReadError(ValueError):
"""Retain the bounded public response when discovery cannot complete."""

def __init__(self, message, evidence):
super().__init__(message)
self.evidence = evidence


IDENTIFIER_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9_-]*")


Expand Down Expand Up @@ -100,11 +108,44 @@ def require_trusted_publication(metadata):
raise ValueError("Open VSX does not attest trusted publishing for this exact version")


def gallery_query(manifest):
"""Use the same exact-ID query and version/assets flags as Gallery clients."""
def gallery_query(manifest, *, latest_prerelease=False):
"""Request version/assets metadata, including the documented latest-channel mode."""
publisher, name, _ = identity(manifest)
return {"filters": [{"criteria": [{"filterType": 7, "value": f"{publisher}.{name}"}],
"pageNumber": 1, "pageSize": 100}], "flags": 147}
"pageNumber": 1, "pageSize": 100}],
# IncludeLatestPrereleaseAndStableVersionOnly (65536) replaces
# IncludeVersions (1); keep files (2), properties (16), asset URI (128).
"flags": 65682 if latest_prerelease else 147}


def catalog_modes(registry):
"""Use an official client discovery fallback only after an absent version."""
return ("query",) + {"cursor": ("latest-prerelease",),
"windsurf": ("latest-resource",)}.get(registry, ())


def catalog_request(registry, manifest, mode):
"""Describe anonymous supported client routes; latest is discovery, not admission."""
if mode not in catalog_modes(registry):
raise ValueError("Unsupported catalog discovery mode")
publisher, name, _ = identity(manifest)
if mode == "latest-resource":
# Released Windsurf/Devin's ExtensionLatestVersionUriTemplate:
# <serviceUrl>/{publisher}/{name}/latest -> full IRawGalleryExtension.
return {"method": "GET", "url": GALLERY_URLS[registry].removesuffix("/extensionquery")
+ f"/{publisher}/{name}/latest"}
return {"method": "POST", "url": GALLERY_URLS[registry],
"request": gallery_query(manifest, latest_prerelease=mode == "latest-prerelease")}


def catalog_response(raw, mode):
"""Normalize the official resource envelope before the same exact-version checks."""
metadata = json.loads(raw)
if mode == "latest-resource":
if not isinstance(metadata, dict):
raise ValueError("Latest-resource response must be full extension metadata")
metadata = {"results": [{"extensions": [metadata]}]}
return metadata


def catalog_version(metadata, manifest, registry):
Expand Down Expand Up @@ -163,28 +204,74 @@ def catalog_download(selected, manifest, registry):
return url


def read_catalog(registry, manifest, root):
"""Anonymous, bounded read-only POST; never inherit curl config or credentials."""
def read_catalog(registry, manifest, root, mode="query"):
"""Bounded anonymous read. HTTP errors, including rate limits, are never retried here."""
spec = catalog_request(registry, manifest, mode)
request = root / "query.json"
response = root / "catalog.json"
request.write_text(json.dumps(gallery_query(manifest)))
result = subprocess.run([
"curl", "--disable", "--fail", "--silent", "--show-error", "--proto", "=https",
headers = root / "headers.txt"
evidence = {**spec, "mode": mode, "requestCacheControl": "no-cache",
"checkedAt": datetime.now(UTC).isoformat()}
command = [
"curl", "--disable", "--silent", "--show-error", "--proto", "=https",
"--connect-timeout", "15", "--max-time", "60", "--max-filesize", str(8 * 1024 * 1024),
"--request", "POST", "--header", "Content-Type: application/json",
"--header", "Accept: application/json;api-version=7.2-preview.1",
"--header", "Cache-Control: no-cache",
"--data-binary", "@" + str(request), "--output", str(response),
"--write-out", "%{http_code}", GALLERY_URLS[registry],
], text=True, capture_output=True, timeout=70, check=False)
"--request", spec["method"], "--header", "Content-Type: application/json",
"--header", "Accept: application/json;api-version=7.2-preview"
+ ("" if mode == "latest-resource" else ".1"),
"--header", "Cache-Control: no-cache", "--dump-header", str(headers),
"--output", str(response), "--write-out", "%{http_code}",
]
if "request" in spec:
request.write_text(json.dumps(spec["request"]))
command.extend(["--data-binary", "@" + str(request)])
command.append(spec["url"])
try:
result = subprocess.run(command, text=True, capture_output=True, timeout=70, check=False)
except subprocess.SubprocessError as error:
raise CatalogReadError("Anonymous catalog request did not complete", evidence) from error
raw = response.read_bytes() if response.exists() else b""
evidence.update(httpStatus=result.stdout, curlCode=result.returncode,
responseSha256=hashlib.sha256(raw).hexdigest(), responseBytes=len(raw),
responseBody=raw.decode("utf-8", errors="replace"))
# Retain only Retry-After, never cookies or other incidental response headers.
if headers.exists():
evidence["retryAfter"] = [line.partition(":")[2].strip()
for line in headers.read_text(errors="replace").splitlines()
if line.lower().startswith("retry-after:")]
if result.returncode or result.stdout != "200":
raise ValueError(f"Anonymous catalog query failed: HTTP {result.stdout}; curl {result.returncode}")
raw = response.read_bytes()
metadata = json.loads(raw)
return metadata, {"url": GALLERY_URLS[registry], "request": gallery_query(manifest),
"requestCacheControl": "no-cache",
"responseSha256": hashlib.sha256(raw).hexdigest(), "responseBytes": len(raw),
"responseBody": raw.decode("utf-8")}
raise CatalogReadError(
f"Anonymous catalog request failed: HTTP {result.stdout}; curl {result.returncode}; "
"no automatic HTTP retry (honor any recorded Retry-After)", evidence)
try:
metadata = catalog_response(raw, mode)
except (ValueError, TypeError) as error:
raise CatalogReadError("Catalog response is not valid extension metadata", evidence) from error
return metadata, evidence


def discover_version(registry, manifest, root, attempts):
"""Record every actual response; fallback only for an absent exact version."""
for mode in catalog_modes(registry):
directory = root / mode
directory.mkdir()
try:
metadata, evidence = read_catalog(registry, manifest, directory, mode)
except CatalogReadError as error:
error.evidence.update(status="FAILED", error=str(error))
attempts.append(error.evidence)
raise
attempts.append(evidence)
try:
selected = catalog_version(metadata, manifest, registry)
except NotIndexed as error:
evidence.update(status="NOT_INDEXED", error=str(error))
continue
except (ValueError, KeyError, TypeError, AttributeError, IndexError) as error:
evidence.update(status="FAILED", error=str(error))
raise
evidence.update(status="INDEXED", version=selected)
return selected
raise NotIndexed("Exact universal version is absent from all supported catalog discovery routes")


def qualify(package, manifest):
Expand Down Expand Up @@ -229,18 +316,13 @@ def main():
for attempt in range(args.attempts):
directory = root / str(attempt)
directory.mkdir()
metadata, evidence = read_catalog(args.registry, expected, directory)
evidence["checkedAt"] = datetime.now(UTC).isoformat()
result["attempts"].append(evidence)
try:
selected = catalog_version(metadata, expected, args.registry)
except NotIndexed as error:
evidence.update(status="NOT_INDEXED", error=str(error))
selected = discover_version(args.registry, expected, directory, result["attempts"])
except NotIndexed:
if attempt + 1 == args.attempts:
raise
time.sleep(args.delay)
continue
evidence.update(status="INDEXED", version=selected)
break
url = catalog_download(selected, expected, args.registry)
if args.registry == "openvsx":
Expand Down
6 changes: 6 additions & 0 deletions vs-code-terraphim-it/tests/fixtures/registries/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
Public anonymous exact-ID catalog responses captured on 14 October 2026. Microsoft offered 0.1.3; Cursor and Windsurf offered 0.1.0. These are parser fixtures, not mocked services or evidence of a later publication. Live CI queries every registry again.

`cursor-latest-prerelease-014.json` is the anonymous 15 October 2026 response to the same exact-ID query with flags `65682` (files, properties, asset URI and Microsoft's documented `IncludeLatestPrereleaseAndStableVersionOnly`). It offers prerelease 0.1.4 while the original flags-147 query still returned 0.1.0. The verifier retains both responses and still requires the exact qualified version and downloaded payload.

The Windsurf latest-resource parser test reuses the full extension object from the captured Windsurf catalog response. It tests the official client's `IRawGalleryExtension` envelope and exact-version refusal; it does not claim a successful live latest-resource request. CI performs that request separately.

Primary contracts: [Microsoft query flags](https://learn.microsoft.com/en-us/javascript/api/azure-devops-extension-api/extensionqueryflags?view=azdevops-ext-latest), and [`getLatestRawGalleryExtension` in the official VS Code client](https://github.com/microsoft/vscode/blob/main/src/vs/platform/extensionManagement/common/extensionGalleryService.ts). The released Windsurf/Devin client advertises `<serviceUrl>/{publisher}/{name}/latest`; latest metadata is only a discovery candidate, never permission to accept another version.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"results":[{"extensions":[{"extensionId":"01a1397c-abbb-7196-a7d0-5f21bae87581","extensionName":"terraphim-it","displayName":"Terraphim It","shortDescription":"Intelligent Markdown editor with alternatives, knowledge-graph synonyms and role-based suggestions","publisher":{"displayName":"applied-knowledge-systems","publisherId":"01a1397c-abbf-7660-af01-72a592315dce","publisherName":"applied-knowledge-systems","domain":"","isDomainVerified":false},"versions":[{"version":"0.1.4","lastUpdated":"2026-10-15T07:26:45.552045Z","assetUri":"https://marketplace.cursorapi.com/open-vsx-mirror/vscode/asset/applied-knowledge-systems/terraphim-it/0.1.4","fallbackAssetUri":"https://marketplace.cursorapi.com/open-vsx-mirror/vscode/asset/applied-knowledge-systems/terraphim-it/0.1.4","files":[{"assetType":"Microsoft.VisualStudio.Code.Manifest","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/package.json"},{"assetType":"Microsoft.VisualStudio.Services.Content.Details","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/readme.md"},{"assetType":"Microsoft.VisualStudio.Services.Content.License","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/LICENSE.txt"},{"assetType":"Microsoft.VisualStudio.Services.VSIXPackage","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/applied-knowledge-systems.terraphim-it-0.1.4.vsix"},{"assetType":"Microsoft.VisualStudio.Services.Content.Changelog","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/changelog.md"},{"assetType":"Microsoft.VisualStudio.Services.VsixManifest","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/extension.vsixmanifest"},{"assetType":"Microsoft.VisualStudio.Services.VsixSignature","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/applied-knowledge-systems/terraphim-it/0.1.4/file/applied-knowledge-systems.terraphim-it-0.1.4.sigzip"},{"assetType":"Microsoft.VisualStudio.Services.PublicKey","source":"https://marketplace.cursorapi.com/open-vsx-mirror/api/-/public-key/14ccb407-4e79-41ed-be5a-6d608325c45a"}],"properties":[{"key":"Microsoft.VisualStudio.Services.Branding.Color","value":""},{"key":"Microsoft.VisualStudio.Services.Branding.Theme","value":""},{"key":"Microsoft.VisualStudio.Services.Links.Source","value":"https://github.com/terraphim/terraphim-ai.git"},{"key":"Microsoft.VisualStudio.Code.SponsorLink","value":""},{"key":"Microsoft.VisualStudio.Code.Engine","value":"^1.126.0"},{"key":"Microsoft.VisualStudio.Code.ExtensionDependencies","value":""},{"key":"Microsoft.VisualStudio.Code.ExtensionPack","value":""},{"key":"Microsoft.VisualStudio.Code.LocalizedLanguages","value":""},{"key":"Microsoft.VisualStudio.Code.PreRelease","value":"true"}],"targetPlatform":"universal"}],"statistics":[],"tags":[],"releaseDate":"2026-10-14T08:17:11.286382Z","publishedDate":"2026-10-14T08:17:11.286382Z","lastUpdated":"2026-10-15T07:28:03.027714Z","categories":["AI","Other","Snippets"],"flags":""}],"resultMetadata":[{"metadataType":"ResultCount","metadataItems":[{"name":"TotalCount","count":1}]}]}]}
57 changes: 57 additions & 0 deletions vs-code-terraphim-it/tests/verify_registry_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,63 @@ def test_real_stale_and_revalidated_catalogs_do_not_conflate_publication_with_in
self.assertEqual(registry.catalog_download(selected, manifest, "openvsx"),
"https://open-vsx.org/api/applied-knowledge-systems/terraphim-it/0.1.4/file/applied-knowledge-systems.terraphim-it-0.1.4.vsix")

def test_captured_cursor_prerelease_query_exposes_exact_released_version(self):
manifest = {**verify_vsix_test.VsixTest.manifest, "version": "0.1.4"}
with self.assertRaises(registry.NotIndexed):
registry.catalog_version(self.fixture("cursor"), manifest, "cursor")
data = self.fixture("cursor-latest-prerelease-014")
selected = registry.catalog_version(data, manifest, "cursor")
self.assertEqual(selected["version"], "0.1.4")
self.assertIn("/0.1.4/", registry.catalog_download(selected, manifest, "cursor"))
# A latest-channel response cannot qualify a different frozen version.
with self.assertRaises(registry.NotIndexed):
registry.catalog_version(data, {**manifest, "version": "0.1.3"}, "cursor")
selected["properties"] = [{"key": registry.PRERELEASE_PROPERTY, "value": "false"}]
with self.assertRaisesRegex(ValueError, "prerelease channel"):
registry.catalog_version(data, manifest, "cursor")

def test_supported_fallbacks_preserve_exact_identity_and_channel_metadata(self):
manifest = verify_vsix_test.VsixTest.manifest
self.assertEqual(registry.catalog_modes("marketplace"), ("query",))
self.assertEqual(registry.catalog_modes("openvsx"), ("query",))
self.assertEqual(registry.catalog_modes("cursor"), ("query", "latest-prerelease"))
self.assertEqual(registry.catalog_modes("windsurf"), ("query", "latest-resource"))
original = registry.catalog_request("cursor", manifest, "query")
latest = registry.catalog_request("cursor", manifest, "latest-prerelease")
self.assertEqual(original["request"]["flags"], 147)
self.assertEqual(latest["request"]["flags"], 65682)
self.assertEqual(original["request"]["filters"], latest["request"]["filters"])
self.assertEqual(registry.catalog_request("windsurf", manifest, "latest-resource"), {
"method": "GET",
"url": "https://marketplace.windsurf.com/vscode/gallery/applied-knowledge-systems/terraphim-it/latest",
})
for name, mode in [("marketplace", "latest-resource"), ("openvsx", "latest-prerelease"),
("cursor", "latest-resource"), ("windsurf", "latest-prerelease")]:
with self.subTest(name=name, mode=mode), self.assertRaises(ValueError):
registry.catalog_request(name, manifest, mode)
for key, value in [("publisher", "../escape"), ("name", "x?token=x"), ("version", "latest")]:
with self.subTest(key=key), self.assertRaises(ValueError):
registry.catalog_request("windsurf", {**manifest, key: value}, "latest-resource")

def test_resource_envelope_still_requires_full_exact_version_metadata(self):
# Same IRawGalleryExtension contract returned by the official latest
# resource route; use captured catalog metadata, not an invented package.
extension = self.fixture("windsurf")["results"][0]["extensions"][0]
manifest = verify_vsix_test.VsixTest.manifest
data = registry.catalog_response(json.dumps(extension), "latest-resource")
selected = registry.catalog_version(data, manifest, "windsurf")
self.assertIn("/0.1.0/", registry.catalog_download(selected, manifest, "windsurf"))
with self.assertRaises(registry.NotIndexed):
registry.catalog_version(data, {**manifest, "version": "0.1.4"}, "windsurf")
for raw in ["null", "[]", '"asset URL"']:
with self.subTest(raw=raw), self.assertRaises(ValueError):
registry.catalog_response(raw, "latest-resource")
for change in [{"publisher": {"publisherName": "other"}}, {"versions": []},
{"versions": [{"version": "0.1.0", "files": selected["files"]}]}]:
data = registry.catalog_response(json.dumps({**extension, **change}), "latest-resource")
with self.subTest(change=change), self.assertRaises((ValueError, KeyError)):
registry.catalog_version(data, manifest, "windsurf")

def test_catalog_rejects_ambiguous_channel_platform_and_validation(self):
original = self.fixture("marketplace")
manifest = {**verify_vsix_test.VsixTest.manifest, "version": "0.1.3"}
Expand Down
Loading