docs: document the library API and karet integration contract - #108
Merged
Merged
Conversation
`CreatedWorktree::submodule_seeding` is a public field, but its type lived in the private `service` module and was never re-exported — so an embedder could read the field and had no way to name what it got back. A crate-internal test cannot catch that, since `service` is visible in-crate, so the regression guard is a doctest: it compiles as its own crate and fails exactly when an outcome struct exposes a type the public API does not export. `RemovedWorktree` gains `#[non_exhaustive]`, matching `CreatedWorktree` and `SubmoduleSeeding`. Both types are unreleased — neither is in v1.5.0 and the v1.6.0 release PR is still open — so sealing it now costs no consumer a break, whereas leaving it open makes every field added later a breaking change. The module doc also stops linking to the private `service` and `rows` modules, which rustdoc could not resolve. Claude-Session: https://claude.ai/code/session_014ce9P64RKbVU6kj3GmA1mo
An embedder reading the signatures cannot see the rules that matter most: which module owns path resolution and why reimplementing it is a bug, what each `wt.<branch>.*` key means and which changes to the namespace are safe without a schema bump, and how the crate splits into an application surface and an engine. Documents that on the items themselves, so the README is not the only source. Also clears the remaining rustdoc warnings, leaving `cargo doc --no-deps` clean: two redundant explicit link targets and a link to a private field. Claude-Session: https://claude.ai/code/session_014ce9P64RKbVU6kj3GmA1mo
The README covered only the CLI, so the embedding surface existed solely as Cargo.toml comments and rustdoc — nothing a consumer would find before depending on the crate. Adds a "Using wt as a library" section covering what karet depends on: consuming the crate with `default-features = false` and what that drops, the `Workspace` API and the no-prompting/no-stdout contract that makes it embeddable, resolving worktree paths through the template module rather than reimplementing the layout, the `wt.<branch>.*` metadata contract and the `wt.schema` gate, the locking rules (including what a caller must not hold a lock across), and the generation/work split. The worked example is extracted from the README and compiled against the library with `default-features = false`, then run against a real repository, rather than written by hand — which is how the `Option<String>` branch field got caught. Claude-Session: https://claude.ai/code/session_014ce9P64RKbVU6kj3GmA1mo
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.
Documents the surface
karetconsumes, and closes two holes in it thatwriting the documentation exposed.
Closes #101
Why there was nothing to point karet at
The embedding surface exists — feature gates (#94), the stateless
WorkspaceAPI (#95),
wt.schemaand the advisory lock (#99) — but it was never writtendown anywhere a consumer would look. The README's 295 lines never mentioned
cargo features,
default-features = false,Workspace, thewt.<branch>.*keys,
SCHEMA_VERSIONor locking. The only records were comments inCargo.tomland rustdoc on individual items.What is documented
A new
## Using wt as a libraryREADME section covering #101's six topics, andrustdoc on the items themselves so the README is not the only source:
default-features = false;wt::…despite thekono-wtpackagesrc/lib.rsWorkspace, and the no-prompting/no-stdout contract that makes it embeddablesrc/worktree/mod.rssrc/template.rswt.<branch>.*keys, what is additive-safe, and thewt.schemagatesrc/config/wtconfig.rsRepoLockTwo API holes this turned up
SubmoduleSeedingwas unnameable.CreatedWorktree::submodule_seedingisa public field, but its type lived in the private
servicemodule and wasnever re-exported — an embedder could read the field and had no way to name
what it got back. Proved from outside the crate before fixing:
No crate-internal test can catch this, because
serviceis visible in-crate.The guard is therefore a doctest, which compiles as its own crate — it
fails exactly when an outcome struct exposes a type the public API does not
export. Verified it has teeth by reverting the export: the doctest fails with
the same unresolved import.
RemovedWorktreewas not#[non_exhaustive], unlike its siblingsCreatedWorktreeandSubmoduleSeeding. Sealing it is safe now and notlater: neither type is in v1.5.0 and the v1.6.0 release PR (#103) is still
open, so no published consumer can break — whereas leaving it open makes every
field added afterwards a breaking change.
The example is compiled, not written
The worked example is extracted from the README, compiled against this branch
as an external crate with
default-features = false, and then run against areal repository. It creates a worktree at the template path and records
metadata:
That is what caught the one defect in the prose:
Worktree::branchisOption<String>, so the obvious listing loop does not compile. A READMEsnippet nothing builds is how documentation rots, and this section is the one
karet will follow literally.
The same scratch crate also confirms every type the prose names is reachable
with the default features off.
Also: rustdoc is now warning-free
cargo doc --no-depsemitted 5 warnings on master, three of them broken linksin the public API being documented here (
worktreelinked to the privateserviceandrowsmodules;JobKeylinked to a private field). All 5 arefixed; the command is clean.
Validation
mise run testmise run lint-D warnings)mise run format-checkmise run check-core--no-default-features) + 621 (--features cli) passedmise run coveragecargo doc --no-depsdefault-features = falseNote for the reviewer
The
#[non_exhaustive]addition is only non-breaking while #103 is unmerged.If #103 lands before this does, that one line needs revisiting — the rest of
the PR is unaffected.