Skip to content

Foundation for stable gix (crate) - #3061

Draft
Sebastian Thiel (Byron) wants to merge 3 commits into
mainfrom
stable-gix
Draft

Sebastian Thiel (Byron) wants to merge 3 commits into
mainfrom
stable-gix

Conversation

@Byron

@Byron Byron commented Oct 14, 2026

Copy link
Copy Markdown
Member

Tasks

  • refackiew

Stable facade crates need to retain plumbing implementations internally while
restricting their public API. Add `unstable` and `unstable_fields` attributes
that lower visibility without removing storage or internal calls. Their reasons
appear in experimental API documentation. Trait implementations are gated as a
whole because Rust has no crate-private trait implementations.

Provide `unstable_module!` for file-backed modules, whose attribute form requires
a compiler newer than the workspace MSRV. Isolated downstream compile checks
cover feature-off internal access, feature-on public access, gated trait impls,
fields and methods, and invalid reasons.

Validation: `cargo test -p gix-macros`.
Private plumbing updates should not force a major release of a stable facade.
Add opt-in `smart-release` metadata and explicit stable feature profiles for
`gix-lock` and `gix-tempfile`. Gate their plumbing re-exports and configurable
directory creation behind `unstable`, make extensible public types
non-exhaustive, and adapt workspace consumers in the same change.

Add a release checker to `gix-testtools`, reusing its existing JSON support.
Compare fresh rustdoc APIs from the current tree and release tag with
`cargo-semver-checks`, normalized type signatures, and public dependency
identities. Reject failed checks, unsupported JSON schemas, ambiguous dependency
identities, and accidental activation of excluded features. Keep `gix-error`
public while its own stabilization remains pending.

Validation: pilot tests with experimental APIs and signals, doctests, isolated
stable consumers, strict docs, checker unit tests and Clippy. Real controls show
that private dependency changes and gated return-type changes remain compatible,
while public dependency changes and stable return-type changes are breaking.

End-to-end validation used the modified `cargo smart-release`, this checker,
real `cargo-semver-checks`, and Git release tags in disposable workspaces.
A private `leaf/unstable` dependency moving from 0.2 to 0.3 kept the facade and
client at 1.2.4; exposing `leaf::Thing` instead required 2.0.0 for both.
Both dry runs preserved Git status and HEAD.
@Byron Sebastian Thiel (Byron) changed the title Foundation for stable Gix Foundation for stable gix (crate) Oct 14, 2026
Establish a small API baseline that can grow without committing to unstable
plumbing types. Gate re-exports, fields, methods, and trait implementations with
explicit reasons. Preserve internal access and use a private object-access
adapter where public plumbing trait implementations cannot remain visible.

Keep repository opening, initialization, discovery, paths, and selected options
available. Make repository kind and format version non-exhaustive, and update
workspace consumers to opt into experimental APIs. Keep `gix-error` APIs
available as an explicit exception until that crate is stabilized.

Document the complete reachable API contract, feature unification, construction
and matching decisions, downcasts, and the gradual stabilization workflow in
`gix/AGENTS.md` and `STABILITY.md`. Add isolated downstream compile probes and
blocking CI audits for minimal and rich stable feature profiles.

Validation: all 633 `gix` tests with blocking networking, doctests, stable and
experimental consumer probes, strict rustdoc for both API modes, public API
allowlist audits, workspace all-target checking, and target-only strict Clippy.
Macro tests and the minimal stable `gix` build also pass on Rust 1.88.

CI follow-up: the `stable API boundary` job on PR #3061 correctly rejected the
experimental consumer, but its diagnostic assertions failed because the Ubuntu
runner does not install `rg`. Use portable `grep -Fq` for these literal checks.
The isolated stable/experimental probe passes locally with CI's forced-color
settings, without requiring ripgrep in the script.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants