Add P1-#6: Capabilities cache TTL invalidation E2E (F3.cache-invalidation)
Summary
- New E2E
Listening_ProbePastCacheTtl_RebuildsWithFreshAgentValuepins the OTHER direction of the[CacheResponse(60)]cache contract - Existing
Listening_RepeatedProbes_WithinCacheTtl_ReturnCachedResponseasserts the cache holds within TTL; this PR asserts it expires + rebuilds past TTL - Catches "cache TTL silently stretched" regressions invisible to the existing within-TTL test
Why this matters
[CacheResponse(60)] is a contract attribute on ICapabilitiesService.GetCapabilities — production server caches the response for 60s to reduce health-check-poll storms.
| Test | Direction asserted |
|---|---|
Listening_RepeatedProbes_WithinCacheTtl_ReturnCachedResponse |
Cache holds within 60s window (returns stale v1 even after agent flips to v2) |
Listening_ProbePastCacheTtl_RebuildsWithFreshAgentValue (this PR) |
Cache expires + rebuilds past 60s window (returns fresh v2) |
Pre-PR untested risk
If cache TTL stretches silently (regression changes [CacheResponse(60)] to [CacheResponse(3600)]):
- Operators would see stale version in UI for an HOUR after every upgrade
- The within-TTL test would still pass (60s contract is a ceiling)
- Only an explicit "wait past 60s + assert refresh" catches it
Test mechanism (~75s)
- Initial probe at v1 → cached for ≤60s
- Flip agent to v2 (server cache still has v1)
- Within-TTL probe → returns CACHED v1 (sanity: cache works)
- Wait > 60s (production cache TTL) — total wait 65s
- Post-TTL probe → cache miss → rebuild → returns FRESH v2
Why test runtime is 75s
[CacheResponse(60)] is a wire-contract attribute on ICapabilitiesService.GetCapabilities. Making it configurable for tests would either:
- Change production behaviour (bad)
- Require a test-only contract (violates Rule 12.4 — test would run against a different surface than production)
75s test runtime is the cost of pinning the real production contract.
Test plan
-
dotnet build— 0 errors -
CI on windows-latestrunsCategory=TentacleCapabilitiesE2E:-
Listening_ProbePastCacheTtl_RebuildsWithFreshAgentValuepasses (~75s) -
All other capabilities tests still green
-
Phase status — P0/P1 sweep complete after this lands
| PR | Priority | Title | Status |
|---|---|---|---|
| #275 | P0-#3 | LocalScriptService async-flush |
|
| #276 | P0-#1 | SCM-launched real-binary E2E |
|
| #277 | P0-#2 | Server-restart polling-reconnect E2E |
|
| #278 | P1-#4 | Upgrade + polling composite E2E |
|
| #279 | P1-#5 | Long-soak with leak detection |
|
| this | P1-#6 | Capabilities cache TTL invalidation |
|