Repository navigation
v2: a fetch-only registry call (#492), chtypes resolve (#493) and chtypes prune (#494), in all four bindings - #609
Merged
Conversation
…egistry.Fetch and CLI - go/internal/ocifetch: Resolve (what a request resolves to on every platform, verified, no layer), Prune (superseded builds of a line, kept newest N per platform, never a held build, never another fingerprint's), and Hold, the shared flock on an entry's verified.json a registry takes before it loads a build (prune takes the exclusive lock without waiting). - go/chtypes: Registry.Fetch(ctx, request) installs without opening, shares one fetch with a concurrent open, and holds what it returns. - go/cmd/chtypes: chtypes resolve and chtypes prune. - genfixtures: resolve-build-* and prune-* cases in both corpora, with the case-schema fields they need (setup.held, request.prune, expect.resolutions, expect.prune). - scripts/abi-v1/emit/ts.py: flock in the generated TS libc declarations (fingerprint and header unchanged). Refs #492, #493, #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d CLI parity - python: Registry.fetch(request) installs without opening and shares one fetch with a concurrent open; the open path holds what it loads; the fetch layer's resolve, prune and hold (_resolve.py, _prune.py, _hold.py); the chtypes resolve and chtypes prune commands; the conformance runner runs the resolve-build-* and prune-* cases. - docs: fetch-v1.md gains "In use", "Pruning", "What a request resolves to", "The fetch-only call" and "The command line", and the new case kinds in section 10; bindings-v1.md gains the registry's fetch row and the hold in section 6; the per-language references and install notes name the two new commands. - scripts/check-cli-parity.sh: resolve and prune rows, and a planted --keep 0 the selftest must catch. - CHANGELOG: Go and Python. Refs #492, #493, #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hold - ts: registry.fetch(request) installs without opening and shares one fetch with a concurrent open; the open path holds what it loads; the fetch layer's resolveBuilds, prune and hold (flock through the generated libc declaration, which now never reports a failure as 0); chtypes resolve and chtypes prune; a refused spelling exits with the usage status; the conformance runner runs the resolve-build-* and prune-* cases and installs each installed.json build under its own index entry's platform. - rust: Registry::fetch(&self, request) with the same single flight and holds (libc::flock; libc added as a direct dependency, Cargo.lock refreshed); the fetch layer's resolve, prune and hold; chtypes resolve and chtypes prune; the conformance runner and unit tests. - CHANGELOG (TypeScript, Rust) and the Rust README's command list; a scratch prefix the public-repo lint reads as a repository name. Refs #492, #493, #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…andContext - examples/rust/Cargo.lock lists libc in the chtypes package's dependencies, as rust/Cargo.lock does (cargo metadata --offline; the tour runs --locked). - The Go registry fetch tests skip loudly when the fetch fixtures' test key or scripts/fetch-v1/server.py are not beside the module (the bare standalone copy has neither). - hold_test.go starts its helper process with exec.CommandContext (noctx). Refs #492, #493, #494 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pre-lock items #492, #493 and #494, in all four bindings, on
v2. None of them needs a C-ABI entry or argument:fetchandresolverun entirely in each binding's own OCI layer (the library is first touched at load, which neither reaches), and the in-use signal is a file lock on the cache, not an ABI call. The fingerprint and the header are unchanged (gen.py --check,--major 2 --check).What it adds
A fetch-only call (#492). The registry's
fetchis the library counterpart ofchtypes fetch: it resolves, fetches, verifies and installs the build a request names, and opens nothing (nodlopen, no setup, nothing in the memo orlibraries()). It honors the registry's fetch options, its errors are the fetch codes, and it returns the fetch layer'sResolved(version, build, digests, library path).(*Registry).Fetch(ctx context.Context, request string) (Resolved, error)Registry.fetch(request: str) -> Resolvedregistry.fetch(request: string): Promise<Resolved>Registry::fetch(&self, request: &str) -> Result<Resolved>A concurrent
fetchand open of one request share one fetch: the open's fetch now runs through a per-request table of fetches in progress thatfetchuses too (#491's single flight, extended).chtypes resolve <spelling> [--json] [--offline](#493). What the spelling resolves to on every platform the index offers: the index (through the dev channel's alias first), then each platform manifest by digest and its signed statement, verified exactly as a fetch verifies it. No layer is requested and nothing is written. Output, byte-identical in all four CLIs:or, with
--json, one line:[{"platform":"linux-amd64","version":"26.8.15.10","build":"20261001.183455","manifest":"sha256:…"},…].--offlineanswers from the cache (each platform'sresolve_installed); nothing installed isCHTYPES_ARTIFACT_MISSING.chtypes prune [--line <line>] [--keep <n>] [--dry-run](#494). Removes each (platform, line)'s installed builds older than its newestn(default 1): the entry and its record, itsindex.jsonentries, and its blobs (manifest, config, layer, and its referrers with their layers), never a blob a remaining build names. Cache only, never a system directory; on the dev channel only its own fingerprint's builds, so another SDK's are neither removed nor counted. Output:pruned|would-prune|in-use <version> <platform> <dir>lines, then a summary on stderr.The in-use signal (new; the cache had none). A registry holds every build it opens or fetches with
flock(LOCK_SH)on the entry'sverified.json, taken before the library is read and kept until the process exits; prune takesflock(LOCK_EX|LOCK_NB)on the same file and keeps any build it cannot lock, renaming a claimed entry aside before it drops the lock, so a hold taken after finds it gone and the registry looks once more. flock is per open file description, so the same rule holds within one process and across all four bindings; the kernel drops a dead process's locks. TypeScript reaches flock through the generated libc declarations (scripts/abi-v1/emit/ts.py), Rust through thelibccrate.Tests
genfixtures,--abi=2):resolve-build-{line,exact,partial-index,untrusted,unpublished,offline,offline-miss,dev-alias}(every online case forbids each layer GET inrequests.none_matching) andprune-{keep-newest,keep-two,line,dry-run,in-use,system-dirs-never,foreign-fingerprint-untouched,v1-channel-sees-all}. The schema gainssetup.held,request.prune,expect.resolutionsandexpect.prune.fetchinstalls without opening (bytes that are no library: fetch succeeds, nothing loaded, setup not latched), and afetchand an open of one request make one tag GET and one layer GET (the fixture server's gate and log); the CLI's resolve and prune over the fixtures' basic tree; Go also holds a build from a second process and shows prune keeps it until that process exits.Gates
Run locally on darwin-arm64, each alone and unpiped, every one exit 0 (
measured):go test ./...;go test -raceoninternal/ocifetchandchtypes(also with the ABI v2 stubs built bybuild-stubs.sh);TestConformanceV1andTestConformanceProdV2, 325 results over 183 cases each, the 24 new results among them passing.uv run pytest -q(487 passed, 244 skipped without stubs;tests/abi2with the stubs: 285 passed); the conformance suite on both corpora, 325/325 each, 24/24 new;ruff check,ruff format --check.genfixtures --check(v1 and--abi=2) and--selftest;server.py --selftest;schema_check.py;staging.py --selftest;parity.py --selftest.gen.py --checkand--major 2 --check(fingerprintsha256:d60a681e…and header unchanged);gen-constants.py --check;check-no-hand-decls.py --scope all.check-cli-parity.sh --selftest(the new planted--keep 0is caught), andgoandpythonmatchexpected.txt(34 cases);parity-surface.py --selftest,run --only go python(0 findings),--check-issues.lint-public,lint-spelling,lint-cited-paths,lint-actions,check-selftests-wired.py, markdownlint,dprint check,rustfmt --edition 2024 --check;policy-merge-check.py --check-ci-namesand--check-guide.TypeScript and Rust were not built or tested locally (CI only, per the lane rules);
rust/Cargo.lockgains onlylibcin the crate's own dependency list (cargo metadata --offline, no build).Refs #492
Refs #493
Refs #494
🤖 Generated with Claude Code