Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RFC-0007: adapter workspace subcrates

Version: 0.1.2 | Status: normative | Phase: impl


1. Summary

[RFC-0007:C-SUMMARY] Summary (Informative)

This RFC specifies the extraction of built-in adapters from the main typub crate into separate workspace subcrates.

Scope:

  • Defines the target workspace layout with adapter subcrates.
  • Specifies the shared adapter types crate (typub-adapters-core).
  • Specifies crate boundaries and dependency rules.
  • Specifies feature gates for optional adapter inclusion.

Out of Scope:

  • Third-party adapter crates (covered by RFC-0006).
  • Runtime plugin loading.
  • Migration path from current layout (covered by work items).

Rationale: The current monolithic layout has several drawbacks:

  1. All adapters share dependencies, even when only a subset is needed (e.g., Ghost requires JWT crates that others do not).
  2. Adding adapters requires modifying core files (Adapter enum, registry factory array).
  3. Compile times scale with total adapter count rather than enabled adapters.
  4. Testing adapters in isolation is difficult.

Extracting adapters into subcrates enables:

  • Feature-gated inclusion for smaller binaries and faster compiles.
  • Cleaner separation of concerns.
  • First-party and third-party adapters follow the same patterns.
  • Independent testing of each adapter.

References:

  • RFC-0006 — adapter extension API (defines AdapterRegistrar, External variant)
  • ADR-0002 — shared types in typub-core
  • ADR-0003 — extraction of typub-html subcrate

Since: v0.1.0


2. Specification

[RFC-0007:C-WORKSPACE-LAYOUT] Workspace Layout (Normative)

The workspace MUST include the following crates:

  • typub — main CLI binary
  • typub-core — capability types (existing)
  • typub-html — HTML parsing/serialization (existing)
  • typub-adapters-core — shared adapter abstractions (new)

Adapter crates MUST follow the naming convention typub-adapter-{platform_id}.

Adapter crates SHOULD be placed under crates/adapters/ to group related crates:

crates/
├── typub-core/
├── typub-html/
├── typub-adapters-core/
└── adapters/
    ├── typub-adapter-ghost/
    ├── typub-adapter-notion/
    └── ...

The workspace Cargo.toml MUST list all adapter crates as members.

New first-party adapters MAY be added without modifying this RFC, provided they follow the naming convention and placement guidelines above.

Rationale: Consistent naming enables tooling and documentation automation. The crates/adapters/ subdirectory groups related crates without polluting the top-level. Pattern-based rules avoid RFC churn when adding new adapters.

Since: v0.1.0

[RFC-0007:C-SHARED-TYPES] Shared Adapter Types Crate (Normative)

A new crate typub-adapters-core MUST be created to hold shared adapter abstractions.

This crate MUST export:

  • PlatformAdapter trait (moved from src/adapters/mod.rs)
  • AdapterPayload struct
  • PublishContext struct
  • RenderConfig struct
  • OutputFormat enum
  • AdapterCapability struct (with Cow<'static, str> fields per RFC-0006:C-REGISTRAR-API)
  • AdapterRegistrar struct and AdapterFactory type alias per RFC-0006:C-REGISTRAR-API

This crate MUST re-export from dependencies:

  • From typub-core: AssetStrategy, MathRendering, MathDelimiters, DraftSupport, CapabilitySupport, CapabilityGapBehavior
  • From semantic IR crate (typub-html at present): document IR surface required by adapters, including Document, Block, and Inline (or equivalent top-level semantic IR types defined by current RFC baseline)

This crate MUST NOT depend on:

  • Main typub crate (no circular dependency)
  • Any adapter implementation crate

Rationale: A shared types crate provides a stable interface that both the main crate and adapter crates depend on. This avoids circular dependencies and enables third-party adapters to compile against a minimal dependency set. Re-exporting semantic document IR types (instead of legacy HTML-structured node vectors) aligns adapter boundaries with semantic IR v2 and reduces duplicated migration logic.

Since: v0.1.0

[RFC-0007:C-ADAPTER-CRATE] Adapter Crate Structure (Normative)

Each adapter crate MUST:

  1. Implement the PlatformAdapter trait from typub-adapters-core.

  2. Expose a public register(registrar: &mut AdapterRegistrar) function that:

    • Calls registrar.register_factory(platform_id, factory) for the adapter factory.
    • Calls registrar.register_capability(platform_id, capability) for the adapter capability.
    • The platform_id MUST match the crate’s platform identifier (e.g., typub-adapter-ghost"ghost").
  3. Have a Cargo.toml with:

    • name = "typub-adapter-{platform_id}"
    • version matching the workspace version
    • Dependency on typub-adapters-core (not typub)
    • Adapter-specific dependencies (e.g., hmac, jwt for Ghost)
  4. Contain all adapter-specific logic:

    • API client (if applicable)
    • Semantic IR transformations
    • Type definitions

Each adapter crate SHOULD include integration tests that can run independently of the main CLI.

Adding new first-party adapters: Create a new crate following the above structure, add it to workspace members, add a feature gate in main crate, and add the feature-gated register() call to CLI bootstrap.

Rationale: Self-contained adapter crates enable independent testing, versioning, and optional inclusion. The register function provides a uniform entry point consistent with RFC-0006:C-CLI-BOOTSTRAP.

Since: v0.1.0

[RFC-0007:C-DEPENDENCY-RULES] Dependency Rules (Normative)

The following dependency rules MUST be enforced:

Allowed dependencies:

CrateMay depend on
typub-core(none in workspace)
typub-htmltypub-core
typub-adapters-coretypub-core, typub-html
typub-adapter-*typub-adapters-core
typub (main)all of the above

Adapter crates SHOULD depend only on typub-adapters-core, which re-exports needed types from typub-core and typub-html. Direct dependencies on typub-core or typub-html MAY be added only when adapter-specific needs require types not re-exported by typub-adapters-core.

Forbidden dependencies:

CrateMUST NOT depend on
typub-coreany other workspace crate
typub-htmltypub-adapters-core, typub-adapter-*, typub
typub-adapters-coretypub-adapter-*, typub
typub-adapter-*typub, other typub-adapter-* crates

Rationale: Strict layering prevents circular dependencies and ensures adapter crates can compile without the full CLI. No adapter should depend on another adapter to maintain isolation. Preferring typub-adapters-core avoids redundant dependency declarations.

Since: v0.1.0

[RFC-0007:C-FEATURE-GATES] Feature Gates (Normative)

Adapter feature gates in the main typub crate are OPTIONAL.

Implementations MAY use Cargo features to control first-party adapter inclusion, but this RFC does not require a specific feature matrix (for example adapter-all / adapter-{platform}) for conformance.

If feature gates are used, the implementation MUST ensure:

  1. Disabled adapters are not registered at runtime.
  2. Enabled adapters preserve the same runtime semantics as non-feature-gated builds.

If feature gates are not used, the default runtime path MUST still support selective adapter activation via platform configuration (enabled = true/false) and adapter requires_config semantics.

A build with no optional adapter features enabled (when such features exist) SHOULD still compile and provide non-adapter CLI commands (--help, --version). Commands requiring unavailable adapters MUST fail with a clear diagnostic.

Rationale: The current implementation relies primarily on runtime registration/activation semantics. Making feature gates optional avoids constraining implementation to one packaging strategy while preserving behavior guarantees.

Since: v0.1.0

[RFC-0007:C-RFC-0006-COMPAT] RFC-0006 Compatibility (Normative)

This RFC MUST be compatible with RFC-0006 (adapter extension API).

Specifically:

  1. The AdapterRegistrar defined in RFC-0006:C-REGISTRAR-API MUST be implemented in typub-adapters-core.
  2. Each adapter crate’s register() entrypoint (when provided) MUST use the same AdapterRegistrar API surface as extension adapters.
  3. Runtime adapter execution MUST be based on PlatformAdapter trait-object semantics, whether registry construction is registrar-based or factory-table-based.
  4. First-party and extension adapter wiring MUST preserve stable platform-ID behavior and MUST NOT alter semantics for unrelated platform IDs.

Rationale: Compatibility is defined by shared adapter contracts and runtime behavior, not by a single mandatory bootstrap implementation shape.

Since: v0.1.0


Changelog

v0.1.2 (2026-02-22)

Make adapter feature-gate model optional

Added

  • Relax C-FEATURE-GATES from mandatory adapter-all matrix to optional build strategy
  • Update RFC-0006 compatibility clause to behavior-based compatibility

v0.1.1 (2026-02-21)

Adapter wording alignment

Added

  • Replace remaining AST wording with semantic IR terminology in adapter crate responsibilities

v0.1.0 (2026-02-14)

Initial draft

Added

  • Resolve versioning contradiction; loosen workspace layout clause