@@ -132,7 +132,7 @@ jobs:
132132 name : Feature powerset and coverage
133133 runs-on : ubuntu-latest
134134 steps :
135- - uses : actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
135+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
136136 with :
137137 submodules : recursive
138138 persist-credentials : false
@@ -143,7 +143,7 @@ jobs:
143143
144144 - uses : Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
145145
146- - uses : taiki-e/install-action@5b4d68e2e660441203ab128a23676f1e4faf1532 # v2
146+ - uses : taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2
147147 with :
148148 tool : cargo-hack,cargo-llvm-cov
149149
@@ -165,14 +165,58 @@ jobs:
165165 - name : Feature powerset compiles
166166 run : cargo hack --feature-powerset --depth 2 --workspace check --all-targets
167167
168- # §E8. `AGENTS.md` asks for 80% of meaningful library behaviour and
169- # nothing measured it. Reported rather than enforced to begin with: a
170- # threshold picked before anyone has seen the number is a guess, and a
171- # failing gate on day one gets disabled rather than fixed.
172- - name : Coverage
168+ # §E8. Enforce the repository's 80% floor over production sources only.
169+ # Test helpers and vendored code can make the aggregate look healthy
170+ # without exercising the libraries a release actually ships.
171+ - name : Enforce production-source coverage
173172 run : |
174- cargo llvm-cov --all-features --workspace --summary-only \
173+ set -euo pipefail
174+ cargo llvm-cov --all-features --workspace \
175+ --ignore-filename-regex '(^|/)(tests|vendor)/|(^|/)(test|tests|test_helpers|test_support|test_seams)\.rs$|(_test|_tests|_test_support)\.rs$|/crates/tinymemory-core/src/(engine/parity|tree/retrieval/benchmarks)\.rs$' \
176+ --fail-under-lines 80 --summary-only \
175177 | tee "$GITHUB_STEP_SUMMARY"
178+ cargo llvm-cov report \
179+ --ignore-filename-regex '(^|/)(tests|vendor)/|(^|/)(test|tests|test_helpers|test_support|test_seams)\.rs$|(_test|_tests|_test_support)\.rs$|/crates/tinymemory-core/src/(engine/parity|tree/retrieval/benchmarks)\.rs$' \
180+ --json --output-path target/production-coverage.json
181+ test_decl_line="$(grep -n '#\[cfg(test)\]' \
182+ crates/tinymemory-api/src/host/local_ai.rs | tail -1 | cut -d: -f1)"
183+ active_line="$(grep -n 'pub fn is_active' \
184+ crates/tinymemory-api/src/host/local_ai.rs | cut -d: -f1)"
185+ jq -e --argjson test_decl_line "$test_decl_line" \
186+ --argjson active_line "$active_line" '
187+ .data as $data
188+ | [$data[].files[]
189+ | select(.filename | endswith("/crates/tinymemory-api/src/host/local_ai.rs"))]
190+ as $local_ai
191+ | ($local_ai | length == 1)
192+ and ([$local_ai[].segments[]
193+ | select(.[0] >= $test_decl_line and .[3] == true)] | length == 0)
194+ and ([$local_ai[].segments[]
195+ | select(.[0] == $active_line and .[2] > 0 and .[3] == true)] | length > 0)
196+ and ([$data[].files[]
197+ | select(.filename | endswith("/local_ai_tests.rs"))] | length == 0)
198+ ' target/production-coverage.json
199+ inline_test_code="$(
200+ grep -R -l -E '^[[:space:]]*#\[cfg\((test|any\(test,)' crates \
201+ --include='*.rs' --exclude='test.rs' --exclude='tests.rs' \
202+ --exclude='*_test.rs' --exclude='*_tests.rs' \
203+ --exclude='*_test_support.rs' --exclude='test_support.rs' \
204+ --exclude='test_helpers.rs' --exclude='test_seams.rs' \
205+ | xargs -r awk '
206+ /^[[:space:]]*#\[cfg\((test|any\(test,)/ { cfgline=FNR; pending=1; next }
207+ pending && (/^[[:space:]]*$/ || /^[[:space:]]*#/ || /^[[:space:]]*\/\//) { next }
208+ pending {
209+ if ($0 !~ /^[[:space:]]*(pub\([^)]*\)[[:space:]]+)?(pub[[:space:]]+)?(mod|use)[[:space:]]/)
210+ print FILENAME ":" cfgline ":" $0
211+ pending=0
212+ }
213+ '
214+ )"
215+ if [[ -n "$inline_test_code" ]]; then
216+ printf '%s\n' "$inline_test_code" >&2
217+ echo 'inline test-only executable code must live in a filtered test file' >&2
218+ exit 1
219+ fi
176220
177221 # §E2's first half: build **and test** each engine configuration on its own.
178222 #
@@ -186,10 +230,8 @@ jobs:
186230 # `DriverRegistry` admission is a static policy table rather than a function
187231 # of which adapters were compiled in.
188232 #
189- # Two of §E2's nine configurations name features the facade does not have.
190- # `--features contacts` belongs to `tinymemory-core` and is covered by the
191- # powerset job above. `--features sync-composio` names a feature that exists
192- # nowhere in the workspace: the Composio sync is unconditional in
233+ # `--features sync-composio` names a feature that exists nowhere in the
234+ # workspace: the Composio sync is unconditional in
193235 # `tinymemory-core`, so there is nothing to select and nothing to isolate.
194236 # Recorded here rather than quietly dropped, because a missing row in a
195237 # matrix reads as covered.
@@ -208,6 +250,18 @@ jobs:
208250 features : --features tinycortex
209251 - name : tinycortex and memory-git
210252 features : --features tinycortex,memory-git
253+ - name : memory-git implication
254+ features : --no-default-features --features memory-git
255+ - name : all engines aggregate
256+ features : --no-default-features --features engines
257+ - name : sources network implication
258+ features : --no-default-features --features sources-network
259+ - name : documents network implication
260+ features : --no-default-features --features documents-network
261+ - name : contacts implication
262+ features : --no-default-features --features contacts
263+ - name : full aggregate
264+ features : --no-default-features --features full
211265 - name : mem0
212266 features : --features mem0
213267 - name : supermemory
@@ -231,6 +285,26 @@ jobs:
231285 - name : Test
232286 run : cargo test -p tinymemory ${{ matrix.features }}
233287
288+ # A retaining HTTP double checks adapter translation cheaply; this separate
289+ # job proves the routes and wire payloads against the pinned AgentMemory and
290+ # iii containers the integration guide tells operators to run.
291+ agentmemory-e2e :
292+ name : AgentMemory E2E
293+ runs-on : ubuntu-latest
294+ timeout-minutes : 15
295+ steps :
296+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
297+ with :
298+ persist-credentials : false
299+ submodules : recursive
300+
301+ - uses : dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
302+
303+ - uses : Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
304+
305+ - name : Run AgentMemory conformance
306+ run : ./scripts/ci/agentmemory-e2e.sh
307+
234308 # The module crate is its own workspace root (see the `exclude` note in the
235309 # root Cargo.toml), so NONE of the steps above touch it: `--all-targets`,
236310 # `--all-features` and `--workspace` all stop at the workspace boundary and
@@ -250,10 +324,14 @@ jobs:
250324
251325 - uses : dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
252326 with :
253- components : rustfmt, clippy
327+ components : rustfmt, clippy, llvm-tools-preview
254328
255329 - uses : Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
256330
331+ - uses : taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2
332+ with :
333+ tool : cargo-llvm-cov
334+
257335 - name : Check formatting
258336 run : cargo fmt --manifest-path crates/tinymemory-module/Cargo.toml --all -- --check
259337
@@ -273,6 +351,17 @@ jobs:
273351 - name : Unit tests
274352 run : cargo test --manifest-path crates/tinymemory-module/Cargo.toml --lib
275353
354+ # The module is excluded from the root workspace, so the root coverage
355+ # gate cannot see it. Hold its production code to the same floor here.
356+ - name : Enforce module production-source coverage
357+ run : |
358+ set -euo pipefail
359+ cargo llvm-cov --manifest-path crates/tinymemory-module/Cargo.toml \
360+ --workspace --all-features \
361+ --ignore-filename-regex '(^|/)(tests|vendor)/|(^|/)(test|tests|test_helpers|test_support|test_seams)\.rs$|(_test|_tests|_test_support)\.rs$|/crates/tinymemory-core/src/(engine/parity|tree/retrieval/benchmarks)\.rs$' \
362+ --fail-under-lines 80 --summary-only \
363+ | tee "$GITHUB_STEP_SUMMARY"
364+
276365 # The loader E2E drives a real dlopen'ed module, and tinybus binds its
277366 # broker tasks to the runtime that created them. The module is loaded once
278367 # per process and never unloaded, so two such tests in one process leave the
0 commit comments