Six-scenario E2E suite: extraction→injection, cross-tenant isolation, latency, degradation ladder correctness, and MCP/proxy consistency — proving the composed system works.
Milestone 3.5.F.1 — End-to-End Learning-Loop Test Suite
Status: Completed
Goal: Track F — Exit Gate
Phase: 3.5 — Extraction & Context Assembly
Estimated effort: Composition complexity comparable to 3.5.D.4 (not the original 3-day sketch)
Track: Track F — Exit Gate
Depends on: All Tracks A–E milestones
Outcome
Prove the composed learning loop against process-managed services on compose-test infra (Postgres/Redis/ClickHouse), not a fictional full app mesh in compose-test.yml:
make e2e-smoke-p3.5 → infra/scripts/e2e_phase35.sh (IBEX_E2E_P35_MANAGE=1)
Scenarios
- Extraction → injection — terminate with non-empty turn buffer → worker stub extraction → memory row → next chat injects (
X-IBEX-Memories-Injected/ marker) - Cross-tenant smoke — Org A marker absent from Org B search/chat (thin; full matrix is 3.5.F.2)
- Latency mechanism — 20 concurrent Assemble; print p95/p99 (soft; not CI hard threshold)
- Proxy overhead mechanism — Assemble-on chat headers + optional
ibexmetadata timings printed (soft) - Degradation (ADR-0071) — L0–L1 require
candidates_evaluated > 0(L1 viaskip_cold); L2 hard zeros withskip_hot+skip_cold; L3 viaX-IBEX-Context-Fallback=true(no 4-valued header; nowas_truncatedproto field) - MCP/proxy consistency —
write_memory→ eventually proxy injects same substrate
Harness notes
- Extraction uses OpenAI-compat HTTP stub (
phase35_e2e_extraction_stub.py); worker staysIBEX_WORKER_EXTRACTION_PROVIDER=openai - Uniqueness markers are Presidio-verified word phrases (
phase35_e2e_safe_marker.py) — hex/NATO concatenations false-positive asNRP/PERSONand break search/inject proofs - Sync via bounded
eventually()polling of memory/search/headers — not CeleryAsyncResult(task_ignore_result=True) - CI job display name
e2e-smoke-p3.5(workflow ide2e-smoke-p35; YAML job ids cannot contain.) - Prefork worker asyncio:
_run_coro()in session store / engine dispose (Celery +asyncio.runloop mismatch)
Observed latency (local compose-test, soft)
Recorded from a green make e2e-smoke-p3.5 run (mechanism-gated; not CI hard thresholds):
- Scenario 3 Assemble (n=20): mean ≈ 249 ms, p95/p99 ≈ 286 ms
- Scenario 4 proxy overhead headers: p95/p99 ≈ 314 ms; context assembly p95 ≈ 183 ms
Success signals
-
make e2e-smoke-p3.5exits 0 (exit criterion #9) - Six scenarios exercised with empty-buffer hazard addressed (memory/marker proof after terminate)
- Degradation assertions match ADR-0071 (not sketch L0–L3 headers); L0/L1 require non-zero candidates
- Additive scripts/Makefile/CI — F.1 harness is new; collateral fixes only where older suites were broken
- Repo guards / CI checks still pass
Prerequisites
- All Tracks A–E milestones
Last updated on