Skip to content

comparator: pair columns by agreement, an unordered door, the outputs claim (ACE-131) - #316

Open
sandeep-agami wants to merge 1 commit into
ACE-130-literal-grader-existsfrom
ACE-131-comparator-agreement
Open

comparator: pair columns by agreement, an unordered door, the outputs claim (ACE-131)#316
sandeep-agami wants to merge 1 commit into
ACE-130-literal-grader-existsfrom
ACE-131-comparator-agreement

Conversation

@sandeep-agami

Copy link
Copy Markdown
Collaborator

Spec: ACE-131 (agami-sdlc projects/agami-core-extension/specs/reconcile-evidence/ACE-131-comparator-agreement.md)

Stacked on #315 (ACE-130). Round 9 of the reconcile stack, from the 51-row run.

The findings

  1. Order sensitivity was wrong for reconcile. 2e handed the person's statement as --golden-sql-file, has_top_level_order_by set ordered=True, one reordered row unpaired every column, the early return fired before the values level's forgiveness, column_pairs came back empty and every safety net in reconcile.py is keyed on pairs. Two rows were false mismatches on sort order alone.
  2. All-or-nothing pairing over-reported. One differing row unpaired the column and the page printed "no generated column carries the values of: …" for a column that was there; four rows had real differences the report buried.
  3. "Can the reconcile skill determine if the query is equivalent based on the join and filters?" Partly: the seven claims never covered the projection.

The change

comparator.py

  • pair_columns: stage one is today's exact pairing (names and positions never consulted). Stage two, over what is left: a same-named column (lowercase, qualifier dropped) pairs at any agreement; otherwise the candidate with the highest share of agreeing rows pairs when the share is strictly above one half. Agreement is positional when ordered, a multiset when not, over canonical cells with the level's quantize. match_columns stays a two-tuple wrapper, so every caller keeps its shape.
  • ItemScore gains column_agreement (pair for pair) and paired_row_share (the share of rows every paired column agrees on, computed even when a golden column has no partner). Additive, defaults.
  • compare_result_sets(..., ordered=None): when given it decides instead of the statement; False adds the note "row order was not compared". The golden run never passes it.
  • The pass mark does not move: an item passes at exactly 1.0; a golden column with no partner still scores 0 with its name. What changes is the failing item's number and reason ("9 of the answer key's 10 rows matched").

golden_claims.py: the eighth claim outputs, after tables: one key per output expression through _expression_key, alias peeled; SELECT * and t.* read *; DISTINCT is not read. Reports, never gates. Docstrings, sm claims help and the plugin prose that counted seven count eight.

cli.py: sm compare-results --unordered.

Pins moved on purpose

  • test_column_values_in_a_different_row_order_do_not_match_when_ordered → the column pairs by name and compare_rows finds 0 of 2 rows in order; the score reads the rows reason, not the missing-column one.
  • test_a_bool_column_does_not_match_an_int_column and the end-to-end boolean test → paired by name at agreement 0.0, accuracy still 0.0.
  • test_a_null_does_not_match_the_empty_string_end_to_end → paired at agreement 0.0, accuracy still 0.0.
  • test_each_level_over_a_passing_and_a_failing_pair[exact …] → 0.5 (one of two rows agrees) instead of 0.0.
  • test_matching_forwards_quantize → the name-free case keeps the old assertion; the same-name case checks agreement 0.0 against 1.0.
  • test_the_claim_set_is_exactly_seven_claims → eight, with outputs; test_a_scored_item_carries_the_seven_claims likewise; two * 7 status lists → * 8.

Tests

New: a column agreeing on 9 of 10 rows pairs and scores 0.9; a differently named column agreeing on 3 of 10 stays unmatched with paired_row_share 1.0 over the paired one; a same-named column pairs at any agreement; ordered=False against an ORDER BY statement scores 1.0 with the note, and the statement still decides when the caller says nothing; differing row counts leave pairs, agreement and share empty; --unordered at the CLI; the outputs claim (aliases peeled, a different aggregate differs, a bare column in a single-table statement is its table's, SELECT * differs, never gates). 639 passed across the comparator, claims, CLI, golden and reconcile suites (the golden_run client test is the known local failure).

🤖 Generated with Claude Code

…: read the outputs

One differing cell unpaired a whole column, so the score read "no generated column carries the
values of: total" for a column agreeing on nine rows of ten, and every reader keyed on the pairs saw
none. Columns still pair on whole-vector equality first; what is left pairs by name when both sides
spell one (qualifier and case dropped), or by the highest share of agreeing rows when more than half
agree. The score then counts rows and carries `column_agreement` beside `column_pairs` and
`paired_row_share` over the paired columns. The pass mark does not move.

`compare_result_sets(ordered=False)` and `sm compare-results --unordered` compare the rows as a set
whatever ORDER BY the statement wrote, for reconcile, whose ordering is a claim of its own. The
golden run never passes it.

The claims reader gains an eighth claim, `outputs`: what each statement selects, alias peeled, so
two statements are the same query only when they select the same expressions. It reports and never
gates. Every reader that counted seven counts eight.

Pins moved on purpose: reversed rows under one name pair by name and disagree row for row; a
boolean against an int of the same name, and a null against an empty string, pair at agreement 0;
the exact level's failing pair reads 0.5; the claim count and names.

Spec: ACE-131

Co-Authored-By: Claude Fable 5.1 <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