test(module): drive a source sync over the bus, not just its routing - #152
Merged
YellowSnnowmann merged 1 commit intoSep 9, 2026
Merged
Conversation
`every_declared_method_is_actually_routed` walks the module's declared method list and checks each one dispatches. Six sync members are in that list and none was ever called. Routing is not behaviour, and the sync pipeline is what a connector-backed install spends its time doing. Measured before writing this: 143 unique declared members, 96 driven over the bus, 47 listed-only — ten of them sync. The pipeline itself is not short of tests; there are ~397 across this workspace. Every one runs in-process. What none of them reaches is the same pipeline over the bus, and that is a real gap rather than a formality: the module is a separately compiled `cdylib` with its own statics, so a task-local set host-side reads as absent inside it, and the host's sync entry points are where scope and credentials cross that boundary. The case syncs a `folder` source over a temp directory holding one file — no network, no credentials — and then asks the store, over the same bus, whether the chunks are there. That second call is the point: `records_ingested` is the run's own report, `chunks_synced` is the store's, and a member that answered a plausible `SyncRunOutcome` without writing anything satisfies the first and fails the second. Mutation-tested by removing the fixture file, which turns `records_ingested` to 0 and takes the case red. Three things the implementation found, each of which the test now pins: **The registry is not `admit_module`'s `memory_sources` config key.** That key is the serialized registry snapshot operations read; `run_source_sync` resolves ids through `get_source_in` against the host's `config.toml`. Registering in the wrong one answers `NotFound` for every source — openhuman#5820's "no memory source registered as src_…" strand, which `config.rs`'s own doc comment predicts and which this test hit first. **`RunSourceSync` writes no audit row.** It goes through `engine::run_source_pipeline`; the audit appends live in `sources::sync::sync_source`, the periodic path. Asserting an audit row here — the obvious reading of "assert its effect" — would have asserted something the member does not do. The absence is pinned instead, because the two entry points look interchangeable from the wire and a caller polling the audit log after a manual sync would wait forever. **`SourceSyncState` refuses on this engine**, with `Invalid` and a message naming the connector module as the owner. `Invalid` rather than `Unsupported` is the distinction worth keeping: the family is served, this member's subject is not. Closes tinyhumansai#149
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Comment |
YellowSnnowmann
marked this pull request as ready for review
September 9, 2026 20:39
There was a problem hiding this comment.
tinysweeper found nothing blocking. Approving.
$0.0024 · 32,809 in / 326 out · 0 cached (0%) · openrouter/openai/text-embedding-3-small, deepseek/deepseek-v4-flash · 490 embedded
critique: $0.0009 · 13,214 in / 73 out · 0 cached (0%) · deepseek/deepseek-v4-flash
security: $0.0009 · 13,193 in / 148 out · 0 cached (0%) · deepseek/deepseek-v4-flash
description: $0.0005 · 6,402 in / 105 out · 0 cached (0%) · deepseek/deepseek-v4-flash
How this change flows1 changed behaviour across 13 relationships. 6 surrounding behaviours are shown (60 graph nodes walked). 40 further behaviours left out to keep the diagram readable. flowchart LR
n0["...s_its_provider_registry_inside_the_module<br/>changed"]:::changed
n1["call"]:::impacted
n2["assert"]:::impacted
n3["admit_module"]:::impacted
n4["Result"]:::impacted
n5["proxy"]:::impacted
n6["..._runs_over_the_bus_and_lands_in_the_store"]:::impacted
n0 -->|calls| n1
n0 -->|tests| n1
n0 -->|calls| n2
n0 -->|calls| n3
n0 -->|uses| n4
n0 -->|calls| n5
n1 -->|uses| n4
n6 -->|calls| n1
n6 -->|tests| n1
n6 -->|calls| n2
n6 -->|calls| n3
n6 -->|uses| n4
n6 -->|calls| n5
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
Green: changed behaviour. Grey: surrounding behaviour. Arrows name the call, use, implementation, or test relationship. Orange: has findings. Red: has a finding that blocks the merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
every_declared_method_is_actually_routedwalks the module's declared method list and checks each one dispatches. Six sync members are in that list and, until now, none was ever called. Routing is not behaviour, and the sync pipeline is what a connector-backed install spends its time doing.Measured before writing anything: 143 unique declared members, 96 driven over the bus, 47 listed-only — ten of them sync.
This adds one isolated loader case that drives
RunSourceSyncend to end through a realdlopened module and asserts its effect, then drivesSourceSyncStateand pins how it refuses.Why bus-level coverage is not redundant with the ~397 in-process sync tests
sources/sync_tests.rs,sync/audit_tests.rs,sync/workspace/periodic_tests.rsand thetinymemory-syncpost-processor suites are thorough, and every one of them runs in-process. The module is a separately compiledcdylibwith its own statics, so a task-local set host-side reads as absent inside it — and the two at this boundary (source_scope, the self-echo exclusion) are permission checks that fail open. The host's sync entry points are exactly where scope and credentials cross.module_e2e.rsis the only file in the repo that loads a real module (sole match forTINYMEMORY_TEST_MODULE), so this is the only place that gap can be closed.What the case does
Syncs a
foldersource over a temp directory holding one file — no network, no credentials, no fixture beyondtempfile— then asks the store, over the same bus, whether the chunks arrived.That second call is the point.
records_ingestedis the run's own report;chunks_syncedis the store's. A member that answered a plausibleSyncRunOutcomewithout writing anything satisfies the first assertion and fails the second.Mutation-tested: removing the fixture file gives
records_ingested: 0and takes the case red. Restoring it passes. An assertion that cannot fail is not coverage.Three findings the implementation turned up, now pinned
The source registry is not
admit_module'smemory_sourcesconfig key. That key is the serialized registry snapshot operations read;run_source_syncresolves ids throughget_source_inagainst the host'sconfig.toml. Registering in the wrong one answersNotFoundfor every source — openhuman#5820's "no memory source registered as src_…" strand, whichconfig.rs's own doc comment predicts, and which this test hit on its first run.RunSourceSyncwrites no audit row. It goes throughengine::run_source_pipeline; the audit appends live insources::sync::sync_source, the periodic path. Asserting an audit row here — the obvious reading of the issue's "assert the audit row" — would have been asserting something the member does not do. The absence is pinned instead, with a note to invert the assertion if that ever changes: the two entry points look interchangeable from the wire, and a caller polling the audit log after a manual sync would wait forever.SourceSyncStaterefuses on this engine, withInvalidand a message naming the connector module as the owner.Invalidrather thanUnsupportedis the distinction worth keeping — the family is served, this member's subject is not — and a refusal that says where the answer lives beats aNonethat reads as "no state yet".Scope
Two members driven properly, per the issue:
RunSourceSyncandSourceSyncState.BackfillConnectorTrees,SyncAuditLog(beyond reachability),IsToolkitSyncableandRunConnectionSyncstay out — each needs a Composio connection, which is not hermetic. TheNotFoundcontract for an unregistered id is asserted too; it came free and nothing checked it.Test plan
cargo fmt --all --checkand the module manifest's owncargo clippy --manifest-path crates/tinymemory-module/Cargo.toml --all-targets -- -D warningscargo build --workspace/cargo test --workspaceTINYMEMORY_TEST_MODULE=… cargo test --manifest-path crates/tinymemory-module/Cargo.toml --test module_e2e— 13 isolated cases (12 existing + this one), harness greenCloses #149