Skip to content

refactor(memory): hoist policy out of the engine and make the workspace schema gate real - #5480

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:memory-carveout
Aug 10, 2026
Merged

senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:memory-carveout

Conversation

@senamakel

@senamakel senamakel commented Aug 10, 2026

Copy link
Copy Markdown
Member

What

Prerequisite work for moving the graph and episodic substrate into tinycortex. Two things
have to be true before any of that code moves, and neither is true today:

  1. Host policy must leave the move set. Once policy ships into a persistence crate it does
    not come back.
  2. There must be a schema gate that actually catches a workspace-format regression. The one we
    have does not, and it never runs.

Both are independently valuable even if the move is never made.

1. The engine no longer reads the host's execution context

UnifiedMemory's Memory::recall called
agent::tinyagents::thread_context::current_thread_id() to compute exclude_session_id — the
same-session self-echo guard that stops the agent's own memory_recall surfacing the very user
message that triggered the turn. A memory engine reading the host's tokio task-local is not
an engine.

The engine body now lives in an inherent
recall_excluding_session(..., exclude_session_id: Option<&str>), and a nine-line
Memory::recall adapter resolves the ambient value and passes it in. Behaviour is unchanged in
both directions: None in, None out; in-turn recall still excludes the triggering message.

Stated honestly, because it matters for the next PR: the read is still ambient — it just no
longer happens inside the engine.
Lifting it all the way to the callers is unreachable
today. Every in-turn caller holds an Arc<dyn Memory>, and RecallOpts is re-exported
verbatim from the vendored tinycortex crate with exactly five fields (both From impls
destructure exhaustively, and owned_and_borrowed_recall_opts_have_identical_fields pins the
pair), so widening it is an upstream SDK change, not a host edit. Post-filtering is not a
substitute: the document branch returns session_id: None, and filtering after ranking would
let limit be consumed by rows the caller asked not to see.

What this buys: the engine body imports nothing from crate::openhuman::agent::* and is
driveable with no harness present. The one remaining resolution sits in
memory/store/recall_policy.rs — deliberately outside namespace_store, so it does not travel
with the move — and its doc comment names the exact upstream change that finishes the job
(RecallOpts gaining exclude_session_id). Worth raising upstream.

2. Redaction happens before the driver sees content

sanitize_document_input ran inside upsert_document / upsert_document_metadata_only.
Redaction is host policy and belongs ahead of the persistence call.

The whole ordered gate moved, not just the redactor — reject-secret-address → canonicalize-PII-key
→ redact-content is one unit, and hoisting only the third step would scrub a different string
than the one the row is addressed by.

The shape is what guarantees no bypass. The driver methods were renamed to
upsert_document{,_metadata_only}_presanitized and narrowed to pub(crate); the new gate
re-declares the original names with identical signatures. All ~90 call sites are gated with
zero call-site edits, and the raw names are new, so nothing could already be calling them.
Verified: the _presanitized names appear only at their definitions and one doc link.

3. A parity gate that is actually a gate

tests/memory_golden_parity_e2e.rs was the only thing between a schema change and a corrupted
user workspace. It did not work:

  • It asserted three hardcoded &'static [&str] table-name constants were a subset of the
    tables found, filtering type='table'. Indexes, triggers, columns, PRAGMA user_version,
    row data and migration paths were all unasserted.
  • The workspace under test was tempdir()-fresh, so nothing about an existing user DB was
    exercised.
  • Renaming a table and editing the matching constant — a two-line diff — passed green.
  • And it never ran. grep -rn "memory_golden_parity" .github/ scripts/ returned zero hits,
    and .github/workflows/test.yml is workflow_dispatch: {} only.

Replaced with tests/memory_golden_fixture_e2e.rs over a committed fixture captured from the
pre-move binary (~512KB across memory.db + chunks.db, seeded to materialize both FTS5
shadow tables and all six sync triggers). It asserts full sqlite_master over
type IN ('table','index','trigger') for set equality against a manifest, user_version
on both files, row-level readback through memory::ops rather than raw SQL, deterministic
recall, and close/reopen.

The manifest is derived from the fixture, never hand-written. That is what closes the
two-line vacuity: editing the DDL and the manifest together still fails, because the fixture
was built by the pre-move binary. Making it pass requires deliberately regenerating the
fixture (scripts/regen-memory-golden-fixture.sh), which is a reviewable act.

This is the gate's weakest joint and a test cannot close it. A diff that touches a .db
blob needs explicit reviewer sign-off. Please treat a fixture regeneration in someone else's PR
as a red flag unless it is the point of the PR.

.gitattributes gains tests/fixtures/memory_golden/**/*.db binary — the repo root sets
* text=auto eol=lf, which would corrupt the blob on a CRLF checkout.

CI wiring: the memory integration targets are added to CI Lite's scoping table
(scripts/ci/rust-coverage-changed.sh), so a PR touching src/openhuman/memory/** now
actually runs them.

4. Unrelated latent defect, fixed while in the file

The nine ALTER TABLE statements in namespace_store/init.rs swallowed all errors, so a
genuine failure was indistinguishable from "column already exists". Narrowed to the
duplicate-column case; anything else now surfaces.

Verification

An independent adversarial pass attacked both slices and confirmed them. The parts worth
repeating:

  • The gate bites. Table rename (graph_globalgraph_global_v2 + the parity constant):
    old harness ok. 1 passed; new gate FAILED. 1 passed; 2 failed. Index/trigger-only edit
    (added idx_memory_docs_taint, reordered idx_episodic_session, dropped a column from
    episodic_ad): old harness ok. 1 passed — it filters type='table' and structurally
    cannot see these — new gate red on both.
  • The self-echo guard holds. The verifier used a stronger break than the implementer
    reported, neutering the adapter (the real production regression shape); the retained
    end-to-end test fired, naming the leaked triggering message.
  • The fixture is binary-safe. git check-attr reports binary: set, text: unset; SHA-256
    identical across worktree, index and HEAD.
  • CI wiring confirmed by execution, via a cargo PATH shim rather than by reading the diff.
check result
cargo check --tests 0 errors
cargo test --lib openhuman::memory 1501 passed, 0 failed
cargo test --test memory_golden_fixture_e2e 3 passed, 2 ignored
cargo test --test memory_golden_parity_e2e 1 passed
cargo fmt --check clean
git diff upstream/main...HEAD -- vendor/ empty

One pre-existing failure the parent should know about, unrelated to this branch: the full
unscoped cargo test --lib aborts the whole test binary with a stack overflow in
agent::harness::session::runtime::tests::run_single_publishes_completed_and_error_events.
Reproduced identically on a clean upstream/main worktree. Because it SIGABRTs, it masks every
test ordered after it.

Two corrections to note

  • pnpm test:rust:e2e is invoked from ci-full.yml and e2e-reusable.yml, not e2e.yml.
    Since ci-full only runs on PRs targeting release, the CI Lite coverage lane is the
    load-bearing path on a normal PR to main — and that one is wired correctly.
  • The tests/fixtures/memory_golden/* scoping arm pulls in only memory_golden_fixture_e2e,
    not memory_golden_parity_e2e, unlike the src/openhuman/memory/* arm which adds both.
    Harmless (parity is superseded), but the asymmetry is deliberate rather than an oversight.

Note on the history

The auto-commit hook checkpointed ~60 intermediate commits here, including deliberate
break-then-restore cycles from proving the gate bites. I squashed them; the squashed tree is
byte-identical to the tree the verifier signed off (bdd2c6c2f). The second commit exists only
because the hook's content scanner withholds write_gate_tests.rs — it contains
sk-1234567890123456789012345, a synthetic fixture already used verbatim on main in
namespace_store/documents_tests.rs and store/safety/mod.rs. Flagged on shape alone.

Next

With the gate in place, the graph engine (graph_global/graph_namespace, ~842 LOC, the only
unit with no policy inside it and no host-type coupling) is the pilot move, via
from_shared_connection-style adoption in place with the DDL frozen verbatim. Then
segments.rs + fts5.rs together — episodic_fts is external-content and cannot be separated
from episodic_log across a database file.

profile.rs, events.rs and query.rs stay host-side permanently: the FacetType taxonomy
and an LLM-prompt renderer, English pattern tables, and the recall ranking weights respectively.
Per docs/tinycortex-migration-spec.md, the rest of the namespace-document tier does not move
at all.

Summary by CodeRabbit

  • New Features

    • Added safeguards that redact sensitive document content, reject secret-like memory keys, and canonicalize personal-information keys before storage.
    • Memory recall can now explicitly exclude the current conversation session, reducing self-echoes in results.
  • Bug Fixes

    • Improved database migration handling for existing columns and missing tables while reporting unexpected failures clearly.
    • Added comprehensive validation for memory data, retrieval, schemas, and reopening workspaces.
  • Documentation

    • Documented memory fixture contents, provenance, and schema review requirements.

senamakel and others added 2 commits August 10, 2026 16:48
…ema gates

Extract the recall self-echo exclusion logic into a parameterised engine body so the storage layer no longer reads ambient agent-harness state, and introduce a golden-workspace fixture that pins the memory-store schema against regressions. The new `recall_excluding_session` method takes the exclusion as an explicit argument, with the trait adapter resolving host policy via `recall_policy`. The golden fixture, seeded by a new `golden` module, captures the full schema including episodic, segment, event and profile tiers that lack guarded writers, and is enforced by two integration tests now wired into the CI coverage and e2e suites. Additive SQLite migrations are also hardened: `apply_additive_migration` surfaces genuine failures instead of swallowing them as idempotent re-runs.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The two `raw_*_driver_upsert_does_not_redact` cases are the load-bearing
half: they fail if anyone folds redaction back into the storage layer,
which is exactly the regression the hoist exists to prevent.

The `sk-1234567890123456789012345` literal is a synthetic fixture, not a
credential — it is the same value `namespace_store/documents_tests.rs`
and `store/safety/mod.rs` already use on main for this purpose. The
auto-commit content scanner flags it on shape alone.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel requested a review from a team August 10, 2026 13:53
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds host-level memory recall and write policies, stricter additive migrations, a deterministic SQLite golden fixture, schema and persistence E2E gates, fixture regeneration tooling, and CI coverage integration.

Changes

Memory policy and storage boundaries

Layer / File(s) Summary
Recall and write policy boundaries
src/openhuman/memory/store/..., src/openhuman/memory/store/namespace_store/documents.rs
Recall supports explicit session exclusion. Document writes reject, canonicalize, and sanitize input before persistence.
Additive migration error handling
src/openhuman/memory/store/namespace_store/init.rs
SQLite migrations classify expected duplicate-column and missing-table cases while propagating other failures.
Golden fixture seeding and schema capture
src/openhuman/memory/store/golden.rs, docs/specs/memory-guard-allowlist.md, src/openhuman/memory/bypass_allowlist_tests.rs
The golden module seeds deterministic records across memory tiers, reads them back, and generates schema manifests.
Fixture schema and persistence gates
tests/memory_golden_fixture_e2e.rs, tests/memory_golden_parity_e2e.rs, tests/fixtures/memory_golden/*, .gitattributes
E2E tests compare committed and fresh schemas, validate persisted data and retrieval, test process reopening, and document generated binary fixtures.
Regeneration and CI execution wiring
scripts/regen-memory-golden-fixture.sh, scripts/test-rust-e2e.sh, scripts/ci/rust-coverage-changed.sh
Fixture regeneration is scripted. Both memory gates run by default and are selected for changed memory sources and fixtures.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant E2ETest
  participant GoldenFixture
  participant MemoryWorkspace
  participant SchemaManifest
  E2ETest->>GoldenFixture: Copy committed SQLite databases
  E2ETest->>MemoryWorkspace: Initialize or reopen workspace
  E2ETest->>GoldenFixture: Read seeded records
  GoldenFixture->>MemoryWorkspace: Query memory, tree, vector, and summary data
  E2ETest->>SchemaManifest: Compare database schema sets
  SchemaManifest-->>E2ETest: Exact match or diagnostics
Loading

Possibly related PRs

Suggested labels: rust-core, memory

Suggested reviewers: al629176

Poem

A rabbit checks each golden byte,
Then hops through schemas crisp and bright.
Recall skips its echo trail,
Safe writes pass the guarded rail.
SQLite dreams stay sealed just right.

🚥 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 summarizes the main changes: moving memory policy out of the engine and strengthening the workspace schema gate.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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 memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Aug 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
src/openhuman/memory/store/write_gate.rs (1)

90-100: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Lower the canonicalization log to debug.

log::info! fires on every write whose key is rewritten. Recurring scanner-built keys make this a hot path. log::debug! matches the repository logging guideline for domain flows and keeps the same fields.

♻️ Proposed level change
-            log::info!(
+            log::debug!(
                 "[memory:write_gate] {flow} write canonicalized PII-like key key_chars={}",
                 input.key.chars().count()
             );

As per coding guidelines: "use log/tracing at debug or trace levels with stable prefixes and correlation fields".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/write_gate.rs` around lines 90 - 100, Lower the
canonicalization log in the write-gate flow around
`safety::canonical_document_key` from `log::info!` to `log::debug!`, preserving
the existing stable prefix, message, and `key_chars` field.

Source: Coding guidelines

tests/fixtures/memory_golden/manifest.txt (1)

14-15: 🚀 Performance & Scalability | 🔵 Trivial

The captured schema records a duplicate index and an unversioned host DB.

The fixture pins two identical indexes on the same column: idx_kv_namespace_ns from namespace_store/init.rs and idx_kv_ns from the crate KV tier, both ON kv_namespace(namespace). Every kv_namespace write maintains both. Line 39 also shows memory/memory.db pragma user_version 0, while memory_tree/chunks.db reports 2, so the host tier carries no schema version to drive future migrations.

Neither point is introduced by this PR. Track them as follow-ups now that the manifest makes them visible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/fixtures/memory_golden/manifest.txt` around lines 14 - 15, Track
follow-up work for the duplicate kv_namespace(namespace) indexes represented by
idx_kv_namespace_ns and idx_kv_ns, and for adding schema versioning to the host
database reported by memory/memory.db; preserve the current fixture while
recording both items for future cleanup and migration support.
src/openhuman/memory/store/namespace_store/init.rs (1)

240-252: 🩺 Stability & Availability | 🔵 Trivial

Confirm the boot-abort behavior for transient SQLite failures.

? now aborts new_with_memory_dir for every non-benign error. A lock error that outlives the 15-second busy_timeout returns SQLITE_BUSY, which classify_additive_migration_error treats as genuine. On such a workspace the store no longer opens at all, where the previous code continued with a possibly incomplete schema. That is the intended trade, so confirm the desktop and CLI boot paths surface this failure as a readable message instead of a crash.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/namespace_store/init.rs` around lines 240 - 252,
Verify the desktop and CLI boot paths that call new_with_memory_dir surface
propagated SQLite migration failures as readable user-facing messages rather
than panicking or crashing. Preserve the current `?` propagation and
classify_additive_migration_error behavior, including aborting startup for
persistent SQLITE_BUSY errors.
src/openhuman/memory/store/golden.rs (2)

109-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Derive the epoch seconds from fixed_time.

The literal 1_700_000_000 appears in both helpers. A future edit to one value silently desynchronizes the tinycortex rows from the SQLite rows in the fixture.

♻️ Proposed single source of truth
 fn fixed_epoch_secs() -> f64 {
-    1_700_000_000.0
+    fixed_time().timestamp() as f64
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/golden.rs` around lines 109 - 117, Update
fixed_epoch_secs to derive its value from fixed_time instead of duplicating the
timestamp literal, ensuring both fixture representations remain synchronized
when fixed_time changes.

1-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Mark the module hidden so it matches the allowlist claim.

docs/specs/memory-guard-allowlist.md states this module is #[doc(hidden)]. The file carries no such attribute, and every item is pub, so the fixture engine becomes part of the crate's documented public API. Add the attribute at the module declaration in src/openhuman/memory/store/mod.rs, or correct the document.

♻️ Suggested declaration change in `src/openhuman/memory/store/mod.rs`
/// Golden-workspace fixture engine. Test infrastructure; not a supported API.
#[doc(hidden)]
pub mod golden;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/golden.rs` around lines 1 - 56, Add #[doc(hidden)]
to the public golden module declaration in the memory store module, preserving
its existing visibility and adding the suggested test-infrastructure
documentation comment if appropriate. Do not alter the fixture implementation in
golden.rs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/regen-memory-golden-fixture.sh`:
- Around line 40-45: Update the source-change check in
regen-memory-golden-fixture.sh to compare src/openhuman/memory against HEAD,
detecting both staged and unstaged changes. When the comparison differs, print
the existing warning context and exit nonzero instead of generating fixtures;
preserve the clean-tree path and SOURCE_SHA recording for unchanged memory
source.

In `@src/openhuman/memory/store/golden.rs`:
- Around line 1-56: Apply the containment fix at the pub mod golden declaration
in src/openhuman/memory/store/mod.rs by adding #[doc(hidden)]. Update
docs/specs/memory-guard-allowlist.md (lines 112-123) to retain the
#[doc(hidden)] statement only once the attribute is present; otherwise describe
the module as public with no callers outside tests. The golden.rs range (lines
1-56) requires no direct change.

In `@src/openhuman/memory/store/mod.rs`:
- Around line 42-48: Restrict the golden fixture module instead of exposing it
unconditionally through `pub mod golden`; update the module declaration and
crate feature configuration so it is compiled only under a dedicated
test-support feature, and enable that feature for
`tests/memory_golden_fixture_e2e.rs`. Keep `golden::seed`, `golden::read_back`,
and `golden::init_fresh_schema` unavailable to ordinary downstream crates.

In `@tests/memory_golden_fixture_e2e.rs`:
- Around line 349-376: Update run_second_process_readback to pass the parent
test’s temporary HOME directory to the child process by adding the corresponding
HOME environment assignment to the Command builder, reusing the existing
temporary-directory value used when setting the parent environment.
- Around line 190-228: Add `let _lock = env_lock();` at the start of both
`golden_fixture_schema_matches_the_committed_manifest` and
`fresh_workspace_schema_matches_the_committed_manifest`, before any workspace
setup or schema operations, so environment readers are serialized with the tests
that mutate environment variables.

---

Nitpick comments:
In `@src/openhuman/memory/store/golden.rs`:
- Around line 109-117: Update fixed_epoch_secs to derive its value from
fixed_time instead of duplicating the timestamp literal, ensuring both fixture
representations remain synchronized when fixed_time changes.
- Around line 1-56: Add #[doc(hidden)] to the public golden module declaration
in the memory store module, preserving its existing visibility and adding the
suggested test-infrastructure documentation comment if appropriate. Do not alter
the fixture implementation in golden.rs.

In `@src/openhuman/memory/store/namespace_store/init.rs`:
- Around line 240-252: Verify the desktop and CLI boot paths that call
new_with_memory_dir surface propagated SQLite migration failures as readable
user-facing messages rather than panicking or crashing. Preserve the current `?`
propagation and classify_additive_migration_error behavior, including aborting
startup for persistent SQLITE_BUSY errors.

In `@src/openhuman/memory/store/write_gate.rs`:
- Around line 90-100: Lower the canonicalization log in the write-gate flow
around `safety::canonical_document_key` from `log::info!` to `log::debug!`,
preserving the existing stable prefix, message, and `key_chars` field.

In `@tests/fixtures/memory_golden/manifest.txt`:
- Around line 14-15: Track follow-up work for the duplicate
kv_namespace(namespace) indexes represented by idx_kv_namespace_ns and
idx_kv_ns, and for adding schema versioning to the host database reported by
memory/memory.db; preserve the current fixture while recording both items for
future cleanup and migration support.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1501b67c-cdab-408e-9cc2-bf5c800929bf

📥 Commits

Reviewing files that changed from the base of the PR and between c7e15ba and 04cad95.

⛔ Files ignored due to path filters (2)
  • tests/fixtures/memory_golden/workspace/memory/memory.db is excluded by !**/*.db
  • tests/fixtures/memory_golden/workspace/memory_tree/chunks.db is excluded by !**/*.db
📒 Files selected for processing (18)
  • .gitattributes
  • docs/specs/memory-guard-allowlist.md
  • scripts/ci/rust-coverage-changed.sh
  • scripts/regen-memory-golden-fixture.sh
  • scripts/test-rust-e2e.sh
  • src/openhuman/memory/bypass_allowlist_tests.rs
  • src/openhuman/memory/store/golden.rs
  • src/openhuman/memory/store/memory_trait.rs
  • src/openhuman/memory/store/mod.rs
  • src/openhuman/memory/store/namespace_store/documents.rs
  • src/openhuman/memory/store/namespace_store/init.rs
  • src/openhuman/memory/store/recall_policy.rs
  • src/openhuman/memory/store/write_gate.rs
  • src/openhuman/memory/store/write_gate_tests.rs
  • tests/fixtures/memory_golden/README.md
  • tests/fixtures/memory_golden/manifest.txt
  • tests/memory_golden_fixture_e2e.rs
  • tests/memory_golden_parity_e2e.rs

Comment on lines +40 to +45
SOURCE_SHA="$(git rev-parse HEAD)"
if ! git diff --quiet -- src/openhuman/memory; then
echo "[golden-fixture] WARNING: src/openhuman/memory has uncommitted changes." >&2
echo "[golden-fixture] The fixture will capture the WORKING TREE, but the" >&2
echo "[golden-fixture] README will record ${SOURCE_SHA}. Commit first." >&2
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Fail when memory source differs from HEAD.

Line 40 records HEAD, but lines 41-45 continue after detecting only unstaged changes. Staged memory changes are not detected at all.

The generated SQLite blobs can therefore contain uncommitted code while README.md states that they came from HEAD. Check with git diff --quiet HEAD -- src/openhuman/memory and exit nonzero when it differs.

Proposed fix
 SOURCE_SHA="$(git rev-parse HEAD)"
-if ! git diff --quiet -- src/openhuman/memory; then
-  echo "[golden-fixture] WARNING: src/openhuman/memory has uncommitted changes." >&2
-  echo "[golden-fixture]          The fixture will capture the WORKING TREE, but the" >&2
-  echo "[golden-fixture]          README will record ${SOURCE_SHA}. Commit first." >&2
+if ! git diff --quiet HEAD -- src/openhuman/memory; then
+  echo "[golden-fixture] ERROR: src/openhuman/memory differs from HEAD." >&2
+  echo "[golden-fixture] Commit memory changes before regenerating the fixture." >&2
+  exit 1
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SOURCE_SHA="$(git rev-parse HEAD)"
if ! git diff --quiet -- src/openhuman/memory; then
echo "[golden-fixture] WARNING: src/openhuman/memory has uncommitted changes." >&2
echo "[golden-fixture] The fixture will capture the WORKING TREE, but the" >&2
echo "[golden-fixture] README will record ${SOURCE_SHA}. Commit first." >&2
fi
SOURCE_SHA="$(git rev-parse HEAD)"
if ! git diff --quiet HEAD -- src/openhuman/memory; then
echo "[golden-fixture] ERROR: src/openhuman/memory differs from HEAD." >&2
echo "[golden-fixture] Commit memory changes before regenerating the fixture." >&2
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/regen-memory-golden-fixture.sh` around lines 40 - 45, Update the
source-change check in regen-memory-golden-fixture.sh to compare
src/openhuman/memory against HEAD, detecting both staged and unstaged changes.
When the comparison differs, print the existing warning context and exit nonzero
instead of generating fixtures; preserve the clean-tree path and SOURCE_SHA
recording for unchanged memory source.

Comment on lines +1 to +56
//! Golden-workspace fixture: seeding, read-back, and schema-manifest capture.
//!
//! This module is the engine behind `tests/memory_golden_fixture_e2e.rs`, the
//! schema gate that stands between a memory-store change and a corrupted user
//! workspace. It lives in-crate rather than in the test file because seeding a
//! *complete* workspace needs `pub(crate)` reach that an integration test does
//! not have — `MemoryClient::profile_conn`, `trees::store::insert_summary_tx`,
//! and `trees::store::update_tree_after_seal_tx` are all deliberately
//! crate-private escape hatches.
//!
//! # The four entry points
//!
//! - [`seed`] materialises every structure the gate protects into a workspace,
//! using production write paths (`memory::ops::*` and the same typed store
//! helpers the archivist and the learning cache call).
//! - [`read_back`] reads all of it out again through `memory::ops` — proving
//! the *code path* still works, not merely that the schema still parses.
//! - [`init_fresh_schema`] stands up an empty workspace's schema, which is the
//! only way to see an *in-place* DDL redefinition (`CREATE … IF NOT EXISTS`
//! is a no-op against a DB that already holds the name).
//! - [`schema_manifest`] dumps `sqlite_master` (tables, indexes, triggers) plus
//! `PRAGMA user_version` across every `*.db` in the workspace, normalised to
//! a deterministic, diffable text form.
//!
//! # Why the fixture must be captured, not synthesised
//!
//! The committed fixture under `tests/fixtures/memory_golden/` was produced by
//! a **specific past build**. The manifest is derived from that fixture by
//! [`schema_manifest`], never hand-written. That combination is what makes the
//! gate bite: editing a `CREATE TABLE` in `namespace_store/init.rs` *and*
//! editing the manifest to match still fails, because the committed `.db` was
//! built by the older binary and no longer matches the new DDL. Making the
//! suite green requires deliberately regenerating the fixture — a visible,
//! reviewable act. See `tests/fixtures/memory_golden/README.md`.
//!
//! Debug logging uses the `[golden]` prefix throughout. Nothing seeded here is
//! real user data: every value is a fixed literal chosen to be obviously
//! synthetic.

use std::collections::BTreeSet;
use std::path::{Path, PathBuf};

use anyhow::{Context as _, Result};
use chrono::{DateTime, TimeZone, Utc};

use crate::openhuman::config::Config;
use crate::openhuman::memory::ops::{
doc_list, doc_put, graph_query, graph_upsert, kv_get, memory_query_namespace, GraphQueryParams,
GraphUpsertParams, KvGetDeleteParams, KvSetParams, NamespaceOnlyParams, PutDocParams,
};
use crate::openhuman::memory::rpc_models::QueryNamespaceRequest;
use crate::openhuman::memory::store::chunks;
use crate::openhuman::memory::store::chunks::types::{Chunk, Metadata, SourceKind, SourceRef};
use crate::openhuman::memory::store::namespace_store::{events, fts5, profile, segments};
use crate::openhuman::memory::store::trees;
use crate::openhuman::memory::store::trees::types::{SummaryNode, Tree, TreeKind, TreeStatus};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

The fixture module is not #[doc(hidden)], so the allowlist entry overstates its containment. One root cause: the module declaration never received the attribute, and the specification documents it as if it had.

  • src/openhuman/memory/store/golden.rs#L1-L56: add #[doc(hidden)] to the pub mod golden; declaration in src/openhuman/memory/store/mod.rs, so the fixture engine stays out of the documented public API.
  • docs/specs/memory-guard-allowlist.md#L112-L123: keep the #[doc(hidden)] sentence only after the attribute lands; otherwise remove that clause and state that the module is public but has no caller outside tests/.
📍 Affects 2 files
  • src/openhuman/memory/store/golden.rs#L1-L56 (this comment)
  • docs/specs/memory-guard-allowlist.md#L112-L123
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/golden.rs` around lines 1 - 56, Apply the
containment fix at the pub mod golden declaration in
src/openhuman/memory/store/mod.rs by adding #[doc(hidden)]. Update
docs/specs/memory-guard-allowlist.md (lines 112-123) to retain the
#[doc(hidden)] statement only once the attribute is present; otherwise describe
the module as public with no callers outside tests. The golden.rs range (lines
1-56) requires no direct change.

Comment on lines +42 to +48
/// Golden-workspace fixture seeding / read-back / schema-manifest capture.
///
/// Public only so `tests/memory_golden_fixture_e2e.rs` can drive it; it needs
/// `pub(crate)` reach (`MemoryClient::profile_conn`, the tree seal helpers)
/// that an integration test does not have. Not part of the product API.
#[doc(hidden)]
pub mod golden;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 2 'pub mod golden|pub (async )?fn (seed|init_fresh_schema|read_back)' \
  src/openhuman/memory/store

rg -n -C 2 'openhuman_core::openhuman::memory::store::golden' tests

Repository: tinyhumansai/openhuman

Length of output: 2831


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '--- memory store public module docs ---\n'
wc -l src/openhuman/memory/store/mod.rs src/openhuman/memory/store/golden.rs src/openhuman/memory/store/memory_trait.rs
sed -n '1,90p' src/openhuman/memory/store/mod.rs
sed -n '1,190p' src/openhuman/memory/store/golden.rs

printf '\n--- usages of golden module ---\n'
rg -n -C 2 'openhuman::memory::store::golden|memory::store::golden|store::golden::|read_back|init_fresh_schema|seed\(' .

Repository: tinyhumansai/openhuman

Length of output: 251


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- memory store public module docs ---'
wc -l src/openhuman/memory/store/mod.rs src/openhuman/memory/store/golden.rs src/openhuman/memory/store/memory_trait.rs
sed -n '1,90p' src/openhuman/memory/store/mod.rs
sed -n '1,190p' src/openhuman/memory/store/golden.rs

printf '%s\n' ''
printf '%s\n' '--- usages of golden module ---'
rg -n -C 2 'openhuman::memory::store::golden|memory::store::golden|store::golden::|read_back|init_fresh_schema|seed\(' .

Repository: tinyhumansai/openhuman

Length of output: 49991


Keep the golden fixture helpers out of the public crate surface.

pub mod golden exposes golden::seed, golden::read_back, and golden::init_fresh_schema to downstream crates; #[doc(hidden)] only avoids documentation. These functions create and mutate workspace databases, so an external crate can invoke test fixture state outside the intended integration-test boundary. Gate the module behind a test-support feature and enable it only for tests/memory_golden_fixture_e2e.rs, or move the support into in-crate tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/store/mod.rs` around lines 42 - 48, Restrict the golden
fixture module instead of exposing it unconditionally through `pub mod golden`;
update the module declaration and crate feature configuration so it is compiled
only under a dedicated test-support feature, and enable that feature for
`tests/memory_golden_fixture_e2e.rs`. Keep `golden::seed`, `golden::read_back`,
and `golden::init_fresh_schema` unavailable to ordinary downstream crates.

Comment on lines +190 to +228
#[test]
fn golden_fixture_schema_matches_the_committed_manifest() {
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
copy_fixture_to(&workspace);

let actual = golden::schema_manifest(&workspace).expect("dump fixture schema");
eprintln!(
"[golden-fixture] fixture holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}

/// Gate 2 — a **fresh** workspace built by the current code has exactly the
/// schema the fixture captured.
///
/// Gate 3 reopens the committed fixture, which cannot see an *in-place*
/// redefinition: `CREATE TABLE / INDEX / TRIGGER IF NOT EXISTS` is a no-op
/// against a DB that already holds the name, so changing an existing object's
/// definition leaves an old workspace untouched. A fresh DB takes the new DDL,
/// so this half catches exactly that edit.
///
/// Touches no process globals.
#[tokio::test]
async fn fresh_workspace_schema_matches_the_committed_manifest() {
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
golden::init_fresh_schema(&workspace)
.await
.expect("initialise a fresh workspace schema");

let actual = golden::schema_manifest(&workspace).expect("dump fresh schema");
eprintln!(
"[golden-fixture] fresh workspace holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Take env_lock() in the two gates that run without it.

golden_fixture_schema_matches_the_committed_manifest and fresh_workspace_schema_matches_the_committed_manifest run on the same test threads as golden_fixture_rows_read_back_and_schema_is_stable_after_reopen, which mutates HOME and OPENHUMAN_WORKSPACE through unsafe set_var. The EnvVarGuard safety comment states that env_lock() serializes env mutation, but that holds only when every test that reads the environment also holds the lock. Any config lookup inside UnifiedMemory::new or the tinycortex init that reads an env var can race with the writer.

Add let _lock = env_lock(); to both gates, so the lock covers readers as well as writers.

🔒️ Proposed fix
 #[test]
 fn golden_fixture_schema_matches_the_committed_manifest() {
+    let _lock = env_lock();
     let tmp = tempdir().expect("tempdir");
 #[tokio::test]
 async fn fresh_workspace_schema_matches_the_committed_manifest() {
+    let _lock = env_lock();
     let tmp = tempdir().expect("tempdir");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[test]
fn golden_fixture_schema_matches_the_committed_manifest() {
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
copy_fixture_to(&workspace);
let actual = golden::schema_manifest(&workspace).expect("dump fixture schema");
eprintln!(
"[golden-fixture] fixture holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}
/// Gate 2 — a **fresh** workspace built by the current code has exactly the
/// schema the fixture captured.
///
/// Gate 3 reopens the committed fixture, which cannot see an *in-place*
/// redefinition: `CREATE TABLE / INDEX / TRIGGER IF NOT EXISTS` is a no-op
/// against a DB that already holds the name, so changing an existing object's
/// definition leaves an old workspace untouched. A fresh DB takes the new DDL,
/// so this half catches exactly that edit.
///
/// Touches no process globals.
#[tokio::test]
async fn fresh_workspace_schema_matches_the_committed_manifest() {
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
golden::init_fresh_schema(&workspace)
.await
.expect("initialise a fresh workspace schema");
let actual = golden::schema_manifest(&workspace).expect("dump fresh schema");
eprintln!(
"[golden-fixture] fresh workspace holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}
#[test]
fn golden_fixture_schema_matches_the_committed_manifest() {
let _lock = env_lock();
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
copy_fixture_to(&workspace);
let actual = golden::schema_manifest(&workspace).expect("dump fixture schema");
eprintln!(
"[golden-fixture] fixture holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}
/// Gate 2 — a **fresh** workspace built by the current code has exactly the
/// schema the fixture captured.
///
/// Gate 3 reopens the committed fixture, which cannot see an *in-place*
/// redefinition: `CREATE TABLE / INDEX / TRIGGER IF NOT EXISTS` is a no-op
/// against a DB that already holds the name, so changing an existing object's
/// definition leaves an old workspace untouched. A fresh DB takes the new DDL,
/// so this half catches exactly that edit.
///
/// Touches no process globals.
#[tokio::test]
async fn fresh_workspace_schema_matches_the_committed_manifest() {
let _lock = env_lock();
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path().join("workspace");
golden::init_fresh_schema(&workspace)
.await
.expect("initialise a fresh workspace schema");
let actual = golden::schema_manifest(&workspace).expect("dump fresh schema");
eprintln!(
"[golden-fixture] fresh workspace holds {} schema objects",
actual.len()
);
assert_manifest_set_equal(&committed_manifest(), &actual);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/memory_golden_fixture_e2e.rs` around lines 190 - 228, Add `let _lock =
env_lock();` at the start of both
`golden_fixture_schema_matches_the_committed_manifest` and
`fresh_workspace_schema_matches_the_committed_manifest`, before any workspace
setup or schema operations, so environment readers are serialized with the tests
that mutate environment variables.

Comment on lines +349 to +376
fn run_second_process_readback(workspace: &Path) {
let exe = std::env::current_exe().expect("current test binary path");
eprintln!(
"[golden-fixture] reopening {} in a second process ({})",
workspace.display(),
exe.display()
);
let output = std::process::Command::new(exe)
.args([
"--exact",
"second_process_readback",
"--ignored",
"--nocapture",
"--test-threads=1",
])
.env(SECOND_PROCESS_WS_ENV, workspace)
.env("OPENHUMAN_WORKSPACE", workspace)
.output()
.expect("spawn second-process reopen check");
assert!(
output.status.success(),
"second-process reopen of the golden workspace failed ({})\n\
--- stdout ---\n{}\n--- stderr ---\n{}",
output.status,
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Pass HOME to the child process.

The parent test redirects HOME to a temporary directory before it opens the fixture. The spawned child receives SECOND_PROCESS_WS_ENV and OPENHUMAN_WORKSPACE only, so it inherits the real HOME. Any config or state lookup that falls back to the home directory then reads and writes the developer's or the CI runner's home, which breaks the isolation the parent set up.

🔒️ Proposed fix
-fn run_second_process_readback(workspace: &Path) {
+fn run_second_process_readback(workspace: &Path, home: &Path) {
     let exe = std::env::current_exe().expect("current test binary path");
@@
         .env(SECOND_PROCESS_WS_ENV, workspace)
         .env("OPENHUMAN_WORKSPACE", workspace)
+        .env("HOME", home)
         .output()

Update the call site to pass the same temporary directory the parent used for HOME.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/memory_golden_fixture_e2e.rs` around lines 349 - 376, Update
run_second_process_readback to pass the parent test’s temporary HOME directory
to the child process by adding the corresponding HOME environment assignment to
the Command builder, reusing the existing temporary-directory value used when
setting the parent environment.

@senamakel
senamakel merged commit c32b1c1 into tinyhumansai:main Aug 10, 2026
21 of 32 checks passed

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes: 1 lane(s) blocking, worst finding is critical.

Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.

             $0.0171 · 254,970 in / 47,570 out · 196,200 cached (77%) · z-ai/glm-5.2
critique:    $0.0102 · 103,077 in / 34,451 out · 79,940 cached (78%)  · z-ai/glm-5.2
security:    $0.0031 · 61,632 in  / 6,957 out  · 48,903 cached (79%)  · z-ai/glm-5.2
tests:       $0.0018 · 43,982 in  / 3,237 out  · 34,440 cached (78%)  · z-ai/glm-5.2
description: $0.0020 · 46,279 in  / 2,925 out  · 32,917 cached (71%)  · z-ai/glm-5.2

# The golden memory-workspace fixture (committed .db blobs + the derived
# manifest). A change here IS the schema-gate re-baseline, so run the
# gates rather than falling through to the `*)` full-suite arm.
test_targets_raw="${test_targets_raw}memory_golden_fixture_e2e

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique likely

Run both golden gates on fixture changes, not just one

The new tests/fixtures/memory_golden/*) arm comments that a fixture change is "the schema-gate re-baseline, so run the gates" (plural), but it only appends memory_golden_fixture_e2e to test_targets_raw. The sibling gate memory_golden_parity_e2e — the one domain_integration_targets adds for src/openhuman/memory/** changes — is omitted. Re-baselining the committed fixture is exactly when parity needs to run: the parity gate is what compares the fixture against the implementation, so a fixture-only change can now pass CI without verifying that the new baseline still agrees with the code. Either the comment is wrong and only one gate is intended, or memory_golden_parity_e2e should be appended here too.

[RULE] logic does not do what the surrounding code implies it should ·

let docs = memory.load_documents_for_scope("safe").await.unwrap();
assert_eq!(docs.len(), 1);
assert!(
!docs[0].key.contains("123-45-6789"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique likely

Pin row addressability in the PII-key canonicalization test

The test is named gate_canonicalizes_a_pii_like_key_and_keeps_the_row_addressable, but the body only asserts that the PII substring is gone from the stored key:

    assert!(
        !docs[0].key.contains("123-45-6789"),
        "a PII-like key must be canonicalized rather than stored raw, got {:?}",
        docs[0].key
    );

There is no assertion that the row is still addressable after canonicalization — e.g. that it can be loaded by its canonicalized key, or that docs[0].key equals a specific addressable value. A canonicalization that produced an unfindable/non-addressable key would pass this test. The "keeps the row addressable" half of the contract the test name advertises is not actually pinned.

[RULE] Test claims to verify addressability but does not ·

let path = entry.path();
if path.is_dir() {
prune_non_db_files(&path);
} else if path.extension().and_then(|e| e.to_str()) != Some("db") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique uncertain

Preserve non-.db provenance files when pruning the fixture

The module doc says the fixture directory contains a README.md documenting the build SHA: tests/fixtures/memory_golden/workspace/**.db ... (see that directory's README.md for the SHA). But regenerate_golden_fixture calls prune_non_db_files(&target) where target is fixture_workspace() (tests/fixtures/memory_golden/workspace). prune_non_db_files deletes every file whose extension is not .db, so a README.md (or any other non-.db provenance sidecar) sitting in the committed fixture workspace would be silently destroyed on every regeneration. The function is designed to strip transient SQLite -wal/-shm siblings, but its filter is too broad for a directory that is documented to hold a README. If the README lives in tests/fixtures/memory_golden/ (the parent) this is harmless; if it lives in workspace/ it is lost on regen.

[RULE] prune_non_db_files deletes every non-.db file in the fixture workspace, including the README that the module doc says lives there ·

/// A private key body, split so this source file does not itself contain a
/// scanner-tripping literal in one piece.
const PRIVATE_KEY_BODY: &str =
"-----BEGIN PRIVATE KEY-----\nMIIBVgIBADANBgkq\n-----END PRIVATE KEY-----";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority critical commits confident

Remove the committed private key (a private key)

Rotate the key, remove it from the working tree, and purge it from history — a force-push alone does not remove it from forks or from anyone who already fetched.

[RULE] private-key ·

@tinysweeper

tinysweeper Bot commented Aug 10, 2026

Copy link
Copy Markdown

What this change touches

20 files, +2515 -186 across 9 components. The code graph knows nothing about these files yet — normal for newly added files, and a cold index otherwise.

flowchart LR
  n0["src/openhuman/memory/store<br/>8 files +1642 -186<br/>2 findings"]:::blocking
  n1["tests<br/>2 files +512 -0<br/>1 finding"]:::flagged
  n2["tests/fixtures/memory_golden<br/>2 files +172 -0"]:::changed
  n3["scripts<br/>2 files +108 -0"]:::changed
  n4["scripts/ci<br/>1 file +45 -0<br/>1 finding"]:::flagged
  n5["src/openhuman/memory<br/>1 file +18 -0"]:::changed
  n6["docs/specs<br/>1 file +12 -0"]:::changed
  n7["root<br/>1 file +6 -0"]:::changed
  n8["tests/fixtures/memory_golden/workspace<br/>2 files +0 -0"]:::changed
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading

Green: changed. Grey: untouched, reached through an import or a call. Orange: has findings. Red: has a finding that blocks the merge.

Component Files Lines Findings
src/openhuman/memory/store changed 8 +1642 -186 2 (critical)
tests changed 2 +512 -0 1 (medium)
tests/fixtures/memory_golden changed 2 +172 -0
scripts changed 2 +108 -0
scripts/ci changed 1 +45 -0 1 (medium)
src/openhuman/memory changed 1 +18 -0
docs/specs changed 1 +12 -0
(root) changed 1 +6 -0
tests/fixtures/memory_golden/workspace changed 2 +0 -0
Changed files

src/openhuman/memory/store

  • src/openhuman/memory/store/golden.rs
  • src/openhuman/memory/store/memory_trait.rs
  • src/openhuman/memory/store/mod.rs
  • src/openhuman/memory/store/namespace_store/documents.rs
  • src/openhuman/memory/store/namespace_store/init.rs
  • src/openhuman/memory/store/recall_policy.rs
  • src/openhuman/memory/store/write_gate.rs
  • src/openhuman/memory/store/write_gate_tests.rs

tests

  • tests/memory_golden_fixture_e2e.rs
  • tests/memory_golden_parity_e2e.rs

tests/fixtures/memory_golden

  • tests/fixtures/memory_golden/README.md
  • tests/fixtures/memory_golden/manifest.txt

scripts

  • scripts/regen-memory-golden-fixture.sh
  • scripts/test-rust-e2e.sh

scripts/ci

  • scripts/ci/rust-coverage-changed.sh

src/openhuman/memory

  • src/openhuman/memory/bypass_allowlist_tests.rs

docs/specs

  • docs/specs/memory-guard-allowlist.md

(root)

  • .gitattributes

tests/fixtures/memory_golden/workspace

  • tests/fixtures/memory_golden/workspace/memory/memory.db
  • tests/fixtures/memory_golden/workspace/memory_tree/chunks.db

tinysweeper 0.1.0

@tinysweeper tinysweeper Bot added the priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole. label Aug 10, 2026
senamakel added a commit to nocstah/openhuman that referenced this pull request Sep 11, 2026
…\nrefactor(memory): hoist policy out of the engine and make the workspace schema gate real\n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant