diff --git a/AGENTS.md b/AGENTS.md index 838cfbe184..752538d4be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -434,10 +434,11 @@ GGML_NATIVE=OFF cargo check --manifest-path Cargo.toml \ `--no-default-features --features flows` is the **kernel profile**: the surface a second host would embed to get workflow execution and nothing else. It is measured -and ratcheted, because unmeasured it grows — three heavy dependencies remain -unconditional today (`git2`/vendored-libgit2, `rusqlite`/bundled, and -`tokio-tungstenite`), and none would likely have -landed that way had a number moved in CI when they did. +and ratcheted, because unmeasured it grows — `rusqlite`/bundled and +`tokio-tungstenite` remain unconditional today (`git2`/vendored-libgit2 left the +kernel profile with the `libgit2-sys` + `libz-sys` shed below, once it moved +behind the `memory-git` gate), and none would likely have landed that way had a +number moved in CI when they did. ```bash scripts/kernel-floor.sh flows # CI Linux: 304 packages / 281 names / 3 native @@ -494,7 +495,7 @@ Two columns because there are two sets (see above): **Contrib** is `[features] d | `mcp` | ON | ON | `openhuman::mcp::server` (the `openhuman mcp` stdio/HTTP server), `openhuman::mcp::registry` (dynamic Smithery installs — `mcp_clients` RPC namespace, SQLite, boot spawn, supervisor, OAuth), `openhuman::mcp::audit` (write-audit log), and the static config-declared server set in `openhuman::mcp::config_servers`. ~19 agent tools, ~20k LOC | **none** (see scope note) | | `tui` | OFF | — | `openhuman::tui` — the tabbed ratatui/crossterm CLI UI (Logs, Chat, Config, Settings), auto-opened by bare `openhuman` on interactive non-container hosts and forced with `openhuman tui` (alias `chat`). Runs the core in-process. No controllers, no agent tools. **Intentionally NOT forwarded to the desktop shell** (allowlisted in `check-feature-forwarding.mjs`). | `ratatui`, `crossterm` | | `channels` | ON | ON | `openhuman::channels` (external-messaging providers — Telegram/Discord/Slack/Signal/WhatsApp/iMessage/IRC/… — plus the channel runtime, controllers, host, proactive messaging + inbound dispatch) and the `channels::webview_accounts` / `webview_apis` / `webview_notifications` / `channels::whatsapp_data` webview-bridge domains (incl. the 3 `whatsapp_data_*` agent tools). **Carve-outs `channels::{traits, cli}` stay ungated.** | **28** via `tinychannels/{email,lark}` — the crate itself stays (load-bearing), its two heavy providers do not | -| `memory-git` | OFF | ON | `openhuman::memory::diff` (git-backed snapshots/checkpoints/read markers, the `memory_diff` RPC namespace + agent tool) and the git wiki mirror in `memory::store::content::wiki_git`. **Type carve-out**: `memory::diff::types` compiles in BOTH builds — the always-on subconscious memory profile renders `CrossSourceDiff`/`ChangeKind` into prompts, and tinycortex makes the matching split (its `memory::diff::{types,source}` are ungated, only the `Ledger`/`DiffEngine` half sits behind `git-diff`). Off ⇒ `memory_diff` is unknown-method, the tool is absent, the embedded driver drops `Capability::Diff` **and** `as_diff()` returns `None` in lockstep (`audit_provider` fails on either half alone), and summary nodes are still written to disk but not mirrored into git. | **3**: `git2`, `libgit2-sys`, `libz-sys` — two of the five native C builds in the kernel profile, the largest native shed in the program | +| `memory-git` | OFF | ON | `openhuman::memory::diff` (git-backed snapshots/checkpoints/read markers, the `memory_diff` RPC namespace + agent tool) and the git wiki mirror in `memory::store::content::wiki_git`. **Type carve-out**: `memory::diff::types` compiles in BOTH builds — the always-on subconscious memory profile renders `CrossSourceDiff`/`ChangeKind` into prompts, and tinycortex makes the matching split (its `memory::diff::{types,source}` are ungated, only the `Ledger`/`DiffEngine` half sits behind `git-diff`). Off ⇒ `memory_diff` is unknown-method, the tool is absent, the embedded driver drops `Capability::Diff` **and** `as_diff()` returns `None` in lockstep (`audit_provider` fails on either half alone), and summary nodes are still written to disk but not mirrored into git. **This crate declares no `git2`** — tinycortex owns every libgit2 call in the stack (the diff ledger, the wiki mirror, the persona git-history reader), and the gate reaches the cohort by forwarding `tinycortex/git-diff` + `tinycortex/wiki-git`; `tinymemory-core/memory-git` forwards the same pair. Do not re-add a direct `git2` dependency to this crate or to `tinymemory-core`: it would buy no crates and invite a second major pin, which `links = "git2"` makes a hard cargo error. Test code that must read a ledger back goes through the `tinycortex::git2` re-export (`tests/memory_artifacts_e2e.rs`). | **3**: `git2`, `libgit2-sys`, `libz-sys` — two of the five native C builds in the kernel profile, the largest native shed in the program | | `contacts` | OFF | ON | `memory::people::address_book`'s macOS CNContactStore reader — the address-book seeding path for the people domain. Leaf gate over a **pre-existing** off-state: the module already shipped a non-macOS `imp` stub returning an empty contact list, so the gate only widens that stub's cfg. `read`/`read_with`/`AddressBookError`/`SystemContactsSource` and the whole `people` RPC surface stay compiled in every build; off ⇒ a refresh seeds nothing instead of failing. | **6** on macOS (`objc2`, `objc2-foundation`, `objc2-contacts`, `block2` + 2 transitive). **No-op on Linux/Windows** — never in those graphs, so the kernel-floor ratchet does not move. Verify cross-target: `cargo tree --target aarch64-apple-darwin -e normal -i objc2-contacts --no-default-features` (294 → 288 packages). | | `runtime-node` | OFF | ON | `runtime::node` (download / verify / extract / install a pinned Node.js toolchain), the `runtime::javascript` language slot, `runtime::pool::node`, the `node_exec` / `npm_exec` agent tools, and the `node_runtime` harness-init step. **Facade + stub** — `ShellTool` holds `Option>` and `shell.rs` is kernel, so the module cannot simply vanish; `runtime/node/stub.rs` carries the `NodeBootstrap` type surface while registration sites are leaf-gated. **The generic native-tool dispatcher (`runtime::node::ops` / `runtime::node::types`) is NOT gated** — it backs both the gated `javascript.*` controllers and the ungated `flows` `oh:` `NativeToolBackend`, so native flow tools (`memory_search`, file, shell, …) keep working when the managed Node runtime is off. Off ⇒ `try_cached`/`probe_installed` return `None` and the shell never prepends a managed bin dir, identical to today's `node.enabled = false` path. | **`xz2` + its static liblzma C build.** First gate to remove a NATIVE toolchain build: `lzma-sys` leaves the list, 6 → 5. `tar`/`zip` are NOT shed — shared with `inference` (install_piper), `runtime::python`, and the document tools. | diff --git a/Cargo.lock b/Cargo.lock index cadc0a641a..d4bb8a6256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4119,7 +4119,6 @@ dependencies = [ "fs2", "futures", "futures-util", - "git2", "glob", "hex", "hkdf", @@ -6471,7 +6470,7 @@ dependencies = [ "tinyagents", "tinycortex-api", "tokio", - "toml 0.8.23", + "toml 1.1.2+spec-1.1.0", "tracing", "uuid", "walkdir", @@ -6562,7 +6561,6 @@ dependencies = [ "chrono", "dirs", "futures", - "git2", "log", "parking_lot", "rand 0.8.6", diff --git a/Cargo.toml b/Cargo.toml index c2aaaaa037..8123cd2c48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,7 +101,7 @@ required-features = ["crash-reporting"] [[test]] name = "memory_artifacts_e2e" path = "tests/memory_artifacts_e2e.rs" -# Opens the wiki ledger with `git2::Repository::open` and asserts on +# Opens the wiki ledger with `tinycortex::git2::Repository::open` and asserts on # `content::wiki_git` artifacts — both of which exist only behind this gate. required-features = ["memory-git"] @@ -182,13 +182,15 @@ tinyagents = { version = "2.1", features = ["sqlite"] } # crate through the adapter seam in `src/openhuman/tinycortex/` (mirroring the # tinyagents seam): engine logic (including provider sync pipelines) in the # crate; RPC, agent tools, sync scheduling/credentials/events, security gating, -# and the global singleton stay host-side. rusqlite/git2 are -# aligned to the host pins (=0.40 / 0.21) so one bundled SQLite + one libgit2 -# link. The submodule intentionally tracks reviewed upstream main commits; -# keep this semver requirement compatible with the vendored crate version. +# and the global singleton stay host-side. rusqlite is aligned to the host pin +# (=0.40) so one bundled SQLite links. The submodule intentionally tracks +# reviewed upstream main commits; keep this semver requirement compatible with +# the vendored crate version. # `git-diff` and `wiki-git` are NOT here: they are pulled in by the # `memory-git` gate below, which is where the git2/libgit2-sys/libz-sys cohort -# enters the graph. Everything else tinycortex needs is unconditional. +# enters the graph. This crate holds no `git2` pin of its own to align — the +# gate turns tinycortex's on, and tinycortex is the sole libgit2 link in the +# graph. Everything else tinycortex needs is unconditional. tinycortex = { version = "0.1", features = [ "obsidian", "persona", @@ -310,10 +312,16 @@ argon2 = "0.5" rand = "0.10" dirs = "5" sha2 = "0.10" -# Git-backed change ledger for the memory_diff module: snapshots are commits, -# checkpoints are tags, read markers are refs, diffs are git tree diffs. -# Vendored libgit2 (no system git dependency on end-user machines). -git2 = { version = "0.21", default-features = false, features = ["vendored-libgit2"], optional = true } +# NO `git2` HERE, DELIBERATELY — do not add it back. Every use of libgit2 in +# the memory stack lives in tinycortex: the diff ledger (`memory::diff`), the +# wiki mirror (`memory::store::content::wiki_git`), and the persona git-history +# reader. This crate holds the RPC surface, the agent tool and the gate around +# them, and never touches a repository itself, so a direct dependency here was +# a declaration with no `use` behind it. Re-declaring it costs nothing in +# crates (the `memory-git` gate pulls tinycortex's copy either way) but invites +# a second major pin, and `git2` sets `links = "git2"` — two majors in one +# graph is a hard cargo error, not a warning. Test code that must inspect a +# ledger goes through `tinycortex::git2`. hmac = "0.12" # Archive extraction for the Node.js runtime bootstrap. Unix Node # distributions ship as .tar.xz, Windows as .zip. `xz2` with `static` @@ -621,9 +629,12 @@ default = ["media", "skills", "flows", "mcp", "channels", "medulla", "http-serve # git-backed wiki content format in `memory::store::content::wiki_git`. # Default-OFF, product-ON. # -# The most expensive gate in the tree by native-build cost: it carries `git2` -# with vendored libgit2, so turning it off drops `git2` + `libgit2-sys` + -# `libz-sys` and takes the kernel profile from 5 native C builds to 3. +# The most expensive gate in the tree by native-build cost: it turns on +# tinycortex's `git-diff`/`wiki-git`, which carry `git2` with vendored libgit2, +# so turning it off drops `git2` + `libgit2-sys` + `libz-sys` and takes the +# kernel profile from 5 native C builds to 3. The cohort enters the graph +# through tinycortex only — this crate declares no `git2` of its own (see the +# note where it used to sit in `[dependencies]`). # # TYPE CARVE-OUT (see AGENTS.md): `memory::diff::types` stays compiled in BOTH # builds. It re-exports tinycortex's `serde`-only diff wire types, which the @@ -638,7 +649,7 @@ default = ["media", "skills", "flows", "mcp", "channels", "medulla", "http-serve # `None`; and the three `ops` entry points always-on code calls return a # build-fact error, so a post-sync snapshot or a subconscious diff is logged and # skipped rather than silently reported as "nothing changed". -memory-git = ["dep:git2", "tinycortex/git-diff", "tinycortex/wiki-git", "tinymemory-core/memory-git"] +memory-git = ["tinycortex/git-diff", "tinycortex/wiki-git", "tinymemory-core/memory-git"] http-server = ["dep:axum", "dep:socketioxide"] # Local audio-device access: the `cpal` capture stack behind voice recording # and the accessibility microphone-permission probe. Default-ON. Slim / diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index 0d3929a9e8..0fa363d32a 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -4668,7 +4668,6 @@ dependencies = [ "fs2", "futures", "futures-util", - "git2", "glob", "hex", "hkdf", @@ -7632,7 +7631,7 @@ dependencies = [ "tinyagents", "tinycortex-api", "tokio", - "toml 0.8.2", + "toml 1.1.4+spec-1.1.0", "tracing", "uuid", "walkdir", @@ -7723,7 +7722,6 @@ dependencies = [ "chrono", "dirs 5.0.1", "futures", - "git2", "log", "parking_lot", "rand 0.8.7", diff --git a/scripts/kernel-floor.limits b/scripts/kernel-floor.limits index 6e3db40089..55430b0ab6 100644 --- a/scripts/kernel-floor.limits +++ b/scripts/kernel-floor.limits @@ -13,12 +13,31 @@ # Simulate with: scripts/dep-sim.py --cut # # History -# 304/281/2 2026-08-14 TinyJuice moved behind the TinyBus module boundary -# (-3 packages / -3 names). The `tinyjuice`, -# `tinyjuice-tokenizer`, and `tinyjuice-vector` -# crates no longer enter the always-on `flows` graph; -# OpenHuman keeps only its stable wire types and host -# adapter. Measured with `scripts/kernel-floor.sh flows`. +# 297/279/2 2026-08-14 tinycortex + tinymemory advanced to their merge +# commits for the git2-ownership move (-6 packages / +# -2 names). A shed, not a gate: the newer submodules stop +# pulling a second `toml` parser stack into this profile — +# `toml`, `toml_edit`, `toml_datetime`, `toml_write`, +# `serde_spanned` and `winnow` leave, and nothing is added. +# Six packages but only two names, because four of them +# were duplicate majors of names still present at another +# version. +# +# Measured AFTER merging main's TinyJuice extraction and +# tinyflows 0.8 (the 303/281/2 entry below), so this is +# that baseline minus this branch's shed: 303 - 6 = 297 +# packages, 281 - 2 = 279 names. The two sheds are +# disjoint — no crate is claimed twice. Measured with +# `scripts/kernel-floor.sh flows --json` (297/279/2) and +# confirmed by diffing `cargo tree --no-default-features +# --features flows -e normal` across the two submodule +# pins. +# +# NOTE: this takes the profile BELOW the 302 package count +# of the 2026-08-09 spec-target entry below, which the +# three intervening entries had grown away from. Native +# builds are unchanged at 2 (libsqlite3-sys, ring) — still +# the floor, and still load-bearing. # 303/281/2 2026-08-14 tinyflows 0.8: the duplicate reqwest major is gone, # closing #5539. Main had raised this to 308 because # tinyflows pulled reqwest 0.13 alongside the kernel's @@ -39,18 +58,7 @@ # crates no longer enter the always-on `flows` graph; # OpenHuman keeps only its stable wire types and host # adapter. Measured with `scripts/kernel-floor.sh flows`. -# PLACEHOLDER 2026-08-14 tinyflows 0.8: the duplicate reqwest major is gone, -# undoing the 308 below and closing #5539. tinyflows PR #45 -# put its HTTP client behind the `chrome-extension` and -# `host-caps` features, and this crate enables neither — so -# reqwest 0.13 leaves the graph entirely rather than being -# unified with 0.12. Verified with `cargo tree -# --no-default-features --features flows -e normal`: -# `reqwest v0.12.28` is the only major resolved. -# Nothing was unified and nothing was gated here; the -# vendor bump simply stopped pulling the second copy in. -# Measured with `scripts/kernel-floor.sh flows`: -## 308/284/2 2026-08-13 tinyflows' host-stack advance (PR #5537) moved its +# 308/284/2 2026-08-13 tinyflows' host-stack advance (PR #5537) moved its # direct HTTP client from reqwest 0.12 to 0.13 while the # rest of the kernel still uses 0.12. That creates one # additional resolved package but no new crate name or @@ -292,4 +300,4 @@ # (libsqlite3-sys, ring) — see docs/plans MIGRATION-PLAN G6. # 307/284 2026-08-12 Re-baseline after the upstream lockfile resolution; # `flows` remains at two native packages. -flows:303:281:2 +flows:297:279:2 diff --git a/tests/memory_artifacts_e2e.rs b/tests/memory_artifacts_e2e.rs index 74bcb9543a..23f9c98405 100644 --- a/tests/memory_artifacts_e2e.rs +++ b/tests/memory_artifacts_e2e.rs @@ -164,7 +164,11 @@ async fn summary_ingest_records_summary_only_git_history_and_timestamped_read_ta .expect("ingest summary"); let wiki_root = content_root.join("wiki"); - let repo = git2::Repository::open(&wiki_root).expect("wiki git repo should be initialized"); + // Through tinycortex's re-export, not a `git2` dependency of this crate: + // tinycortex writes this ledger and owns the only libgit2 link in the + // graph, so the assertion reads it back with the very same binding. + let repo = tinycortex::git2::Repository::open(&wiki_root) + .expect("wiki git repo should be initialized"); let head = repo.head().expect("wiki head").peel_to_commit().unwrap(); let tree_obj = head.tree().expect("wiki commit tree"); diff --git a/vendor/tinycortex b/vendor/tinycortex index be7b395354..0a7a06710f 160000 --- a/vendor/tinycortex +++ b/vendor/tinycortex @@ -1 +1 @@ -Subproject commit be7b395354271082953d2594765aded73975b54c +Subproject commit 0a7a06710fce8dba1cdb06b3e4640c351bba800c diff --git a/vendor/tinymemory b/vendor/tinymemory index 1e2338aa71..c4af0eae84 160000 --- a/vendor/tinymemory +++ b/vendor/tinymemory @@ -1 +1 @@ -Subproject commit 1e2338aa71cf979915c749297b0fb77706e80ac8 +Subproject commit c4af0eae848864572bc2f38506f0a003b21e1a5f