Repository navigation
v2: resolve the parity gate's #499/#500 surface before the lock (codes generated in all four; one shape per concept) - #608
Merged
Conversation
- Error codes are generated from spec/fetch-v1/constants.json in every binding (scripts/fetch-v1/gen-constants.py): Go's public ErrorCode is a type of the package's own (go/chtypes/codes_gen.go) with no ExitCode or Sentinel method; Python's CODE_* come from the generated chtypes._codes; Rust gains chtypes::code::*, which Error::code returns. - Go: ArtifactError keeps Code and the refusal and cache-fault fields; the message, the cause and the request, platform and source fields are no longer exported (Error(), errors.Unwrap). Every fetch error's message names the request, the platform and the source it concerns, and a test pins it. FetchOptions.ConnectTimeout and IdleReadTimeout are removed. Format.CHName is Format.ChName. - Python: chtypes.errors.internal and misuse are private (#499); SourceUnreachableError loses retryable and retry_after; TrustedKey is no longer public and FetchOptions.trusted_keys takes hex keys. - Rust: Refusal.detail is removed (a one-sided finding is in got, as in the other bindings) and Refusal is #[non_exhaustive]; the fetch layer's own corruption has an empty reason; FetchOptions.platform is removed; reason::is_lossy is reason::lossy. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tion notes - TypeScript: ArtifactError carries reason, path, want and got, as Go's and Python's do; LoaderCorruptError and LoaderErrorFields go (the loader's corrupt refusal is an ArtifactCorruptError); isChtypesError, exitStatus, retryAfterRefused, BatchOutcome and batchOutcomeKnown are removed; the CODE_* constants and ErrorCode are exported, generated from the fetch constants. FetchOptions is an interface of its own, so the gate reads its fields: trustedKeys takes hex keys, and platform and lockAllPlatforms are gone (a registry opens for this host; CHTYPES_TARGET stays the CLI's). - Python and TypeScript ignore the trusted keys where the channel honors no trust override, without validating them, as Go and Rust do. - Rust registry unit tests open for the host, now that FetchOptions has no platform. - bindings-v1.md: §3 gains the discover_query_param row and the TypeScript free-function rule for facts; §4 gains the codes table and says where each binding carries a loader refusal's fields; §6 says the trusted keys are hex and that no option names a platform or a timeout. The per-language pages and the Go and TypeScript tours follow. - parity-surface.py reads §4's codes table (header `code`) as it reads an operation table; the allowlist drops every entry #499, #500 and #487 cited and keeps the four TypeScript fact spellings as the documented idiom. - Each binding's CHANGELOG carries a migration note, old to new. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Summary
The parity gate (#436) carried each binding's one-binding conveniences and shape differences as allowlist entries citing #499, #500 and #487. 2.0.0 is the last window before the v2 lock for removing or renaming public binding API, so this PR resolves every one of them, following the ruled table. A convenience exists in every binding or in none (
docs/reference/bindings-v1.md§1, principle 2). Every removed allowlist entry goes with its item, and no entry cites #499, #500 or #487 any more. Each binding's CHANGELOG has a migration note under### Changed, marked Breaking, old → new.Error codes, in all four, generated
scripts/fetch-v1/gen-constants.pygenerates the codes fromspec/fetch-v1/constants.jsoninto every binding, so--checkcovers them and no binding types a code by hand:ErrorCodeplusCode…, as a type of the public package's own (go/chtypes/codes_gen.go, no methods), and ocifetch's ownCode….CODE_*, in the privatechtypes._codes.CODE_*and theErrorCodeunion.chtypes::code::*, whichError::code()returns.bindings-v1.md§4 gains a codes table, and the gate reads it.ErrorCode.ExitCode()and.Sentinel()are removed, and so is TypeScript'sArtifactError.exitStatus. The CLIs keep the exit status internally.Go
ArtifactErrorno longer exportsMsg,Err,Request,PlatformorSource. UseError()anderrors.Unwrap.TestFetchErrorMessageCarriesRequestPlatformSourcepins this, including the"layer: %v"case.FetchOptions.ConnectTimeoutand.IdleReadTimeoutare removed.Format.CHName()is renamedFormat.ChName(), through the generator.Python
chtypes.errors.internalandmisuseare private (Python: chtypes.errors exports internal and misuse helpers through __all__ #499).SourceUnreachableError.retryableand.retry_afterare removed.retry_afterwas never set.TrustedKeyis no longer public.FetchOptions.trusted_keystakes hex keys, as Go and Rust do, and derives each key id.Rust
Refusal.detailis removed. A one-sided finding is now ingot, as the other three already did, andRefusalis#[non_exhaustive].reason(it was"fetch"), as Go's has.FetchOptions.platformis removed.reason::is_lossyis renamedreason::lossy, through the generator.TypeScript
ArtifactErrornow carriesreason,path,wantandgot, as Go and Python do.LoaderCorruptErrorandLoaderErrorFieldsare removed. The loader's corrupt refusal is anArtifactCorruptError.isChtypesErroris removed. Since v2 fetch: zero-request frozen paths (#414), Go frozen re-download, TS lock platforms and error class, Python index duplicates (#487) #606,e instanceof ChtypesErroris the same test.retryAfterRefused,BatchOutcomeandbatchOutcomeKnownare removed.FetchOptionsis now an interface of its own, so the gate reads its fields; an allowlist entry covers them, like the other three bindings' entries.trustedKeystakes hex keys.platformandlockAllPlatformsare removed. A registry opens libraries for this host only, andCHTYPES_TARGETstays the CLI's.Documentation
bindings-v1.md§3 gains thediscover_query_paramrow; all four bindings have that vocabulary on v2.issue.Test plan
Run locally, each gate on its own and unpiped, with its exit status:
go vet ./...: 0.go test ./...with the ABI v2 stubs (CHTYPES_ABI2_STUBS): 0. The Go fetch conformance (TestConformance(V1|ProdV2),TestDevChannel*) againsttests/fixtures/fetch-v1andfetch-v2: 0.uv run pytest -qwith the stubs and both conformance corpora: 0 (712 passed, 3 skipped by name).ruff checkandruff format --check: 0.scripts/fetch-v1/gen-constants.py --selftestand--check: 0.scripts/abi-v1/gen.py --check,--major 2 --checkand--selftest: 0.check-no-hand-decls.py --scope all: 0.scripts/parity-surface.py --selftest: 0.scripts/parity-surface.py run --only go python: 0, green, with no findings and no allowlist problems.policy-merge-check.py --check-ci-namesand--check-guide: 0.lint-public.sh,lint-spelling.sh,lint-cited-paths.sh,check-quoting-passthrough.py,check-no-error-code-table.py,check-reserved-test-names.shandcheck-selftests-wired.py: 0.check-cli-parity.sh goandpython: 0.markdownlint-cli2anddprint check: 0.biome lint(ts): 0.rustfmt --checkon every changed Rust file: 0.golangci-lint: CI only. The local binary was built with an older Go and cannot read Go 1.27.2's export data.Related issues
Closes #499
Closes #500
🤖 Generated with Claude Code