Repository navigation
test(evals): Tier E negative control for the cross-environment parity check - #225
Merged
Merged
Conversation
… check Ports the Tier E scenario from the archived PostgreDataMigrationApp repo (commit f902ae5, never in this repo) to the current runner, whose schema query and error handling have changed since: _column_signature now raises on a failed query (issue #45), and returns a table -> columns map. Scenario 01 passes when every environment matches dev. That only means something if a deploy that wrote nothing is visible. Scenario 02, against the real database: - creates a throwaway empty schema beside dev's and requires the real schema query to read it as empty (a failed query is a failure, not an empty schema); - requires comparing dev's real schema with it to report the missing tables, which the original did not check, though it is the stated purpose; - refuses to run when dev is not deployed, since comparing nothing with nothing proves nothing; - always drops the throwaway schema, and never with CASCADE, so it cannot delete something that is not its own. Unit tests (mocked psql) pin each branch, including that the control fails when the comparison is neutralised. Verified against PostgreSQL 16 by neutralising the comparison, planting a non-empty schema under the control's name (it is left alone) and reintroducing the #45 failure mode: each turns the scenario red. README's scenario count (26 -> 27) and the Tier E notes in evals/HANDOFF.md and evals/FAILURE_MODES.md are updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBrxqChRJtxdvSpFhiUWUy
The tests moved to tests/unit/ with the reorganisation; Git carried the control's tests across the rename. One path in them computed the repo root with parent.parent and is now parents[2]. The generated test catalogue was the only conflict: taken from main and regenerated with scripts/test_catalogue.py. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBrxqChRJtxdvSpFhiUWUy
amar-python
marked this pull request as ready for review
November 9, 2026 14:50
amar-python
pushed a commit
that referenced
this pull request
Nov 9, 2026
Only the generated test catalogue conflicted: regenerated with scripts/test_catalogue.py. Evals in CI order on a fresh PostgreSQL 16: 27 passed, including the Tier E control. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBrxqChRJtxdvSpFhiUWUy
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
Ports a Tier E scenario that existed only in the archived
PostgreDataMigrationApprepo (its commitf902ae5, "add Tier E negative control for empty-schema detection") into this repo, rewritten against the currentevals/runner.py. A small, separate change; it touches none of the open PRs (#213, #221, #222).Why
Scenario
01_envs_have_identical_structurepasses when Test, Staging and Prod match Dev. That is only worth anything if a deploy that wrote nothing is something it can see. Nothing in the repo showed that against a real server: the existing unit tests cover the comparison logic with a mockedpsql.Scenario
02_empty_schema_is_detectedAgainst the real database it:
min_reference_tables), because comparing nothing with nothing proves nothing;_te_empty_neg_ctrlbeside Dev's and requires the real schema query to read it as having no tables. A failed query is a failure, not an empty schema (the confusion behind issue CI: integration job has never passed - T&E tables not found in te_dev #45);CASCADE: if something else is found under that name, the scenario fails instead of deleting what isn't its own.Scenario 01 deploys Dev first, so
--tiers eruns them in the right order. It already runs in theintegration (postgres service)job (--tiers p,i,s,e), so no workflow change is needed; the count there becomes 27.What changed from the original commit (why it is a port, not a cherry-pick)
_get_schema_fingerprint, which no longer exists. The current helper is_column_signature, which returns a table→columns map and raises on a failed query; the original'sfp is Nonebranch is obsolete.CASCADEcleanup (step 4).Files
evals/runner.py: dispatch,_psql_run,_run_empty_schema_negative_control(+109 lines)evals/datasets/tier_e/02_empty_schema_is_detected/NOTES.txt,evals/expected/tier_e/02_empty_schema_is_detected.jsontests/test_evals_tier_e_x.py: 15 new unit tests (mockedpsql), one per branch, including that the control fails when the comparison is neutralisedREADME.md(scenario count 26 → 27),evals/HANDOFF.md,evals/FAILURE_MODES.md, regenerateddocs/TEST_CASES.mddocs/VCRM.md's dated entries (e.g. "26 of 26 passed … on its first real run") are history.Verified (local, PostgreSQL 16, all four environments deployed)
python3 evals/runner.py --tiers p,i,s,ein CI order: 27 passed, 0 failed; the throwaway schema is gone afterwards.tests/test_evals_tier_e_x.py37 passed;make lintclean (flake8 + bandit);make health90/0;test_catalogue.py --checkcurrent; free tier passes.integration (postgres service), whose eval step runs--tiers p,i,s,eand fails the job on any failed scenario, so the new scenario passed against the CI database too.Not verified
I did not read the new scenario's own line in the CI step log; its pass is inferred from the job's green result (the runner exits non-zero on any failed scenario).
The control creates and drops a schema in Dev's database, so it needs the privilege to do that. The CI job and local setup connect as
postgres; a restricted role would see a clear "could not create the throwaway schema" failure, not a silent pass.CI green on the current head (9036305):
free-tier,integration (postgres service)and the Windowspython-validator-tests.🤖 Generated with Claude Code
https://claude.ai/code/session_01VBrxqChRJtxdvSpFhiUWUy