Skip to content

core: finish the public-path freeze — ten pub mod + barrel sites, and two unreferenced capsule-i18n functions #480

Description

@justin13888

Found by the API audit on the integration head (#479), which is the first tree that held every
lane of the 2026-09 programme at once.

1. The #399 freeze is incomplete — ten sites, ~110 types at two public paths

#399 converted most of capsule-core to pub(crate) mod + pub use, which gives one canonical
path per type. Ten sites still pair a pub mod with a re-export of the same items from the
parent, so every listed item resolves at two paths:

# Site Duplicated
1 capsule-core/src/backup/mod.rs:15,17-25 artifact::* — 10 items
2 capsule-core/src/crypto/mod.rs:22,26,33 hash, primitives, verify_asset — and only these 3 of 14, so the crate is inconsistent about which crypto types get a short alias
3 capsule-core/src/crypto/encryption/mod.rs:14-28 blob, keywrap, rekey, stream — 21 items
4 capsule-core/src/crypto/provenance/mod.rs:13-22 action, manifest, record — 13 items
5 capsule-core/src/crypto/authority/mod.rs:28,42 reference::ReferenceAuthority (its sibling openmls_authority is already private — half-converted)
6 capsule-core/src/exif/mod.rs:1-5 extract, timezone
7 capsule-core/src/ml/mod.rs:45-63 orchestrator, regen, registry, runner — ~37 items, the largest site
8 capsule-core/src/validation/mod.rs:17-24 protocol, structural — notable because validation is part of the ungated sealing surface
9 capsule-core/src/metadata/crdt/mod.rs:13-19 counter, lww, or_set (parent metadata/mod.rs is correctly converted, so the freeze stopped one level short)
10 capsule-core/src/lib.rs:27 + media/mod.rs:75 DerivativeFormat at capsule_core::derivative_format:: and capsule_core::media::. Deliberate and documented, but done with a pub mod rather than a private module or #[doc(hidden)], so the second path leaks

Both paths are live in the tree, not merely reachable: capsule-wasm/src/lib.rs:65 imports the
long form (capsule_core::crypto::encryption::stream::…) while capsule-cli/src/repair.rs:54
imports the short form (capsule_core::exif::{extract_exif, resolve_timezone}).

The converted sites are the template. capsule-core-ffi, capsule-wasm and capsule-i18n are
clean — this is a capsule-core issue only.

2. Two capsule-i18n functions with no caller outside the crate

format_message (capsule-i18n/src/format.rs:80) and format_message_in (:90), both
re-exported at lib.rs:31. Inside the crate format_message is called only by its own tests and
format_message_in only by format_message and Bundle::format; every external consumer goes
through Bundle::format.

Flagged rather than asserted dead: format_message_in is the natural entry point for formatting
a template you already hold rather than a catalog key, which is a plausible intentional API. The
decision is whether that is a supported surface — if yes it wants a caller or a doc example, if
no it wants pub(crate).

3. A ROADMAP wording correction, already applied in #479

The invocation that ordered this audit described cbor, crypto, drop, sharing,
validation, lqip and client_build as cargo features. They are not; they are the ungated
pub mod declarations in capsule-core/src/lib.rs, and what keeps them in the
--no-default-features build is the absence of a #[cfg(feature = …)], not a flag.
cargo check -p capsule-core --no-default-features --features cbor,… fails with
"does not contain these features". The surface itself is intact — plain
--no-default-features compiles, and the set is one larger than the seven
(derivative_format is also ungated, deliberately). ROADMAP.md now records it as modules.

Not in scope here

Whether capsule_core::{culling, federation, ml, media, utils, constants} should narrow to
pub(crate): each is used by capsule-core's own internals and has no external consumer, but
design/module-map.md:53-58 names culling, federation and ml as contract-owning modules,
so that is a design call rather than a mechanical one.

One concrete item that is mechanical: capsule-server/src/upload/policy.rs:43-48 restates
DERIVATIVE_CONTENT_TYPES with a comment saying it should be
capsule_core::derivative_format::DerivativeFormat::STILL_DELIVERY_ORDER mapped through mime()
but that the module "is not reachable from this crate yet: it exists only on the branch of #436".
It is reachable now — #436 is merged and the module is ungated, which is why the server can link
it with default-features = false. The stated blocker has cleared.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions