Skip to content

DEV-1510: audit livesqlbench museum gold + wire single_file overlay - #14

Merged
ZmeiGorynych merged 4 commits into
mainfrom
egor/dev-1510-audit-livesqlbench-museum-gold-against-kb-kb-contradicts
May 30, 2026
Merged

DEV-1510: audit livesqlbench museum gold + wire single_file overlay#14
ZmeiGorynych merged 4 commits into
mainfrom
egor/dev-1510-audit-livesqlbench-museum-gold-against-kb-kb-contradicts

Conversation

@ZmeiGorynych

@ZmeiGorynych ZmeiGorynych commented May 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Audited the 10 livesqlbench museum SELECT tasks against museum_kb.jsonl + museum_column_meaning_base.json + museum_schema.txt. The deliverable is audited_gold/livesqlbench_audited.jsonl (gitignored — rides into the cloud image via the BuildKit `audited-gold=` context, not git).
  • museum_7 (`edited`): KB 16 says "SESR<4 OR at least three of [4 condition flags]" but the original gold treated each flag as independently sufficient. Rewrite uses a NULL-safe `CASE WHEN ... THEN 1 ELSE 0 END + ... >= 3` predicate (SQLite boolean arithmetic is NULL-fragile).
  • museum_9 (`clean`): KB 8 (LER) doesn't pin the host table for light readings, but `column_meaning:ConditionAssessments|LightReadRefObserved` + the schema's single-hop declared FK do. Gold's join chain IS justified; `reasoning_summary` documents the KB-alone underspec.
  • Overlay wiring: previously short-circuited for livesqlbench via `not b.gold_required`. Now `Benchmark.audited_gold_layout` ∈ {`per_db`, `single_file`} controls dispatch — mini-interact keeps the per-db sidecars; livesqlbench uses a consolidated `audited_gold/livesqlbench_audited.jsonl` keyed by `instance_id` with `selected_database` as the per-DB discriminator. Both layouts flow through `apply_audited_gold_overlay` + `missing_audited_gold_ids`. Local + cloud + submit-time guard all updated.
  • Skill split: new `.claude/skills/audit-gold-sql-livesqlbench/SKILL.md` (livesqlbench-shaped — adds `external_knowledge:` citations, drops `labeled_ambiguity:`/`knowledge_ambiguity:` since no source exists in livesqlbench, treats schema FKs as first-class evidence). Shared contract at `.claude/skills/_shared/audit-gold-sql.contract.md`; mini-interact skill rewritten to point at it.

Acceptance criteria status

  • Every clause in each museum SELECT-task gold is justified from authorised sources, with `audit_status` ∈ {clean, edited, unrecoverable}.
  • museum_7 has `audited_sol_sql` aligned with KB 16.
  • museum_9 has the column-meaning justification documented (no SQL rewrite needed — the column meaning resolves the KB-alone underspec).
  • Cloud rerun of museum with `--use-audited-gold-sql` shows `phase1_passed_audited > phase1_passed_original` for ≥1 task — manual smoke post-merge.
  • (Stretch) Audit-or-trust mechanism for the other 17 livesqlbench DBs — deferred.

Follow-up

A child Linear issue will be filed after merge: `claude_sdk_otf: consult column meanings + schema FKs when KB underspecifies the join graph`. museum_9 is the worked example — the agent's `UsageRecords→Showcases→EnvironmentalReadingsCore→LightAndRadiationReadings` 3-hop chain is KB-faithful but column-meaning-blind; the canonical answer requires reading the schema's declared FK.

Pre-existing test failures (out of scope)

Two tests in `tests/test_db_isolation_pre_copy.py` fail on `origin/main` (commit `9d4975f` / DEV-1509, merged via PR #13, before this branch existed). Per the user's instruction these are NOT fixed here.

  • `test_upstream_reset_still_works_after_pre_copy`: header byte 18 diff after upstream reset.
  • `test_materialize_uses_atomic_rename_for_working_db_copy`: 2 `os.replace` calls when test expected 1.

Test plan

  • `env -u SSH_AUTH_SOCK uv run --extra all --extra dev --extra pydantic-ai pytest` — full non-integration suite passes (1633 passed locally; only the 2 pre-existing failures above remain).
  • `env -u SSH_AUTH_SOCK uv run --extra all --extra dev --extra pydantic-ai pytest -m integration tests/integration/test_livesqlbench_audited_gold_execute.py` — 31 integration tests pass (every audited_sol_sql executes against `museum.sqlite`; sample rows match; museum_7 result-set differs from gold as expected).
  • Cloud smoke: `bird-interact-cloud submit --dataset livesqlbench --gold-file ... --instance-ids museum_1,museum_2,museum_7,museum_9 --use-audited-gold-sql` — confirms `phase1_passed_audited > phase1_passed_original` for museum_7 (and possibly others).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for audited SQL in LiveSQLBench with consolidated single-file storage format.
    • Implemented audited SQL validation during task submissions and evaluation workflows.
  • Documentation

    • New contract documentation defining audited SQL schema, semantics, and citation requirements.
    • Added LiveSQLBench-specific audit instructions with worked examples.
  • Tests

    • Comprehensive test coverage for audited SQL validation, execution, and correctness verification.

Review Change Stack

…y (DEV-1510)

Audits the 10 livesqlbench museum SELECT tasks against `museum_kb.jsonl`,
`museum_column_meaning_base.json`, and `museum_schema.txt`. Two locked
findings:

* museum_7 (`edited`): KB 16 says "SESR<4 OR at least three of [4 condition
  flags]" but gold treats each flag as independently sufficient. Rewrites to
  a NULL-safe `CASE WHEN ... THEN 1 ELSE 0 END + ... >= 3` predicate.
* museum_9 (`clean`): KB 8 (LER) doesn't pin the host table for light
  readings, but `column_meaning:ConditionAssessments|LightReadRefObserved`
  + the schema's single-hop declared FK do. Gold's choice IS justified;
  the audit ships AS-IS with the column-meaning citation in
  `reasoning_summary`.

Wires the audited-gold overlay through to livesqlbench (previously
short-circuited via `not b.gold_required`):

* `Benchmark.audited_gold_layout` ∈ {`per_db`, `single_file`}. mini-interact
  stays `per_db` (one sidecar per DB); livesqlbench is `single_file`
  (`audited_gold/livesqlbench_audited.jsonl`, `selected_database` per row).
* `apply_audited_gold_overlay` gains a `benchmark` kwarg and dispatches
  per layout. Defensive cross-benchmark guard on single_file row's
  `selected_database` mismatch.
* `run.run_evaluation` + `cloud/ray_app._load_task_data` drop the
  `not gold_required` gate, pass `benchmark=b`.
* `cloud/cli.py` drops the same gate on `--require-audited-gold`.
  `missing_audited_gold_ids` dispatches per layout.
* `paths.audited_gold_file(benchmark)` resolves the single_file path
  (raises for per_db).

Skill split:

* New `.claude/skills/audit-gold-sql-livesqlbench/` (livesqlbench-shaped
  recipe; cites `external_knowledge:<id>` for KB ids in the task's anchor
  list, drops `labeled_ambiguity:`/`knowledge_ambiguity:` — no source in
  livesqlbench, adds schema FKs as first-class evidence).
* New `.claude/skills/_shared/audit-gold-sql.contract.md` — schema,
  citation tokens, audit-status semantics, classification recipe,
  anti-patterns. Both skills reference it.

Tests: 22 new tests covering the schema contract, status-claim
consistency, museum_7 + museum_9 pinning, citation resolvability,
original-gold equality with the gated sidecar, overlay dispatch, cloud
wiring, submit-time guard, and cloud-image baking. 31 integration tests
for the audit-execute path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear

linear Bot commented May 30, 2026

Copy link
Copy Markdown

DEV-1510

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@ZmeiGorynych, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 51 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cc904cbe-a25a-4ccc-a523-052dd91f902f

📥 Commits

Reviewing files that changed from the base of the PR and between 18a00e6 and 83bcf60.

📒 Files selected for processing (6)
  • src/bird_interact_agents/cloud/_audited_gold_check.py
  • src/bird_interact_agents/harness.py
  • src/bird_interact_agents/paths.py
  • tests/cloud/test_audited_gold_check.py
  • tests/cloud/test_cli.py
  • tests/test_dual_eval.py
📝 Walkthrough

Walkthrough

This PR extends audited-gold SQL handling to support a single consolidated JSONL file layout for livesqlbench benchmarks, complementing the existing per-database sidecar layout. It adds a benchmark-configurable dispatch mechanism throughout the codebase, updates core overlay and validation logic, wires the new benchmark parameter through all call sites, and provides comprehensive test coverage.

Changes

Audited-Gold Single-File Layout for LiveSQLBench

Layer / File(s) Summary
Audit Contract & Specification
.claude/skills/_shared/audit-gold-sql.contract.md, .claude/skills/audit-gold-sql-livesqlbench/SKILL.md, .claude/skills/audit-gold-sql/SKILL.md
Defines the shared audit-gold-sql contract specifying JSON schema, citation tokens, clause classification, and audit semantics. Livesqlbench-specific skill documents the end-to-end procedure including single-file output, schema FK evidence rules, and pinned audit decisions for museum_7 and museum_9.
Benchmark Model Configuration
src/bird_interact_agents/benchmark.py, tests/test_benchmark.py
Adds audited_gold_layout: Literal["per_db", "single_file"] field to Benchmark model (default: "per_db"), sets LIVESQLBENCH to "single_file", and includes model validation tests.
Path Resolution Helper
src/bird_interact_agents/paths.py, tests/test_paths.py
Introduces audited_gold_file(benchmark=...) helper that resolves single-file audited-gold JSONL paths, validates benchmark tokens, and enforces layout type constraints.
Core Overlay: Single-File Layout
src/bird_interact_agents/harness.py, tests/test_dual_eval.py, tests/test_audited_gold_overlay_wiring.py
Extends apply_audited_gold_overlay to dispatch based on Benchmark.audited_gold_layout. Implements single-file JSONL reading, instance-to-row mapping, selected_database validation, overlay status logging, and conditional SQL replacement for edited/unrecoverable tasks. Includes dual-eval tests covering both layout paths.
Validation Guard: Single-File Layout
src/bird_interact_agents/cloud/_audited_gold_check.py, tests/cloud/test_audited_gold_check.py
Updates missing_audited_gold_ids and helpers to dispatch on audited_gold_layout. Adds single-file index loader, missing-ID detection including audit-status and audited_sql presence checks, and cross-benchmark collision detection via selected_database validation.
Wiring: Call Site Updates
src/bird_interact_agents/cloud/cli.py, src/bird_interact_agents/cloud/ray_app.py, src/bird_interact_agents/run.py
Updates all call sites to pass explicit benchmark parameter, enabling layout dispatch and removing prior benchmark-specific conditional logic.
Comprehensive Test Coverage
tests/cloud/test_cli.py, tests/cloud/test_image.py, tests/cloud/test_ray_app.py, tests/integration/test_livesqlbench_audited_gold_execute.py, tests/test_livesqlbench_audited_gold.py
Unit, wiring, integration, and contract tests covering model validation, path resolution, overlay logic, validation guard behavior, cloud CLI integration, and execution validation against museum.sqlite. Includes acceptance tests requiring museum_7 to produce different results than original.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • MotleyAI/bird-agents#8: Introduces the Benchmark Pydantic registry and descriptor logic; this PR extends it with audited_gold_layout field and threads that configuration throughout the audited-gold overlay and validation call paths.

Poem

🐰 A single file now holds the gold,
where livesqlbench audits unfold—
per-database paths fade to gray,
as benchmark dispatch lights the way,
from contract to code to test, behold! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main work: auditing livesqlbench museum gold and implementing the single-file overlay wiring for DEV-1510.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch egor/dev-1510-audit-livesqlbench-museum-gold-against-kb-kb-contradicts

Comment @coderabbitai help to get the list of available commands and usage tips.

…ivesqlbench-museum-gold-against-kb-kb-contradicts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/bird_interact_agents/paths.py (1)

175-177: ⚡ Quick win

Remove the redundant lazy import.

get_benchmark is already imported at the module level (line 26), so the lazy import here is unnecessary. Additionally, there is no circular import between paths.py and benchmark.py (benchmark.py only imports from typing and pydantic), so the comment about avoiding an import cycle is misleading.

♻️ Remove the redundant import
 def audited_gold_file(*, benchmark: str) -> Path:
     """DEV-1510: resolve the audited-gold JSONL for a `single_file` benchmark.
 
     Mini-interact uses ``per_db`` (each DB gets its own
     ``<audited_root>/<db>/<db>_audited.jsonl``) and has no single-file
     path — call ``audited_gold_root()`` directly there.
 
     Livesqlbench uses ``single_file`` because its DB names collide with
     mini-interact's (alien, museum, …); the file is one consolidated
     ``audited_gold/livesqlbench_audited.jsonl`` keyed by ``instance_id``
     with ``selected_database`` as the per-DB discriminator on each row.
 
     Raises ``ValueError`` for ``per_db`` benchmarks or unknown tokens —
     same posture as ``slayer_otf_cache_root`` so a forgotten / typo'd
     benchmark cannot silently land at a wrong path.
     """
     _validate_benchmark(benchmark)
-    # Lazy import to avoid a top-level import cycle with `benchmark.py`
-    # (which imports from `paths` indirectly through other modules).
-    from bird_interact_agents.benchmark import get_benchmark
-
     b = get_benchmark(benchmark)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bird_interact_agents/paths.py` around lines 175 - 177, Remove the
redundant lazy import and misleading comment: delete the comment block about a
top-level import cycle and the line "from bird_interact_agents.benchmark import
get_benchmark" in paths.py, since get_benchmark is already imported at module
scope and there is no circular import; ensure any references to get_benchmark
continue to use the existing module-level import.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/bird_interact_agents/paths.py`:
- Around line 175-177: Remove the redundant lazy import and misleading comment:
delete the comment block about a top-level import cycle and the line "from
bird_interact_agents.benchmark import get_benchmark" in paths.py, since
get_benchmark is already imported at module scope and there is no circular
import; ensure any references to get_benchmark continue to use the existing
module-level import.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6e51cf76-b64a-46a4-a3e7-f15e59c71fe7

📥 Commits

Reviewing files that changed from the base of the PR and between 651490c and 18a00e6.

📒 Files selected for processing (20)
  • .claude/skills/_shared/audit-gold-sql.contract.md
  • .claude/skills/audit-gold-sql-livesqlbench/SKILL.md
  • .claude/skills/audit-gold-sql/SKILL.md
  • src/bird_interact_agents/benchmark.py
  • src/bird_interact_agents/cloud/_audited_gold_check.py
  • src/bird_interact_agents/cloud/cli.py
  • src/bird_interact_agents/cloud/ray_app.py
  • src/bird_interact_agents/harness.py
  • src/bird_interact_agents/paths.py
  • src/bird_interact_agents/run.py
  • tests/cloud/test_audited_gold_check.py
  • tests/cloud/test_cli.py
  • tests/cloud/test_image.py
  • tests/cloud/test_ray_app.py
  • tests/integration/test_livesqlbench_audited_gold_execute.py
  • tests/test_audited_gold_overlay_wiring.py
  • tests/test_benchmark.py
  • tests/test_dual_eval.py
  • tests/test_livesqlbench_audited_gold.py
  • tests/test_paths.py

ZmeiGorynych and others added 2 commits May 30, 2026 15:30
…g selected_database (DEV-1510)

Codex review of the DEV-1510 PR flagged that both the overlay
(`apply_audited_gold_overlay`) and the submit-time guard
(`missing_audited_gold_ids`) only rejected MISMATCHING `selected_database`
values, not MISSING ones. A row with no `selected_database` field would
slip past both checks and the audit could be applied based on
`instance_id` alone — defeating the cross-benchmark collision
protection that motivated the single_file layout in the first place.

Both checks now reject missing AND mismatching `selected_database`:
* `harness.apply_audited_gold_overlay`: split into two guards (missing
  vs mismatching) so the warning log is actionable.
* `cloud/_audited_gold_check.missing_audited_gold_ids`: mirror the
  overlay's logic so a submit-time pass doesn't disagree with the
  overlay's mid-run rejection (which would silently fall back to the
  original gold).

Tests: 4 new — overlay+guard each get a "no selected_database" case and
an "empty selected_database" case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… cleanup (DEV-1510)

Codex's second-pass review flagged that the cross-benchmark guard only
verifies `selected_database`, not the row's `benchmark` field. Because
DB names overlap across benchmarks BY DESIGN (alien, museum, … exist
in both mini-interact and livesqlbench — that's why single_file exists),
a misfiled row with the right (instance_id, selected_database) but
the wrong `benchmark` would still slip through.

Both layers now check the `benchmark` field too:

* `harness.apply_audited_gold_overlay` (single_file branch): after the
  `selected_database` check, verify `row.get("benchmark") == benchmark.name`.
  Missing or mismatching → log + missing-row.
* `cloud/_audited_gold_check._load_single_file_audit_index`: capture
  the row's `benchmark` field into the per-row tuple.
* `cloud/_audited_gold_check.missing_audited_gold_ids` (single_file
  branch): mirror the overlay's benchmark-field check.

Also: paths.py:175-177 had a redundant lazy import of `get_benchmark`
(already imported at module level, line 26) with a misleading comment
about an import cycle that doesn't exist. CodeRabbit nitpick — deleted.

Tests:
* 4 new — overlay+guard each get a "wrong benchmark" and "missing
  benchmark" case.
* `_write_lsb_audited` helper defaults to injecting
  `benchmark: "livesqlbench"` for existing rows so the older test cases
  (which only set `selected_database`) keep passing under the new guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant