Repository navigation
[G1] Merge ai-hist-core and ai-hist-engine into one published ai-hist crate with feature gates, a release pipeline and a semver policy #162
Copy link
Copy link
Closed
Description
Part of #160 (group 1 — independent).
Problem
burn is a Rust workspace (relayburn-sdk is published to crates.io) and can only depend on relayhistory from Rust. relayhistory's Rust crates are workspace-internal and split in a way that helps nobody:
crates/ai-hist-core/Cargo.toml—ai-hist-core 0.1.0, never released.crates/ai-hist/Cargo.toml— packageai-hist-engine 0.2.0(libai_hist_engine), never released.- Every consumer already depends on both:
crates/ai-hist-cli/Cargo.toml:13-14,crates/ai-hist-napi/Cargo.toml:13-14,plugins/provider-sources/rust/Cargo.toml:10-11,plugins/relayhistory/rust/Cargo.toml:15-16. Nothing consumes core alone. - The layering story is already broken: core holds
parse_claude/parse_codex/parse_cursor_text(crates/ai-hist-core/src/lib.rs:1123-1175) and the OpenCode sync (:2124-2222), while the main Claude/Codex parsers live in engine. It is not "storage vs parsing"; it is two halves of one library. - Public surface is ~250
pubitems across the two crates, and 47 functions in core take a rawrusqlite::Connection— an embedder is handed the database driver and a bag of free functions. docs/releasing.mddescribes only the npm pipeline (.github/workflows/publish.yml, name bound to npm OIDC trusted publishing — must not be renamed). There is nocargo publishstep anywhere.- All four candidate names are free on crates.io (
ai-hist,relayhistory,ai-hist-core,ai-hist-enginereturn 404 today).
Both workspaces already agree on rusqlite = 0.32 with bundled, so linking is feasible without a version bump on either side.
Decision
Publish one crate, ai-hist (matching the npm package name), formed by merging crates/ai-hist-core and crates/ai-hist into crates/ai-hist. ai-hist-cli and ai-hist-napi stay as unpublished workspace members depending on it (publish = false). The two plugin Rust crates likewise depend on ai-hist only.
Scope
- Merge the crates. Move
ai-hist-core/src/{storage,observations,relationships,source_evidence,privacy,delivery}undercrates/ai-hist/src/as modules; foldai-hist-core/src/lib.rsintocrates/ai-hist/src/store/(schema, open/init, migrations, queries). Deletecrates/ai-hist-core. Update the four dependents'Cargo.toml.cargo test --workspacemust be green with no test body changes beyondusepaths — this is a move, not a rewrite. - Tighten visibility. Everything that takes a
&Connectionbecomespub(crate). The only public entry point is theSessionStorefacade from [G2]SessionStorefacade: the single public entry point (seven methods, typed evidence, no raw connections, no contract constant) #178 (that issue defines the methods; this one makes the rest private so it can). Where the CLI/napi/plugins currently call connection-level functions, route them through the facade or through a#[doc(hidden)] pub mod internalgated behind aunstable-internalfeature the workspace enables and external consumers do not. Check withcargo public-apithat the default-feature surface isSessionStore, the evidence structs, the error type, and theSourceenum only. - Feature gates, default off:
delivery(the durable delivery coordinator — 37 public items on its own, only the cloud plugin needs it),opencode-backup(the whole-DBConnection::backuppath; see [G1] OpenCode: event-level parity across both storage layouts (SQLite opencode.db and legacy JSON storage/), with tokens, model/provider, parts, step-finish, compaction, parentID #168),git-hooks(install_git_hooks/link_git_commit). The napi and CLI crates enable what they need. Verifycargo tree -e features -p ai-hist --no-default-featurespulls notempfile/fs2/urlunless a feature asks for it. - Make it publishable.
description,license(MIT),repository,readme,keywords,categories; workspacerust-version(MSRV) verified withcargo +<msrv> check;cargo publish --dry-run -p ai-histon CI. - Release pipeline. Add a
publish-cratejob to.github/workflows/publish.yml(do not rename the workflow) after the npm core publish, using crates.io trusted publishing (OIDC) orCARGO_REGISTRY_TOKEN; idempotent when the version already exists (skip, don't fail); honourdry_run. - Versioning policy in
docs/releasing.md: the crate shares the npm version line (0.18.xtoday) so one release tag means one artefact set. Cargo semver is the Rust contract — there is no separate Rust contract-version constant. Any change to a public struct field, enum variant, or behaviour a consumer observes is a minor bump pre-1.0 and gets a### Rust APIentry inCHANGELOG.md; acargo public-apidiff in CI (see [G2] Embedder guide, example consumer crate, and a CI job that builds an out-of-tree Rust consumer against the published crates #182) enforces the changelog entry. - Docs.
docs/releasing.md"Rust crate" section;README.mdtwo-line "Embedding from Rust" pointer;docs/architecture.mdcall graph updated (one Rust box, not two).
Acceptance
crates/ai-hist-coreno longer exists;cargo test --workspacegreen.cargo public-api -p ai-hist(default features) listsSessionStore, its methods, the evidence structs,Source,Error, and nothing that mentionsrusqlite.cargo publish --dry-run -p ai-histpasses on CI; a tagged release publishes it;cargo add ai-histin a scratch crate outside the workspace compilesSessionStore::open(Default::default())?.sync(Default::default())?.cargo build -p ai-hist --no-default-featurescompiles without the delivery module.
Out of scope
The facade method set (#178); any parser change.
Reactions are currently unavailable
Activity
[-][G1] Publish ai-hist-core and ai-hist-engine to crates.io with a release pipeline and semver policy[/-][+][G1] Merge ai-hist-core and ai-hist-engine into one published `ai-hist` crate with feature gates, a release pipeline and a semver policy[/+]