Skip to content

feat(lib): re-export git2 for hosts that inspect a ledger - #147

Merged
senamakel merged 3 commits into
mainfrom
move-git-to-tinycortex
Aug 14, 2026
Merged

feat(lib): re-export git2 for hosts that inspect a ledger#147
senamakel merged 3 commits into
mainfrom
move-git-to-tinycortex

Conversation

@senamakel

@senamakel senamakel commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

Re-export git2 from the crate root under #[cfg(any(feature = "git-diff", feature = "wiki-git"))], so a host can read back a ledger this crate wrote without declaring its own git2 dependency.

Problem

TinyCortex owns every libgit2 call in the memory stack — the diff ledger (memory::diff), the wiki mirror (memory::store::content::wiki_git), and the persona git-history reader (memory::persona::readers::git_history). Nothing else in the stack opens a repository.

Hosts still had to declare git2 themselves to assert on the artifacts this crate produces. OpenHuman did exactly that: a git2 entry in [dependencies] plus dep:git2 on its memory-git gate, whose only consumer in the entire crate was one git2::Repository::open in an integration test.

That is not merely redundant. A host pin is free to drift off this crate's major, and git2 sets links = "git2" — two majors in one graph is a hard cargo error, not a warning. The failure would surface as an unrelatable link conflict at build time.

Solution

pub use git2; at the crate root, gated on the two features that already pull the dependency in, with a doc comment saying what it is for and what it is not: reach for it only where a caller genuinely has to inspect a ledger or mirror this crate produced — an integration test asserting on commits, tags or trees. Ordinary callers stay on the typed API.

No behaviour change, no new dependency, no change to the feature-off build (the re-export compiles out with the features that carry git2).

Impact

  • Additive to the public surface; nothing removed or renamed.
  • Lets downstream hosts drop their own git2 declarations, leaving this crate the sole libgit2 link in the graph. The companion PRs do that in tinymemory-core and openhuman.

Validation

  • cargo check --all-targets (default features) — clean.
  • cargo check --features git-diff,wiki-git,obsidian,persona,sync --all-targets — clean.
  • cargo fmt --check — clean.
  • Verified downstream: with OpenHuman's git2 dependency removed and its test moved onto tinycortex::git2, cargo test --features memory-git --test memory_artifacts_e2e passes (2 tests), and cargo tree -i git2 shows this crate as the only parent.

Summary by CodeRabbit

  • New Features

    • Diff description types and sources are now available even when Git-based diff functionality is disabled.
    • Git functionality remains available when the git-diff feature is enabled.
    • The crate now exposes its Git integration for supported feature configurations.
  • Documentation

    • Clarified which memory and diff features are included in default builds and which require optional features.
  • Tests

    • Added coverage for serialization and non-Git usage of diff-related types.

senamakel and others added 3 commits August 10, 2026 13:54
`git-diff` gated the whole `memory::diff` module, so a host that did not want
libgit2 in its dependency graph could not so much as *name* a `CrossSourceDiff`.
That is more than the feature needs to gate: `types.rs` and `source.rs` are
`serde`/`std`-only and reach no `git2` symbol — only `ledger.rs` and
`ledger_helpers.rs` do.

`pub mod diff` is now always compiled. Ungated: `types`, `source`, and their
re-exports. Gated on `git-diff`: `ledger` + `ledger_helpers` (the two that touch
git2), `checkpoint` / `diff` / `snapshot` (whose impls are written against
`Ledger`), and `DiffEngine` itself — its inherent methods live in those modules,
so an ungated engine would be a handle with nothing to call.

The distinction is describe-vs-compute: without the feature a host can pass a
diff around, match on a `ChangeKind`, and implement `SnapshotItemSource`; it
simply cannot produce one.

This unblocks a `memory-git` gate in OpenHuman, whose always-on subconscious
profile renders `CrossSourceDiff`/`ChangeKind` into prompts. Stubbing those
types host-side instead would mean two definitions of one serde shape drifting
apart silently — which is why OpenHuman's own gate guidance says to put a
domain's inert types in a dependency-free submodule and gate only behaviour.

Two `#[cfg(not(feature = "git-diff"))]` tests pin the carve-out, because the
disabled build is the only thing that can catch it regressing: re-gating these
types compiles fine with the feature on and only breaks downstream. They
construct and serde-round-trip the types rather than just naming them, so a
gated-away derive fails too. The pre-existing `types`/`source` unit tests now
run in the disabled build as well.

Verified both ways: `--features obsidian,persona,sync` (43 → the git-backed
tests compile out, 14 inert ones run) and with `git-diff,wiki-git` added (43
diff tests pass, unchanged).

Co-authored-by: Medulla <medulla@tinyhumans.ai>
…ip them

Review follow-ups on #141:

- The tests were an inline `mod` in `mod.rs`; every other test module in this
  directory is a `#[path = "*_tests.rs"]` sibling. Now they match.
- The serde test only serialised. These types exist to cross a boundary, so a
  `Deserialize` derive that got gated away would not have failed it — it now
  round-trips and asserts the restored fields.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
TinyCortex owns every libgit2 call in the memory stack -- the diff ledger,
the wiki mirror and the persona git-history reader. Hosts had to declare
their own git2 to assert on the artifacts this crate writes, which risks a
second major pin; `links = "git2"` makes that a hard cargo error rather
than a warning. Re-export the binding under the two git features instead.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 662f8552-5e89-4eff-b958-9343f50bf4ab

📥 Commits

Reviewing files that changed from the base of the PR and between 4f6517c and a47588a.

📒 Files selected for processing (4)
  • src/lib.rs
  • src/memory/diff/carve_out_tests.rs
  • src/memory/diff/mod.rs
  • src/memory/mod.rs

📝 Walkthrough

Walkthrough

The change keeps diff types and sources available without Git support. It gates Git-backed modules and DiffEngine behind git-diff, re-exports git2 for Git-enabled consumers, and adds non-Git compilation tests.

Changes

Git diff feature carve-out

Layer / File(s) Summary
Always-available diff module contract
src/memory/mod.rs
The diff module is always declared. Its documentation distinguishes ungated types and sources from feature-gated computation.
Git-backed implementation gating
src/memory/diff/mod.rs, src/lib.rs
Git-specific diff modules and DiffEngine require git-diff. The crate conditionally re-exports git2 when git-diff or wiki-git is enabled.
Non-Git compilation validation
src/memory/diff/carve_out_tests.rs, src/memory/diff/mod.rs
Tests validate JSON round trips and SnapshotItemSource implementation without Git support. Git engine tests remain feature-gated.

Estimated code review effort: 2 (Simple) | ~15 minutes

Merge Risk: ⚪ Minimal · up to a4758

This adds a feature-gated public git2 re-export without changing runtime behavior or feature-off behavior; no actionable merge-blocking risk remains beyond normal checks and review.

Possibly related PRs

Suggested labels: priority: p3

Suggested reviewers: hobertrand-hub

Poem

I hopped through the diff with a Git-ready cheer,
Left types and sources available here.
When features are off, the tests still shine,
When features are on, Git tools align.
Squeak—clean boundaries in every design!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: re-exporting git2 for hosts that inspect ledgers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Aug 14, 2026
@senamakel

Copy link
Copy Markdown
Member Author

PR babysitter status

Head: a47588a83a1f5e84357a4b32693160e07493352e

CI: all 7 required GitHub Actions checks are SUCCESS (Rust SDK, Features: core/no-features, git-diff, persona, sync, tokio, all-features). CodeRabbit approved with "No actionable comments were generated in the recent review."

Non-required check tinysweeper/review shows ACTION_REQUIRED with output "The review could not reach a model" — this is a transient failure on TinySweeper's own infrastructure, unrelated to the PR content, and it is not part of this repo's required-checks ruleset (only deletion, non_fast_forward, and pull_request rules are configured; no required_status_checks).

Review threads: 0 unresolved. Reviews requesting changes: 0.

Local validation on head a47588a8:

  • cargo check --all-targets — pass
  • cargo check --features git-diff,wiki-git,obsidian,persona,sync --all-targets — pass
  • cargo fmt --check — pass

Mergeability: MERGEABLE, no conflicts.

Status: READY_FOR_APPROVAL. Handing off to pr-approval-reviewer.

@senamakel
senamakel merged commit 0a7a067 into main Aug 14, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant