Repository navigation
test(scenarios): S1, S7, S9, S12 and S15 catalogue scenarios on the shop pack - #361
Merged
Merged
Conversation
Five scenarios from the strategy's catalogue that test the readiness changes together over /ws on the shop pack, asserting rows, deltas, revisions, structured errors and that other agents are unaffected: agent lifecycle on a deployed rule, a concurrent claim refused with the reason, retraction through recursion and negation, a crash-restart mid-scenario, and tenant isolation with scoped keys. Each names its captain's table row and the milestone 9 issues it gates. S9's history also runs through the differential oracle (oracle_check). The oracle's reference now models schema declarations, equalities that bind a variable and '_' inside a negation, so it covers the whole pack. The testkit client returns a write's statement counts and, through try_execute and try_execute_expecting (with expect_epoch), the engine's refusal with its structured code. A permission refusal carries no code today; S15 asserts access_denied as an expected failure (#364).
jsam
marked this pull request as ready for review
October 5, 2026 21:05
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.
Intent
make sure that all those new changes we are making in accordance with the production readiness are properly covered by e2e / integration testing cause all of them are related so they cannot be tested in isolation only ... we have to check them through scenarios which we have to craft ... please ensure that all those different testing we have is cleaned up and that we bring some structure to it so we dont have too much redudancy ... our testing is getting huge and slow so ensure that we are always testing the right stuff and that this is all properly documented in TESTING.md
(Context: implement issue #336 exactly as written, part of the test strategy in ~/firstmate/data/test-strategy/report.md and TESTING.md draft.)
Substance of the referenced issue #336 ("Testing: Scenarios that run today (T-02)", part of epic #305): Scope: S1 agent lifecycle, S7 concurrent claim, S9 retraction through recursion and negation, S12 restart mid-scenario, S15 multi-tenant and scoped keys, exactly as tabled in the test strategy's scenario catalogue, on the shop pack, asserting rows, deltas, revisions, structured errors and others_unaffected. Acceptance: five scenarios green on main against recompute; each names in its doc comment the captain's table row and the milestone 9 issues it gates; S9's history is also fed to the differential oracle (scenarios::oracle_check) and agrees; total added run time under 30 s.
Substance of the referenced catalogue rows (test strategy report, Section 7.4):
The shop pack: base relations order(id, cust, total), order_item(order, item), stock(item, qty), blocked(item), link(item, other), embedding(item, vec), claim(order, item, agent); rules eligible (join, comparison, negation), related (recursion), offer (negation over recursion, !claim), n_eligible (count aggregate), near (vector, only in the vector size). Shared assertion vocabulary: rows_equal_fresh_query, delta_exact, seq_contiguous, revision_increasing, write_revision_matches_delta, refused(reply, code, message_contains), others_unaffected(agents) (every other agent receives its next delta within the deadline while one connection is refused or disconnected). The captain's table rows: 1 deployed rule as live view; 3 subscriptions read changed rows between revisions.
What Changed
scenariossuite, all running on the shop pack:lifecycle(S1),claims(S7),retraction(S9, plus S9b, which adds a second support),restart(S12) andtenancy(S15). They share one set of assertions insupport.rs: fresh-query view match, exact deltas, write revision matching the delta revision,refusedandothers_unaffected.oracle_checkalso runs the S9 and S9b histories through the differential oracle's adapters, which the suite includes by path. Two scenarios run asKnownDefectexpected failures: S15 for the missingaccess_deniedcode (Permission refusals carry no structured error code (access_denied) #364) and S12 for a bare pre-restartexpect_revisionthat is not refused (Stale expect_revision may pass after restart: revisions restart, bare revision without epoch is not refused #380).WsClientwithtry_execute,try_execute_expectingandtry_result. These return the engine'sRefusalwith its structuredcodeinstead of a violation. A newExpectbuilder setsexpect_revision,expect_relationsandexpect_epoch.RefusalandExpectare re-exported from the crate root._inside a negation matches any value, and persistent schema declarations are accepted.TESTING.mddocuments the new scenarios, the catalogue table (scenario, test, captain's table row, gates), where a scenario follows the documented contract instead of the strategy's table, and the new expected failures.Risk Assessment
Testing
I built the scenarios test binary and ran the S1, S7, S9/S9b, S12 and S15 scenarios plus the S9 differential-oracle check. Each scenario starts a real inputlayer-server with its own data directory, installs the shop pack, and drives agents, writers and keys over /ws; S12 also kills the engine with kill -9 and restarts it. All 7 tests passed in about 2 s under a 16G memory cap. Per-scenario runs logged the expected XFAILs: #380 (a bare pre-crash expect_revision is accepted after restart) and #364 (permission refusals have no access_denied code, two cases). I also changed S9's expected deltas on purpose; the test failed with an exact-delta mismatch, which shows the assertions catch wrong deltas. The file was restored and the worktree is clean. No UI surface is involved; the evidence is the CLI transcripts.
Evidence: Catalogue scenarios run (7 passed, wall time)
Evidence: Per-scenario runs with XFAIL lines for #380 and #364
XFAIL [#380] a pre-crash expect_revision without expect_epoch passes on the new run's revision: ... the request succeeded: Inserted 1 fact(s) into 'claim'. XFAIL [#364] ... missing code: expected access_denied on "Permission denied: the writer role on 'tenant_a' has no write grant for relation 'stock'" XFAIL [#364] ... missing code: expected access_denied on "Access denied: this API key is scoped to knowledge graph 'tenant_a'"Evidence: S9 mutation check: a wrong expected delta fails against the live engine
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
🔧 **Rebase** - 7 issues found → auto-fixed ✅
Makefile- merge conflict rebasing onto origin/mainTESTING.md- merge conflict rebasing onto origin/maintestkit/src/client.rs- merge conflict rebasing onto origin/maintestkit/src/counters.rs- merge conflict rebasing onto origin/maintestkit/src/fixture.rs- merge conflict rebasing onto origin/maintests/scenarios/harness.rs- merge conflict rebasing onto origin/maintests/scenarios/main.rs- merge conflict rebasing onto origin/main🔧 Fix applied.
✅ Re-checked - no issues remain.
tests/scenarios/restart.rs:21- Some catalogue assertions are replaced with different ones. The doc comments document each change, but the intent says to implement issue Testing: Scenarios that run today (T-02) #336 "exactly as written", so each replacement needs sign-off. (a) S12 row: "the first post-restart write reply revision > the last pre-crash one" and "expect_revision with a pre-restart revision is refused". restart.rs:18-21 asserts a new stream epoch instead, and its refusal check (restart.rs:117-122) pinsexpect_epoch. A bare pre-crashexpect_revisionwithout the epoch is never exercised, and after a restart it could pass silently because revisions restart. The "no overlapping seq" check is also absent (see the next finding). (b) S15 row: "the writer tries to subscribe to eligible ... each refused with access_denied". tenancy.rs:83 expects the writer's.subscribeto succeed; that refusal is replaced by a failed connect to KG-B, andaccess_deniedruns as a KnownDefect XFAIL (Permission refusals carry no structured error code (access_denied) #364), not green. (c) S9 row: "deltas retract exactly (i1,i3),(i1,i4) and the offers behind them". retraction.rs:29 adds a second support+link("i5","i4"), so only (o-42,i3) is retracted. Confirm these deviations are accepted, or align the scenarios with the table.tests/scenarios/restart.rs:103- The "nothing replayed across the restart" check filters out every notice whose relation isstock. Before the crash, S1's writer wrote+stock[("i13",4),(other,2)], so if the engine wrongly replayed that pre-crash notice on reconnect, this assertion would still pass; only a replayedclaimnotice is caught. It also does not check the catalogue's "no overlapping seq". Fix: assert the agent's notices after the restart are exactly the two post-restart stock writes (count == 2, with seq contiguous within the new epoch), or that each notice's revision is above the resubscribe snapshot revision, instead of filtering by relation name.testkit/src/client.rs:568-read_resultnow returns anerrorheader asOk(Err(Refusal)), but anerrorframe arriving afterresult_start(chunked path) is still aViolation::Rejected. Sotry_executecallers get two different shapes for an engine refusal, depending on whether the reply was chunked. No scenario hits this today (writes are not chunked), so no action is needed now.🔧 Fix applied.
1 info still open:
testkit/src/client.rs:568-read_resultnow returns anerrorheader asOk(Err(Refusal)), but anerrorframe arriving afterresult_start(chunked path) is still aViolation::Rejected. Sotry_executecallers get two different shapes for an engine refusal, depending on whether the reply was chunked. No scenario hits this today (writes are not chunked), so no action is needed now.✅ **Test** - passed
✅ No issues found.
cargo test --no-run --test scenarios(CARGO_BUILD_JOBS=4, CARGO_INCREMENTAL=0, debug info off)systemd-run --user --scope -p MemoryMax=16G -p MemorySwapMax=0 cargo test --test scenarios -- s1_ s7_ s9 s12_ s15_(7 tests: s1, s7, s9, s9b, s9 oracle, s12, s15)Each scenario run on its own with--nocapture --test-threads=1to capture XFAIL lines and per-scenario runtimeMutation check: changed S9's expected offers retraction to only (o-42,i3), re-rans9_retractionagainst the live engine (it failed with WrongDelta), then restored the file✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.