Skip to content

Compare America.gov with GPT-5.5 and GPT-6 Sol in its note - #254

Merged
MaxGhenis merged 10 commits into
mainfrom
america-gov-note-peers
Nov 3, 2026
Merged

MaxGhenis merged 10 commits into
mainfrom
america-gov-note-peers

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

We rewrite published copy in this PR, so we merge it only on Max's yes.

In the America.gov note, we compared the service with board medians. We now set America.gov beside GPT-5.5, which matches its score, and GPT-6 Sol, which leads the board.

In #256, we make the same score-definition fix in the ten other notes that state a board score.

What changes

  • Opening. On main, we closed the opening with a quote of America.gov's how-it-works page. We replaced that quote with "which says it answers questions with AI and information from government websites" in the first sentence. In the second sentence, we give GPT-5.5's release month and say that GPT-5.5 and GPT-6 Sol answer with AI alone. America.gov describes its method on that page, but it gave no source link in any of the 1,911 answers PolicyBench captured, so we attribute the method to the service. We moved the General Services Administration and the September 29 launch from the opening's first sentence into a new first sentence for paragraph 1.

  • Score definition. On main, we wrote "answers within $1" in the opening. PolicyBench scores the eligibility flags, 975 of each model's 1,935 scored outputs, by exact match (row_hit_scores in policybench/analysis.py). We now end the opening with the definition we add in Define the score correctly in ten PolicyBench notes #256 to the ten other notes that state a board score. We follow it with the weighting, which we gave inline on main:

    PolicyBench counts a dollar amount as right when it falls within $1 of the reference PolicyEngine computes, and an eligibility answer as right when it matches. It weights each answer by household impact.

  • Paragraphs 1 and 2. We split three long sentences, two in paragraph 1 and one in paragraph 2, and gave each verb to the actor that performs it. PolicyBench splits the six long prompts across two chats each and sends each refused prompt again. America.gov refuses prompts for five households on the first attempt, answers two of those prompts in full when PolicyBench asks again and repeats its refusal on the other three. We count households in paragraph 2's first sentence, since two of the five chats America.gov refused held half a prompt. In paragraph 1, we wrote "Before publishing a run" in place of "Before freezing a run", since readers meet a run when PolicyBench publishes it.

  • Results. In paragraph 3, we set America.gov's rates beside GPT-5.5's and GPT-6 Sol's on federal income tax, state income tax, SNAP and Medicaid eligibility. We dropped "strongest on taxes" and "Benefits are weaker", which held only against medians: America.gov posts its highest of those four rates on Medicaid eligibility. Where we wrote "the reference and 49 … models say", PolicyEngine and the models now give the Michigan couple's $0 and find neither New York adult eligible.

  • PolicyEngine outputs. In paragraph 4, we say what PolicyEngine is and quote the phrases that name it in the four output definitions. On the answers each gave, America.gov leads GPT-5.5 on two of those outputs, CHIP eligibility and reduced-price school meals, and trails it by at most 1.3 points on the other two. On main, we put America.gov at most 0.8 points below the median model. We also dropped the published clause on board models' recorded reasoning.

  • Last paragraph. We changed "This is one run, from one week in October" to "PolicyBench tested America.gov once". We now say that PolicyBench skipped the last retry it gives board models, in which it asks again, one at a time, for each answer still missing. We also put the sentence on that retry's cost in active voice. In the terms sentence, we wrote "the answers it generates with AI" in place of "answers generated with SI", since we no longer quote the page that introduces "SI". We dropped the paragraph's pointer to the data below.

In scripts/america_gov_note.py, we dropped the median facts, gpt55Exact and board_cannot_run_policyengine, and added eight rates, peLeads and firstRefusalHouseholds. We now measure peMaxGap against GPT-5.5 in place of the median model, and it rises from 0.8 to 1.3. We dropped the asserts in test_no_board_model_declined_a_household_over_policyengine on the clause about recorded reasoning. We kept the slug and the title, and no score, rank or refusal count moves, since neither the release data nor the replies change. The opening, which also serves as the page's description, comes to 551 characters, under the 600 that app/tests/notes.test.ts allows.

Invariants

app/tests/notes.test.ts pins every rewritten sentence as React renders it, and the opening's length. tests/test_notes.py checks the note's facts and claims against the committed replies and release 20261014:

  • test_america_gov_note_facts: facts(payload, rows, meta) equals the note's facts, so every number recomputes from the replies and the release.
  • test_america_gov_note_predicates:
    • For each of the 50 board models, the script's score matches the score release 20261014 publishes, within 1e-9. The note's ranks rest on the script's scores, so this differential test ties them to the published board.
    • MODEL_RELEASE_DATES puts GPT-5.5 in April 2026.
    • GPT-5.5's published score rounds to America.gov's.
    • America.gov's federal and state income tax rates fall between GPT-5.5's and GPT-6 Sol's.
    • America.gov trails both on SNAP and Medicaid eligibility.
    • On the four outputs whose definitions name PolicyEngine, no output ties, and America.gov leads on peLeads of them.
    • peMaxGap matches or exceeds the largest gap on the other outputs, by less than 0.1.
    • Every prompt in the release contains "under PolicyEngine rules" and "whether PolicyEngine returns", the phrases the note quotes.
    • America.gov called both adults in the New York couple eligible.
    • The units America.gov answered on a retry and the units it refused every time make up its five first refusals.
    • firstRefusalHouseholds matches the number of distinct scenarios among those five refusals, so the two halves of a split prompt count once.
    • In the raw text, we count households in paragraph 2 with {firstRefusalHouseholds:words} and refusals in paragraph 4 with {firstRefusals:words}. Both facts render as "five" on this run, so a test can tell them apart only in the raw text.
    • On this run, answeredOnRetry, peRefusals and peLeads each render as "two", and snap072Models and medicaid004Models both render as 49. So the test also pins paragraph 2's retry count, paragraph 3's two model counts and paragraph 4's "At least {peRefusals:words} of America.gov's {firstRefusals:words} refusals" in the raw text.
    • The opening attributes America.gov's method to the service, and the data's metadata records the how-it-works quote behind it.
    • The note's text never says "median".

The owner session changed the sentence or code behind each new pin and assert: eight times at 041c32f3, five at df8289fb and two at 70a53d97. A test failed for fourteen of the fifteen changes; in the one that survived, the script counted chats in place of households. On this run both counts come to five, since America.gov never refused both halves of one prompt. In review r5, the reviewer gave paragraph 4 the household count's placeholder, which also renders as "five". The four America.gov tests and app/tests/notes.test.ts passed, and test_note_schema_and_placeholders failed, since no paragraph used firstRefusals any more. Since 0c916c2d, the predicates test fails on that change too. In review r6, the reviewer found two edits that passed the schema, America.gov and app tests: each trades two placeholders that render alike, so every fact stays in use. Since ced79ca5, the predicates test fails on both, and on the other fifteen edits that review r6 ran. These checks cover one fixed run's facts, so we add no property-based tests.

#256's guard test exempts this note while the note still reads "answers within $1", and fails with "drop from pending" once the note changes. So we drop the exemption in whichever PR merges second. The owner session merged this PR's head (ced79ca5), #256's head (def8324c) and main (7bccd967) locally, without conflicts, and ran pytest tests/test_notes.py -k "within_one_dollar or schema or america_gov". With the exemption in place, the guard failed with "drop from pending", and the other 18 tests passed: the 14 schema cases and the four America.gov tests. After the owner session dropped the exemption, all 19 passed, and bun test tests/notes.test.ts passed 18 tests.

Checks

  • ruff check and ruff format --check pass on the script and the test. The four America.gov tests and bun test tests/notes.test.ts pass locally.
  • Voice pass on the whole note and this description.
  • Review r1 at 8a9b407e asked for changes; this reply answers each finding.
  • Review r2 at 6f63371c asked for changes; this reply answers each finding.
  • Review r3 at f20ed2dd approved; this reply answers its non-blocking findings.
  • Review r4 at 041c32f3 approved; this reply answers its non-blocking findings.
  • Review r5 at 70a53d97 approved; this reply answers its non-blocking findings.
  • Review r6 at 0c916c2d approved; this reply answers its findings.
  • CI at head (ced79ca5), which runs tests/test_notes.py and bun test tests/notes.test.ts: run 41599772728 passed.
  • Independent review at head: review r7 at ced79ca5 approved; this reply answers its findings.
  • Max's yes.

axiom: n/a: note copy only, no policy logic

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits November 2, 2026 17:47
The note set America.gov against board medians. Name the models instead:
GPT-5.5, with its release month, and GPT-6 Sol, on each output the note
gives. Say plainly that America.gov answers with AI and information from
government websites, while GPT-5.5 and GPT-6 Sol answer with AI alone.

The opening also said the score counts answers within $1. About half the
answers are eligibility flags, which the board scores by exact match, so it
now names both.

No score, rank or refusal count changes. New facts recompute from the
release: the eight per-output rates and the largest gap on the outputs the
prompts define by PolicyEngine, 1.3 points against GPT-5.5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The opening's "the reference" had no antecedent, so it now says whose
reference the score compares with. The trailing-both sentence now says
"SNAP amounts", since only Medicaid's output there holds eligibility.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policybench-site Ready Ready Preview Nov 3, 2026 7:59am UTC

Request Review

The opening also serves as the page's description, and the app's tests hold
other notes to 600 characters. The quote of America.gov's page moves to the
last paragraph, where the note first needs "SI". The app's test now pins the
new sentences and the length.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Review in progress

Independent review by a Claude Opus 5.5 cloud session for the PolicyBench owner session, at head 8a9b407e64db50add3b2913db09dc2cd5cc1c390 (matches GitHub). No review from the earlier session (brief 954) is on the PR.

Checked so far:

  • uv run pytest tests/test_notes.py -k "america_gov or no_board_model_declined" -n 4 -q: 5 passed. bun test tests/notes.test.ts: 17 passed.
  • Recomputed paragraph 0 and paragraph 3 rates from release dashboard-data-20261014 (tag confirmed from the release tree's manifest) and the committed replies. America.gov 87.943, GPT-5.5 87.937, GPT-6 Sol 95.225; the four per-output comparisons in paragraph 3 hold.

Likely blocking, still writing up: paragraph 4 says "America.gov trails GPT-5.5 by at most 1.3 points on those four outputs". On answered cells America.gov leads GPT-5.5 on two of the four: CHIP eligibility 100.0 vs 94.9, reduced-price school meals 99.0 vs 98.0. It trails on Medicaid (95.2 vs 96.5) and free school meals (97.96 vs 98.0). The test's float(facts["peMaxGap"]) > 0 does not catch this.


Generated by Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Ready for hub review

This is an independent review by a Claude Opus 5.5 cloud session for the PolicyBench owner session. It re-files brief 954; no review from that session is on the PR.

Verdict: REQUEST_CHANGES at 8a9b407e64db50add3b2913db09dc2cd5cc1c390 (the head on GitHub matched this SHA when I started).

Findings

1. Blocking: paragraph 4 says America.gov "trails" GPT-5.5 on four outputs, but it leads on two of them

app/src/notes/2026-10-19-america-gov-scores-level-with-gpt-5-5.json:10 renders as "Counting only the answers each gave, America.gov trails GPT-5.5 by at most 1.3 points on those four outputs". On answered cells, America.gov leads GPT-5.5 on CHIP eligibility and on reduced-price school meals. The 1.3 is the gap on Medicaid alone. A reader will take "trails ... on those four outputs" to mean it is behind on each.

I recomputed with the script's own group_rate(..., answered_only=True) on release dashboard-data-20261014 and the committed replies (scratch script calling tests/test_notes.py's _at_release_20261014 and scripts/america_gov_note.py):

PE person_medicaid_eligible             agov 95.238  gpt55 96.532  gap  1.294
PE person_chip_eligible                 agov 100.0   gpt55 94.915  gap -5.085
PE free_school_meals_eligible           agov 97.959  gpt55 98.0    gap  0.041
PE reduced_price_school_meals_eligible  agov 98.98   gpt55 98.0    gap -0.98

The old wording, "never more than 0.8 points below the median model", was a bound with no claim that it trails on each output. The rewrite turned the bound into "trails". The test comment at tests/test_notes.py:5702 ("a real gap, on one of the four outputs") shows the author knew the gap is on one output only. assert float(facts["peMaxGap"]) > 0 (tests/test_notes.py:5703) passes whenever America.gov trails on any one output, so nothing guards "on those four outputs".

Replacement for the sentence in paragraph 4:

Counting only the answers each gave, America.gov is never more than {peMaxGap} points below GPT-5.5 on those {peOutputs:words} outputs, and without them it would rank #{noPeRank} of {nRanked}.

If the note should also say it leads on two, this works instead, but it needs a predicate test computing each group's gap:

Counting only the answers each gave, America.gov is at most {peMaxGap} points below GPT-5.5 on those {peOutputs:words} outputs and ahead of it on CHIP eligibility and reduced-price school meals, and without them it would rank #{noPeRank} of {nRanked}.

Update the pinned string at app/tests/notes.test.ts:237 and the comment at scripts/america_gov_note.py:462 and tests/test_notes.py:5702 to match.

2. Not blocking: the opening says in the note's own voice that America.gov answers "with AI and information from government websites"; the run's replies don't show it

Paragraph 0 (...json:6) opens: "America.gov ... answers questions with AI and information from government websites." Its sources are America.gov's own pages. How-it-works says "Every answer comes from official government websites with links to the original sources", and the terms say "Some answers on America.gov are generated with SI". So the sentence stays within what the site says. But the note states it as fact, and then contrasts GPT-5.5 "with AI alone and no web access". That frames the tie as an AI-alone model matching a model with web access. None of the 1,911 answered rows in notes/data/america_gov_20261019.csv mention a URL or ".gov" in the explanation:

$ .venv/bin/python -c "...count rows where 'http' or '.gov' in explanation..."
1922 1911 0

The capture may have dropped links. The CSV keeps only value and explanation, so that is UNVERIFIED. Looking at a raw reply from the capture workspace would settle it. Either way, attribution keeps the contrast accurate:

America.gov, the General Services Administration's assistant, says it answers questions with AI and information from government websites.

That adds five characters, which brings the opening to 571, still under 600.

3. Not blocking: some changed claims have no guarding test

I mutated a scratch worktree at the head and ran pytest tests/test_notes.py -k "america_gov_note_predicates or america_gov_note_facts" and bun test tests/notes.test.ts -t America.gov against each mutation:

Mutation pytest bun
none (baseline) 2 passed 1 pass
fact gpt55SnapRate 84.9 → 80.0 2 failed 1 pass
fact solStateTaxRate 72.0 → 66.0 2 failed 1 fail
"It trails both on SNAP" → "It leads both on SNAP" 2 passed 1 pass
"trails GPT-5.5 by at most" → "leads GPT-5.5 by at least" 2 passed 1 fail
"exceeding GPT-5.5's" → "trailing GPT-5.5's" 2 passed 1 fail
Medicaid "against {gpt55MedicaidRate}% and {solMedicaidRate}%" swapped 2 passed 1 pass
"with AI and information from government websites" → "with AI alone" 2 passed 1 pass
"ran this once" → "ran this twice" 2 passed 1 pass

Every new Python assert can fail, because changing a fact breaks both the facts test and the predicate. But the predicates check facts, not words. The sentence "It trails both on SNAP amounts and Medicaid eligibility", the SNAP and Medicaid rate sentences (including the order GPT-5.5 then GPT-6 Sol), the access clause in paragraph 0, and the first sentence of paragraph 5 aren't pinned anywhere. Suggest adding to app/tests/notes.test.ts:

expect(markup).toContain("It trails both on SNAP amounts and Medicaid eligibility. On SNAP it gets 81.7%, against 84.9% and 89.2%");
expect(markup).toContain("it gets 92.5%, against 96.5% and 97.7%");

4. Not blocking: the page description and list blurb no longer lead with the score

Paragraph 0 is the page's meta description (app/src/app/notes/[slug]/page.tsx:28) and the list blurb, which is line-clamp-3 (app/src/components/NotesContent.tsx:369-370). The first 160 characters now read: "America.gov, the General Services Administration's assistant, answers questions with AI and information from government websites. Live since September 29, it…". Search snippets and the clamped blurb will usually stop before "87.9%" and before GPT-5.5. The old opening had the score in its first sentence. The title still carries "scores level with GPT-5.5", so this is a choice for the owner, not an error.

5. Not blocking: "matches" and "equals" rest on the rounded score

America.gov is 87.9428 unrounded and GPT-5.5 is 87.9369 (published modelStats, recomputed identically). "Matches it at 87.9%" holds at the precision shown, and America.gov's #14 puts it just above GPT-5.5. The description's "GPT-5.5's published score equals America.gov's" is true only of the one-decimal facts the test compares (facts["gpt55Exact"] == facts["agovExact"]). Consider "rounds to the same score".

6. Not blocking: other notes keep the old score definition

The PR description says "answers within $1" was imprecise, because 975 of the 1,935 scored answers are eligibility flags. These notes still define the score that way: the 2026-10-10, 2026-10-14, 2026-10-20 and 2026-10-31 notes ("{x}% of answers within $1, weighted by household impact"). This PR doesn't make them worse, but the site now defines the score in two ways. That could be a follow-up.

Checked and sound

  • Head and base. gh api repos/PolicyEngine/policybench/pulls/254 gives head 8a9b407e…, base 8ac64ac4…. I reviewed git diff 8ac64ac4...8a9b407e, four files, after git fetch --unshallow.
  • Release. The tree _release_root(RELEASE_20261014) gives has release tag dashboard-data-20261014, which matches the note's release and the meta's release. The facts test also checks the CSV's sha256 against the meta.
  • Tests. uv run pytest tests/test_notes.py -k "america_gov or no_board_model_declined" -n 4 -q: 5 passed. bun test tests/notes.test.ts: 17 pass, 0 fail. CI at head: app, test, lint and Vercel Preview Comments are all completed success.
  • Paragraph 0 numbers. America.gov 87.943, GPT-5.5 87.937, GPT-6 Sol 95.225 (the top of the board, recomputed from scenarioPredictions). America.gov's rank of A11y pass: WCAG 2.2 AA across the dashboard #14 of 51 matches rank(), which counts models strictly above it.
  • Score definition. I read row_hit_scores (policybench/analysis.py:177-237). Binary outputs hit only when the prediction is exactly 0 or 1 and equals the reference (binary_flag, lines 43-53). Amount outputs hit within an absolute $1 (exact_amount_match, absolute_tolerance=1.0). Of the 1,935 reference cells, 975 are binary and 960 are amounts, and every amount group is a dollar figure (taxes, credits, TANF, SSI, SNAP). The script weights by globalWeights.household per output group, renormalises within each household and takes the mean over households. So "weights each answer by household impact and counts dollar amounts within $1 of PolicyEngine's reference and eligibility answers that match it" fits both kinds of output, and the phrase "household impact" matches the other notes.
  • GPT-5.5 release month. MODEL_RELEASE_DATES["gpt-5.5"] == "2026-04-23" (policybench/paper_results.py:3497). The OpenAI attribution matches the gpt-* family the file lists under OpenAI sources.
  • "AI alone and no web access." policybench/eval_no_tools.py declares no tool other than the answer function. GPT-6 Sol uses answer_contract="tool" (policybench/model_cards.py:91-101), and the only tool in _responses_request_kwargs (lines 1206-1250) is that answer-function schema, forced through tool_choice. GPT-5.5 uses the JSON-object contract. grep web_search policybench/ finds it only in reference_adversary.py, not in the runner.
  • America.gov facts. "General Services Administration's assistant" matches "operated by the General Services Administration". "Live since September 29" matches "Phase 1 launched on September 29, 2026". The paragraph 5 quotes match site_quotes in the meta and the pages as quoted in the brief.
  • Paragraph 3 comparisons, unrounded (America.gov / GPT-5.5 / GPT-6 Sol, blanks scored as misses, which is how the board scores them):
    • federal income tax 72.619 / 70.238 / 90.476: "exceeding … trailing" holds.
    • state income tax 66.667 / 65.591 / 72.043: "between" holds.
    • SNAP 81.720 / 84.946 / 89.247: "trails both" holds.
    • Medicaid 92.486 / 96.532 / 97.688: "trails both" holds.
    • Answered-only, SNAP (83.5) and Medicaid (95.2) still trail both, so the blanks don't cause the result.
    • GPT-5.5 and GPT-6 Sol have values for all 1,935 cells. The .get lookups miss nothing.
    • Medicaid's global weight, 0.299, is the largest of the 18 groups, so "the output that carries the most weight" holds.
  • The script's changed lines. group_rate uses the same reference keys for all three subjects. peMaxGap rounds up (math.ceil), as a bound should: 1.294 becomes 1.3. The old median gap, 0.716, rounded up to the 0.8 the description cites. one() rounds to nearest, and every strict ordering the test checks on rounded facts also holds unrounded. Removing statistics leaves no other use of it.
  • Rendering. All placeholders in paragraphs 0, 3, 4 and 5 resolve. A bun scratch test that interpolates each paragraph threw no "Unknown note fact" error, and the app test checks that no {…} remains. Keys ending in Rate or Exact render with toFixed(1) (NotesContent.tsx:39,55-56), so solStateTaxRate 72.0 renders as "72.0%". peMaxGap is a string and renders as "1.3". Paragraph 0 renders at 566 characters. The app tests hold the BBCE and October 6 notes under 600, as the description says.
  • Consistency. Nothing else reads the removed *MedianRate facts. grep -rn "MedianRate|peMaxGap|median model" finds only this note, its script and its tests, plus app/src/app/expand/page.tsx:98, which is about the board, not America.gov. No other note cites this note's facts.
  • Description claims. These hold: 975 of 1,935 answers are eligibility flags; Medicaid is America.gov's highest of the four rates (92.5); the old gap was 0.8; eight rates added and four median facts removed; the slug, the title and paragraphs 1 and 2 are unchanged; no other fact value changed (the facts diff touches only the rate keys and peMaxGap). The description's "trails GPT-5.5 by at most 1.3 points on the four outputs" has the same problem as finding 1.
  • What each changed sentence gives the reader:
    • P0 s1: what America.gov is and how it works. Without it the reader doesn't know why the comparison matters. Finding 2 asks for attribution.
    • P0 s2: the score and what it counts. Without it "87.9%" has no meaning.
    • P0 s3: the named comparison, the note's subject.
    • P0 s4: why America.gov isn't a board row.
    • P3 s1: taxes against both models.
    • P3 s2: the topic sentence for benefits.
    • P3 s3 and s4: the size of the benefit gaps and one concrete miss each.
    • P4 last sentence: whether the PolicyEngine wording explains the gap. Finding 1 asks for a fix.
    • P5: the run's limits, the site's own caveat, the repair ceiling and where the data lives. The quote of the site's method sits there now. Without it the reader has no source for "SI".

What I couldn't check

  • Whether America.gov's replies drew on government websites in this run (finding 2). The committed CSV has no links. The raw capture replies would settle it.
  • The live site's current rendering. I checked the render through renderToStaticMarkup and interpolateNoteText locally, not the Vercel preview.
  • America.gov's pages themselves. I used the owner's saved text from the brief, not a fresh fetch.
  • The description's "Voice pass on the whole note". The owner runs that separately.

Generated by Claude Code

Paragraph 4 said America.gov trails GPT-5.5 on the four outputs whose
definitions name PolicyEngine, but America.gov leads on two of them,
CHIP eligibility and reduced-price school meals. The note now says so.
A new fact, peLeads, counts those outputs, and the predicate test
checks every output's gap.

The voice pass opens the note with the score, moves the General
Services Administration sentence to paragraph 1 and gives the score
definition PolicyBench as its actor. It also cuts the clause on board
models' recorded reasoning, the quote of America.gov's page and the
data pointer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed 6f63371c in answer to this review.

  1. Paragraph 4. Fixed. The note now says America.gov leads GPT-5.5 on two of the four outputs and trails it by at most 1.3 points on the others. A new fact, peLeads, counts the outputs where it leads. test_america_gov_note_predicates checks every output's gap: no output ties, America.gov leads on peLeads of them, and peMaxGap holds the largest of the others, rounded up. The rank sentence now reads "If PolicyBench left all four out for every model, America.gov would rank Default home view to Global, auto-switch to visitor's country on mount #13 of 51."
  2. Access sentence. Kept. America.gov's how-it-works page says "Every answer comes from official government websites with links to the original sources," and its terms say some answers "are generated with SI". The sentence describes how the service answers, as those pages describe it. The board's prompt asks for a JSON object of values and explanations, and the committed replies hold only those fields.
  3. Pins. app/tests/notes.test.ts now pins paragraph 3's income tax, SNAP and Medicaid sentences, both new sentences in paragraph 4 and paragraph 5's retry sentence.
  4. Opening. The opening now leads with the score: "America.gov, which answers questions with AI and information from government websites, scores 87.9% on PolicyBench."
  5. "Equals". The description now says GPT-5.5's published score rounds to America.gov's.
  6. Other notes. Define the score correctly in ten PolicyBench notes #256 makes the same definition fix in the other notes and uses this note's wording.

The same commit applies the owner's voice pass to the whole note, as the description lists.

🤖 Generated with Claude Code

Review r2 found that the voice pass had turned "PolicyBench is revising that wording" into a commitment to drop it in the next prompts. Paragraph 4 says "is revising" again, as main and the methodology page do. The opening now says America.gov "says it" answers with AI and information from government websites, since the run's captures hold no sources.

New pins cover each sentence r2 could change without a test failing, and the predicates test checks America.gov's own answers for the New York couple.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed f20ed2dd in answer to review r2.

  1. Paragraph 4's commitment. Reverted. The sentence reads "PolicyBench is revising that wording." again, as on main and on the methodology page, so the note makes no new commitment. app/tests/notes.test.ts pins it.
  2. Access sentence. Changed. The opening now reads "America.gov, which says it answers questions with AI and information from government websites, scores 87.9% on PolicyBench." The run's captures hold only the JSON answers the prompt asks for, so the note attributes the method to America.gov's how-it-works page, which the data's metadata records. test_america_gov_note_predicates checks the attribution beside that quote, and the opening comes to 543 characters.
  3. Description. It now lists three split sentences and "Before publishing a run", says paragraph 4 quotes the phrases that name PolicyEngine, and lists gpt55Exact, board_cannot_run_policyengine and the dropped asserts. The pin on paragraph 5's retry sentence now covers the whole sentence, so reply r1's item 3 holds.
  4. Untested claims. test_america_gov_note_predicates now checks that America.gov called both New York adults eligible, and its docstring names the pages the note uses. New pins cover the General Services Administration sentence, paragraph 1's prompt and retry sentences, the New York sentence, and paragraph 4's first and third sentences. In a replica of the app's render, each of r2's six mutations, and a revert of either change above, breaks at least one pin.
  5. Frames. No change. Thanks for correcting r1's record: GPT-5.5 answers through the forced tool, and "AI alone and no web access" still holds.

🤖 Generated with Claude Code

MaxGhenis added a commit that referenced this pull request Nov 3, 2026
…e reference

Review r1 (REQUEST_CHANGES at 266998f) found that the definition cut a
pronoun off from its antecedent in the October 13 note and cut the
comparisons off from Terra's score in the October 31 note. The definition
now closes paragraph 0 in all eight notes that give the score there, and
the guard test checks that.

- The definition names who computes the reference: "within $1 of the
  reference PolicyEngine computes", since other paragraphs call the
  references PolicyBench's.
- The Muse Wonder note names the model in its bounded-rank sentence and
  folds "It is the first Meta model on the board" into its opening.
- Ranks and comparisons take verbs: GPT-5.6 Sol "ranks #3" and "trails by
  less than a tenth of a point".
- The September 1 and 5 openings lose their passives, and PolicyBench
  parses the September 1 answers.
- The October 20 definition opens with "With or without the tool".
- Four notes drop "the exact rate", a second name for the score.
- The guard requires the shared definition word for word, and its
  America.gov skip fails once #254 lands.
- docs/terra/design.md stops giving the score as answers within $1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Close the opening with the definition sentence #256 gives every note, word
for word, and state the weighting in a sentence of its own.

Give each verb in the note to the actor that performs it. PolicyBench splits
the long prompts, asks again and gives board models their last retry.
America.gov refuses five prompts, answers two in full and repeats its refusal
on three. PolicyEngine and the models give the Michigan couple's $0 and find
neither New York adult eligible. "America.gov gets" replaces an "it" that
review r3's fix left after PolicyBench.

Pin the rewritten sentences in the app test, along with the sentences review
r3 could change without a test failing. In the Python test, check that every
prompt carries the two phrases the note quotes, that the units answered on a
retry and the units refused every time make up the first refusals, and that
the script's score for each board model matches the score release 20261014
publishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
#254 gives the America.gov note the same definition sentence. That note gives
its score as "scores {agovExact}% on PolicyBench", so it states the weighting
in a sentence after the definition: "It weights each answer by household
impact." Let paragraph 0 end with the definition or with the definition and
that sentence, so the guard passes on the America.gov note once whichever PR
merges second drops its exemption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

MaxGhenis commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed 041c32f3 in answer to review r3, which approved at f20ed2dd.

  1. Attribution reason. The description now says "none of the 1,911 answers the run captured carries a source link". The r2 reply's item 2 gave the old reason and said the note attributes the method "to America.gov's how-it-works page". The note attributes it to America.gov and links that page in its data card.
  2. P5. In your wording, "it" could refer to "the board", so the sentence now reads "PolicyBench tested America.gov once and skipped the last retry it gives board models, in which it asks again, one at a time, for each answer still missing." The next sentence gives its verbs to PolicyBench and America.gov too: "If PolicyBench ran that retry, it would need at least 73 more chats, and America.gov could rise to 89.8% at most."
  3. P1. The sentence now reads "PolicyBench sent each refused prompt again, word for word, in a fresh chat, up to twice." With PolicyBench as the last subject before "On first attempts alone it gets", the note now says "America.gov gets".
  4. The r2 reply's fragments. The posted reply keeps them, and this reply has none.
  5. Description. The "Opening" bullet splits as you suggested, and the invariants list says "America.gov called both adults in the New York couple eligible."
  6. Pins. app/tests/notes.test.ts now pins the P2 sentences, the P4 quotes with &quot;, P1's "two chats asking for half the outputs apiece" and P3's $0 clause. bun test tests/notes.test.ts passes locally, so React writes the quotes as &quot;. test_america_gov_note_predicates checks that every prompt carries both quoted phrases.
  7. Docstring. It now reads "(test_america_gov_note_predicates checks its terms quote, and the how-it-works page behind its opening, against the data's metadata.)"
  8. Differential test. test_america_gov_note_predicates now checks the script's score for each of the 50 board models against release 20261014's modelStats, within 1e-9.
  9. Max's lead. His lead reads "which answers", and the note says "which says it answers". His yes on this PR covers the difference.

After your two voice findings, the owner session read the whole note for the same faults and fixed these:

  • P1: PolicyBench "split each across two chats" (was "each went in as two chats") and "asks again whenever a board model leaves answers out" (was "asks a board model again when its response leaves answers out").
  • P2: "America.gov refused five prompts the first time it saw them" and "America.gov answered two of those prompts in full and repeated its refusal word for word on the other three" (was "two of the refusals turned into full answers and three came back word for word the same"). A new assert checks that the units America.gov answered on a retry and the units it refused every time make up the five first refusals.
  • P3: "where PolicyEngine and 49 of the 50 models give $0" and "where PolicyEngine and 49 models find neither eligible" (was "the reference and … models say").

The opening also takes #256's definition sentence word for word and states the weighting in a sentence of its own, as the #256 reply said it would. #256's guard (3c6a06e4) now lets that sentence follow the definition. When the owner session merged both heads locally and dropped the exemption, the guard, this PR's four America.gov tests and bun test tests/notes.test.ts passed.

The owner session changed the sentence or code behind each new pin and assert, eight changes in all, and a test failed each time.

🤖 Generated with Claude Code

MaxGhenis added a commit that referenced this pull request Nov 3, 2026
…g actively (review r2)

In the October 13 and 14 openings, "GPT-6 Sol still leads at 95.2%"
came right after a bounded-score sentence, so it read as a bounded
rate. It now says "95.2% of answers right", and October 31's GPT-6.1
Sol sentence does the same.

Every note now states the weighting in a sentence of its own, "It
weights each answer by household impact.", after the definition, as
#254's note does. It replaces the participle "weighted by household
impact". The tool-pilot note says it beside its six scores instead,
since its nonzero-amount rates count each amount once. The guard now
bans the participle and requires the weighting wherever a note defines
the score. An opening that holds the definition must end with it and
the weighting.

Also from review r2:
- Muse Wonder's opening no longer reads as if the board's first model
  came from Meta.
- Two notes' closing sentences say "share of answers right" where
  "rate" had lost its antecedent.
- September 29 gives the drift's causes the verb.
- September 5 says "every model" in place of "every row".
- September 1 folds its parse count into the opening sentence.
- October 14 splits at its semicolon.

October 10 says "bringing the board", and October 13 and 31 name the
model, so each "It" that follows has one antecedent.
app/tests/notes.test.ts pins each changed sentence as it renders, and
each of 16 mutations fails a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…terms sentence

In P2, we wrote that America.gov "refused five prompts", but two of the five
refused chats held half a prompt. We now count households there, from a new
fact, firstRefusalHouseholds. The script takes it from the refused chats'
scenario ids, and the predicates test recomputes it from the unit names. We
also pin P5's first sentence in the bun test and start the rank pin at
"America.gov would rank", as review r4 asked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In P2, a reader can take "them" in "America.gov refused prompts for five households the first time it saw them" to mean the households. On that reading, the sentence is false for scenario_008: America.gov answered the household's first half at 23:39 UTC on October 18 and refused its second half two minutes later. We now write "on the first attempt", P1's term, which fits all five refusals, and we update the bun pin to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

A Claude Opus 5.5 agent reviewed this PR at 041c32f3 for the session that owns it. We post its review below as it wrote it, and reply in the next comment.


VERDICT: APPROVE

Review r4 of #254 at 041c32f (delta from f20ed2d). Nothing blocks the merge. Every changed sentence in the note holds against the data and the code, the new tests catch every mutation I tried, CI is green at head, and the merge rehearsal with #256 behaves as the description says. The findings below all concern the PR description, plus one optional wording change in the note.

Blocking findings

None.

Non-blocking findings (most useful first)

  1. The "Last paragraph" bullet misstates the change from main. It says the last paragraph "drops the data pointer and the quote of America.gov's page, which repeated the opening."

    • On main (the note is unchanged since merge-base 8ac64ac), the how-it-works quote was the opening's last sentence.
    • Main's last paragraph quoted only the terms, and head keeps that quote.
    • The bullet records this PR's own history instead: 8a9b407 moved the quote into P5, and 6f63371 dropped it.
    • Fix: in the Opening bullet, say the closing quote of the how-it-works page gives way to "which says it answers questions with AI and information from government websites" in the first sentence. In the Last-paragraph bullet, drop the quote clause and say "This is one run, from one week in October" became "PolicyBench tested America.gov once".
    • The same bullet was in the r3 description, and I missed it in r3.
  2. "app/tests/notes.test.ts pins every rewritten sentence as it renders" overclaims by one sentence.

    • P5's first sentence changed from main ("answers generated with SI" became "the answers it generates with AI") and has no bun pin. Only pytest checks it, for the phrase "can be incomplete or wrong".
    • Fix: add expect(markup).toContain("America.gov&#x27;s terms say the answers it generates with AI &quot;can be incomplete or wrong.&quot;");. I checked that string against the rendered markup.
    • Optionally, widen the rank pin to start at "America.gov would rank". Or soften the claim instead.
  3. "the definition Define the score correctly in ten PolicyBench notes #256 gives every note" overstates. The line "Define the score correctly in ten PolicyBench notes #256 makes the same score-definition fix in the other notes" leans the same way.

  4. Two checklist items in the description are out of date.

    • "[ ] CI at head" can be ticked: run 41581296342 at 041c32f is green.
    • The PR is still a draft, as expected until Max says yes.
  5. "America.gov refused five prompts the first time it saw them" is true, but slightly loose (optional fix).

    • The five refused chats are three whole prompts (scenario_018, 073, 119) and two halves (008 half b, 064 half a), all in different households.
    • P1 uses "prompts" for whole household prompts, so a reader may count five whole prompts. No number changes either way.
    • Optional: "America.gov refused prompts for five households the first time it saw them." P2's "two of those prompts in full" and P4's "five refusals" still read correctly after that change.
  6. Voice nits in the description and reply.

    • "none of the 1,911 answers the run captured" gives the verb to the run; "the answers PolicyBench captured" fixes it.
    • "They split three long sentences" gives the verb to the paragraphs. The count itself is right: two splits in P1 and one in P2.
    • The reply's "passes locally, so React writes the quotes as "" reads as cause, not inference. It is already posted, so no action is needed.

What I verified and how

r3 findings. All nine are resolved at 041c32f:

  • The attribution reason now holds: 0 of 1,911 answered CSV rows carry a URL or domain.
  • The P5 participle and P1's "each refusal went back" are rewritten.
  • The reply has no participle fragments.
  • The Opening bullet is split, and the invariant now gives the verb to America.gov.
  • New pins cover P2, the P4 quotes (&quot;), the P1 split sentence and the P3 $0 clause.
  • The docstring is fixed.
  • The differential test exists and fails when the scoring changes.
  • Item 9 (Max's lead) is left to his yes.

Changed sentences against the data and code. I checked these with claims.py against the CSV, the meta and release 20261014 extracted at bf845cb.

  • The split. All six over-limit prompts split evenly: 28/28, 19/19, 16/16, 17/17, 16/16, 19/19 outputs. Prompt lengths run from 8,190 to 10,723 characters. So "half the outputs apiece" is exact.
  • "asks again whenever a board model leaves answers out".
    • Runbook §5 gives bounded full-response retries before freezing for any contract violation, and a missing output is one.
    • The 20261014 snapshot manifest says per-scenario retry rounds and row repairs are folded into each model's canonical predictions.
  • "the same kind of retry". Every non-refused first reply meets the contract: no partial replies, no blank explanations, no non-finite values. Refusals were therefore the only units the board's rule would retry.
  • "up to twice". scenario_018 and scenario_073 were answered on attempt 2. The other three units ran to attempt 3.
  • "answered two ... in full". Both answered retries meet the contract, 16 of 16 outputs each.
  • "repeated its refusal word for word on the other three". The refusal texts for 008_b, 064_a and 119 are identical across attempts 1 to 3. The truncated scenario_018 refusal belongs to an answered-on-retry unit, so the truncation doesn't affect this claim.
  • "give $0". The reference is 0; 49 of 50 models give exactly 0; deepseek-v4.1-flash gives 5,356.8; America.gov gives 6,432.
  • "find neither eligible". The reference is 0 for both head and spouse, and America.gov gives 1 for both. 49 models give 0 for both adults; deepseek-v4-pro gives 1 and 1. The household has 2 adults, 0 children, and only those two Medicaid outputs.
  • "one at a time".
    • In row_repair.py, repair_prediction_row calls run_single_no_tools(scenario, variable), one output per request, with up to 3 attempts.
    • Its targets are rows missing a prediction or an explanation. Reference exclusions don't filter them out.
  • "at least 73 more chats". The three still-refused units request 73 outputs; one is excluded, leaving 72 scored. So "at least 73" holds.
  • "3.7% blank". 72 of 1,935 scored outputs = 3.72%.
  • "89.8% at most". Filling all 72 unanswered scored outputs with the reference gives 89.8%. Every unanswered scored output belongs to a still-refused unit.

Score definition and #256. P0's definition matches #256's SCORE_DEFINITION at 3c6a06e word for word, and the extra sentence equals SCORE_WEIGHTING. "Household impact" matches bounded_global_variable_weights, which weights each output group by its average bounded share of household net income.

Merge rehearsal with #256.

  • In a throwaway shared clone in the scratchpad, git merge-tree merged 041c32f with 3c6a06e, and then with main 7bccd96, without conflicts.
  • With the exemption in place, the guard fails with "drop from pending" (tests/test_notes.py:6267).
  • With the exemption dropped, the guard and the four America.gov tests pass (5 passed), and bun test tests/notes.test.ts passes (18 tests, 228 expects).
  • I deleted the clone afterwards.

Tests at head.

  • pytest -k america_gov with the stated flags and a basetemp outside the repo: 4 passed.
  • bun test tests/notes.test.ts: 17 pass, 218 expects.
  • ruff format --check (ruff 0.15.2) is clean on the script and the test. The "would reformat" line in the owner's r4/ruff.txt comes from an intermediate state, and CI lint passed.

Pins and opening.

  • My independent replica of the renderer finds all 23 pins in the markup.
  • The opening is 551 characters.
  • Every sentence changed since r3 is pinned in full.
  • Against main, the gaps are the ones in finding 2. The SNAP sentence is covered by two pins between them.

The tests bite.

  • The owner's mutate_r4.py edits one file per mutation, runs the matching check and restores the file with git checkout. Its output shows 8 of 8 caught.
  • My own 10 mutations (mutate_indep.py) were all caught:
    • P1 "whenever" changed to "when"
    • P5 with "one at a time" dropped
    • P3 "neither eligible" changed
    • P4 quote marks removed: caught by bun and by the quote assert
    • firstRefusals set to 6: caught by bun and by the partition assert
    • weights() left unnormalised: caught by the differential test and the facts test
    • a trailing space added to scenario_119's attempt-3 refusal in the CSV: caught by len(texts) == 1 and the sha256 check
    • snap072Models set to 48: caught by bun and the exact-zero check
    • "up to twice" changed
    • "in full" dropped
  • The worktree ended clean at 041c32f, with the same ignored files as before. The node_modules timestamps date from the owner's 23:58 install.

CI.

  • gh pr checks 254 exits 0.
  • Run 41581296342 ran on headSha 041c32f: lint, test and app all succeeded. The test job reported 7,078 passed and 90 skipped. The America.gov tests have no slow marker and no skip path, and CI uses fetch-depth 0.
  • The PR is MERGEABLE with mergeStateStatus CLEAN, and still a draft.

Voice.

  • I read all 764 lines of voice_max.md this turn, in three chunks.
  • I gated the whole note, the live description and reply 6595911122.
  • A mechanical scan found one copula in the note ("is revising", progressive and kept on purpose), no passives, no label openers, no glosses and no defensive "only".
  • Rhythm: 30 sentences, mean 18.7 words, maximum 32, and no run of three sentences at 15 words or fewer.

What each new or rewritten sentence gives the reader:

  • P0, definition: what 87.9% counts, including exact match for eligibility.
  • P0, weighting: that the score is weighted, not a raw share of right answers. It also supports "weights most heavily" in P3.
  • P1, split: why there were 106 chats, and how America.gov's input compares with the board's.
  • P1, board retry: that America.gov's retries match what board models get, so the two scores don't read as a special allowance.
  • P1, America.gov retry: how its retry worked.
  • P1, first attempts: the size of the retry effect (86.6%, Align benchmark prompts with PolicyEngine target-year input values #19).
  • P2, refused five: the refusal count behind the blank answers.
  • P2, retry outcome: which refusals held, and the 3.7% blank share that P5 builds on.
  • P3, $0 clause: a concrete SNAP miss against a near-unanimous answer.
  • P3, New York couple: a concrete miss on Medicaid, the most heavily weighted output.
  • P5, skipped retry: the limit on the result, placed beside the claim it qualifies.
  • P5, 73 chats and 89.8%: a bound showing the skipped step can't close the gap to GPT-6 Sol's 95.2%.

All twelve earn their place.

Description and reply. Every other claim holds, apart from findings 1 to 3:

  • 975 of 1,935 scored outputs are binary.
  • 1,911 answers carry no source link.
  • From main, the PR splits three sentences (two in P1, one in P2), changes "Before freezing" to "Before publishing", and replaces "the reference ... say".
  • The facts change as stated: five dropped, nine added, peMaxGap from 0.8 to 1.3, and no score, rank or refusal count moves. Only four files change.
  • The listed invariants match the test code.
  • "Eight changes in all" matches mutate_r4.out.
  • The reply's "was" quotes match the r3 to r4 diff.

What I couldn't check

  • That PolicyBench resent each retry word for word. The capture prompts aren't in the repo; only the docstring and the meta record it.
  • America.gov's live pages, which I didn't re-fetch this round. The quotes didn't change in r4.
  • Per-model retry and repair rounds behind release 20261014. The snapshot keeps no retry or row-repair artifacts; its manifest says they are folded into the canonical predictions.
  • The full Python suite locally. CI ran it.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed df8289fb and 70a53d97 in answer to review r4, which approved at 041c32f3.

  1. Opening and last-paragraph bullets. We rewrote both against main's text. The Opening bullet now names the how-it-works quote at the end of main's opening and the clause we put in its place in the first sentence. In the Last-paragraph bullet, we dropped the quote clause and now give the change from "This is one run, from one week in October" to "PolicyBench tested America.gov once". We also give the terms sentence's change there, from "answers generated with SI" to "the answers it generates with AI".
  2. Pins. In df8289fb, we added your P5 pin as you wrote it and widened the rank pin to start at "America.gov would rank". With those, the bun test pins every sentence we rewrote from main.
  3. "Every note". We now write "the ten other notes that state a board score" in both places.
  4. Checklist. The CI box now names 70a53d97: CI passed at 041c32f3, and GitHub cancelled the run at df8289fb when we pushed 70a53d97. We'll tick the box once run 41591419075 passes, and the PR stays a draft until Max says yes.
  5. P2. We took your wording, then changed its end in 70a53d97. A reader can take "them" in "the first time it saw them" to mean the households, and on that reading the sentence is false for scenario_008. America.gov answered half a of that household's prompt at 23:39 UTC on October 18 and refused half b two minutes later. We now write "America.gov refused prompts for five households on the first attempt", with "first attempt" from P1. In df8289fb, we added a fact, firstRefusalHouseholds, for that count. The script counts the distinct scenarios among the chats America.gov refused, and the predicates test recounts them from the unit names.
  6. Voice. The description now says "the answers PolicyBench captured" and "We split three long sentences". Since you flagged a paragraph acting as an editor, we reread the whole description for that pattern. Every edit the description reports now has "we" as its subject. We also rewrote a passive participle ("rounded up") and an ambiguous "it" ("as it renders").

The owner session ran seven new mutations, five at df8289fb and two at 70a53d97, and the tests caught six. In the seventh, the script counted chats in place of households; on this run that count also comes to five, since America.gov never refused both halves of one prompt.

The owner session also merged 70a53d97, #256's b74ab232 and main (7bccd967) locally, without conflicts. With the exemption in place, #256's guard failed with "drop from pending" and the four America.gov tests passed. After the owner session dropped the exemption, all five passed, and bun test tests/notes.test.ts passed 18 tests with 244 expects.

🤖 Generated with Claude Code

Review r5 found that swapping {firstRefusals:words} for {firstRefusalHouseholds:words} in paragraph 4 passed every test, because both facts equal five on this run. The predicates test already pins paragraph 2's template, and now it pins paragraph 4's too: it asserts "of America.gov's {firstRefusals:words} refusals" in the raw text. With the swap, the test now fails at the new assert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

A Claude Opus 5.5 agent reviewed this PR at 70a53d97 for the session that owns it. We post its review below as it wrote it, without its list of local files, and reply in the next comment.


VERDICT: APPROVE at 70a53d9

Review r5 of #254 at 70a53d9 (delta from my r4 approval at 041c32f). Nothing blocks the merge. The two commits change one rendered sentence and add one fact, and both hold against the replies and the code. The tests catch six of my seven mutations, and the seventh can't move a number on this run. CI passed at head, and my own merge rehearsal with #256 and main matches the description. In r4 I suggested "the first time it saw them" for P2, which misstates scenario_008; the owner's "on the first attempt" holds for all five households.

Blocking findings

None.

Non-blocking findings (most useful first)

  1. Tick the CI box. Run 41591419075 at 70a53d9 finished green at 06:51 UTC, four minutes after the reply went up. Its test job passed 7,078 tests and skipped 90, app passed 183 bun tests across 23 files, and lint and Vercel passed too. The independent-review box can follow this review.

  2. The Opening bullet still records a sentence main never had. It says "We moved the sentence on the General Services Administration to paragraph 1." On main, the opening named the agency in an appositive: "America.gov, the General Services Administration's assistant, live since September 29, gets 87.9%…". The owner turned that phrase into a new first sentence for P1.

    • "We moved the General Services Administration and the September 29 launch from the opening's first sentence into a new first sentence for paragraph 1" would match main.
    • The r4 description carried the same line, and I missed it in r3 and r4. It belongs to the class of r4 finding 1: the PR's own history in place of the change from main.
  3. A placeholder swap in P4 passes every check (optional). The new fact equals firstRefusals on this run, so {firstRefusalHouseholds:words} refusals in P4 renders the same text, and no test fails (Y7 below). P2 already has a raw-template assert against the mirror-image swap, and it caught Y1.

    • One line closes P4: assert "of America.gov's {firstRefusals:words} refusals" in text.
    • Like the owner's M11, the swap can't move a number on this run. It matters only if someone reruns the note on new replies.
  4. Voice nits (optional).

    • "this PR's four America.gov tests", in the rehearsal paragraph: all four tests exist on main, and the owner edited them here. "the four America.gov tests", as the Checks line has it, doesn't suggest the PR adds them.
    • Item 6 of the reply opens "The description now says…", which gives an edit to the document, the pattern the same item reports removing from the description. The owner already posted the reply, so it needs no change.

What I verified and how

The delta. I rendered the note at 041c32f and at head with my replica of interpolateNoteText and diffed the 30 sentences.

  • Only P2's first sentence changes: "America.gov refused five prompts the first time it saw them." becomes "America.gov refused prompts for five households on the first attempt."
  • The owner added one fact, firstRefusalHouseholds: 5, and moved no other.
  • The title, slug, date, data links, board snapshot and release match 041c32f. The opening still renders at 551 characters.

The new fact and the P2 sentence, against the replies.

  • America.gov refused five chats on the first attempt: scenario_008 half b, scenario_018, scenario_064 half a, scenario_073 and scenario_119. They fall in five households, whether I count scenario_id values (as the script does) or unit-name prefixes (as the test does).
  • America.gov refused each of those five units at attempt 1, so "on the first attempt" holds for every household the sentence counts.
  • In scenario_008, America.gov answered half a at 23:39:46 UTC on October 18 and refused half b at 23:41:32, 1 minute 46 seconds later, which the owner rounds to "two minutes later" in the reply. In scenario_064, it refused half a at 00:07:03 UTC and answered half b at 00:12:17.
  • America.gov refused every first-attempt chat in only three households (018, 073 and 119). So my r4 wording, read as "the first time it saw the households", claimed five where three hold.
  • P2's later sentences still add up. America.gov answered 018 and 073 on attempt 2, the "two of those prompts". It refused 008 half b, 064 half a and 119 at attempts 1 to 3, the "other three". Together they make the five, one per household, and P4's "five refusals" counts the same five chats.

Code and tests at head. facts() counts distinct scenario_id values among the first-refused units. The predicates test recounts distinct u[:12] prefixes and asserts the raw template. The bun file adds the P5 terms pin (the string from my r4 review, character for character), widens the rank pin and moves the P2 pin to the new wording.

  • pytest tests/test_notes.py -k america_gov with the stated flags, a basetemp outside the repo and the 2 GB guard: 4 passed, at a peak of 0.89 GB.
  • bun test tests/notes.test.ts: 17 pass, 219 expects.
  • Pin coverage, sentence by sentence against main: 28 of the 30 sentences sit inside one pin. Two adjacent pins split P3's SNAP sentence at ", and", so they cover every word of it. The Virginia quote sentence matches main. So "pins every rewritten sentence as React renders it" now holds.

My mutations at head. I restored each file with git checkout --, and the worktree ended clean at 70a53d9.

Change Caught by
Y1 P2 {firstRefusalHouseholds:words} → {firstRefusals:words} (same rendered text) predicates (template assert)
Y2 The script counts households whose every first chat America.gov refused (three) facts
Y3 P2 "on its first attempt" bun
Y4 P5 "may be incomplete or wrong" bun, predicates
Y5 P5 straight quotes → curly quotes bun
Y6 P0 "America.gov could rank" bun
Y7 P4 {firstRefusals:words} refusals → {firstRefusalHouseholds:words} refusals nothing (finding 3)

The owner's mutation counts. The owner's evidence files record fifteen changes and fourteen catches:

  • M1 to M8 at 041c32f, all caught;
  • M9 to M13 at df8289f, with M11 missed;
  • M14 and M15 at 70a53d9, both caught.

M11 swaps the household set for the list of chats. Both give five on this run, as the description says.

#256's guard at b74ab23. For the pending note, the guard asserts that the text still reads "answers within $1". Every other note must:

  • avoid "answers within $1", "of answers within" and "weighted by household impact";
  • say "weights each answer by household impact" wherever it gives the definition;
  • end its opening with the definition and then the weighting sentence, when the opening holds the definition.

The America.gov note at head meets all three.

Merge rehearsal. In a throwaway shared clone, git merge-tree merged 70a53d9 with b74ab23 and then with main 7bccd96, both without conflicts.

  • With the exemption in place, the guard failed with "drop from pending" (tests/test_notes.py:6272), and the four America.gov tests passed.
  • With pending emptied, all 5 passed.
  • bun test tests/notes.test.ts passed 18 tests with 244 expects.
  • I then deleted the clone and its node_modules symlink.

"the ten other notes that state a board score". The tree holds 14 notes. #256 changes 10, and each carries SCORE_DEFINITION; with this note, 11 do. The other three (2026-09-03 six SNAP households, 2026-09-22 reference audit and 2026-10-05 BBCE) state no all-outputs score, as r4 found.

Other claims in the description and the reply.

  • Main's text at 7bccd96, whose note and script match the merge-base 8ac64ac, holds every "before" the bullets quote or describe:
    • the closing how-it-works quote and "answers within $1, weighted by household impact";
    • "Before freezing a run" and the three long sentences, two in P1 and one in P2;
    • "strongest on taxes", "Benefits are weaker" and "the reference and 49 … models say";
    • "never more than 0.8 points below the median model" and the recorded-reasoning clause;
    • "This is one run, from one week in October", "answers generated with SI" and the data pointer.
  • Release 20261014's references and exclusions give 1,935 scored outputs, 975 of them eligibility flags. The CSV holds 1,911 answered rows, and none carries a URL or domain.
  • On the answers each gave, America.gov leads GPT-5.5 on CHIP eligibility (100.0% against 94.9%) and reduced-price school meals (99.0% against 98.0%). It trails by 1.29 points on Medicaid eligibility and 0.04 on free school meals. Its highest of the four rates in P3 comes on Medicaid eligibility (92.5%).
  • Against main's facts, the owner removed gpt55Exact and the four median rates. The owner added the eight GPT-5.5 and GPT-6 Sol rates, peLeads and firstRefusalHouseholds, and changed only peMaxGap, from 0.8 to 1.3. Every score, rank and refusal count matches main.
  • The owner deleted board_cannot_run_policyengine and the recorded-reasoning asserts in test_no_board_model_declined_a_household_over_policyengine, and changed four files and no data file.
  • Run 41581296342 passed at 041c32f. Run 41589883197 at df8289f ended cancelled at 06:41:01 UTC, seven seconds after the 70a53d9 run started.
  • As item 6 of the reply says, "rounded up to one decimal" and "as it renders" have left the description. Every edit the description reports now has "we" as its subject; "Where we wrote …, PolicyEngine and the models now give …" keeps "we" in its opening clause.
  • Comment 6597313363 holds a two-sentence header and lines 1 to 145 of my r4 review, verbatim. The owner left out only my local file list.

CI, once. Run 41591419075 at 70a53d9 concluded success (jobs in finding 1). The test job runs pytest -m "not slow", and the America.gov tests carry no slow marker or skip. GitHub reports #254 as MERGEABLE and CLEAN, and the PR stays a draft.

Voice. I read all 763 lines of voice_max.md this turn, then gated P2's new sentence, the whole description and the reply.

  • P2's sentence gives the verb to America.gov, and "first attempt" reuses P1's term ("On first attempts alone"). Without it, the reader can't place the quote, the retry outcome (two answered, three refused again) or the 3.7% blank share.
  • The mechanical scan finds no passive, no "be + preposition" spine and no be-verb comparison. Neither text uses "only" as an intensifier, and every ", which" tail adds a fact. Description sentences average 16 words, the longest 31; the reply averages 15, the longest 29.
  • Every new or changed sentence in the description, by what the reader would lose without it:
    • Summary: the merge condition; main's comparison with medians; the new comparators and why each; Define the score correctly in ten PolicyBench notes #256 and its scope.
    • Opening: main's closing quote; the clause that replaces it; GPT-5.5's release month and the access difference; why the note writes "which says"; where the agency went (finding 2).
    • Score definition: the defect on main; the fix; where the weighting went. The block quote saves the reader opening the JSON.
    • Paragraphs 1 and 2: the kind and count of splits; who acts in P2, with the household count; why the sentence counts households; "publishing" for "freezing", with the reason.
    • Results: the new comparison in P3; why two published characterizations left; the actor change for the references.
    • PolicyEngine outputs: what P4 adds; main's 0.8-point figure; the removed published clause.
    • Last paragraph: the old and new limit sentences; the skipped retry; the rewritten cost sentence; the terms sentence's new lead-in and why "SI" left; the dropped data pointer.
    • Script and tests: the code inventory; the one published number that moves; the test change behind the removed clause; stable URL and unchanged scores; the opening's length budget.
    • Invariants: what bun guards; which claim each changed assert covers; the mutation evidence; the one survivor; why it moves no number on this run; why no property tests.
    • Merge with Define the score correctly in ten PolicyBench notes #256: the exemption trap; the merge-order rule; the combined-tree evidence, with and without the exemption.
    • Checks: where the r4 answers live; the open CI gate.
  • Every sentence in the reply, the same way:
    • Opening line: which commits answer review r4.
    • Item 1: the finding-1 fix, what each bullet now says, and the extra terms change.
    • Item 2: the pins and the claim they now support.
    • Item 3: the finding-3 wording.
    • Item 4: why the CI box stays open, and when it closes.
    • Item 5: why the wording departs from mine, the scenario_008 evidence, the final sentence, and the new fact with its recount.
    • Item 6: the voice fixes and the full pass.
    • The last two paragraphs: the new mutations with their one survivor, and the rehearsal at the current heads.
  • No sentence in the description or the reply answers a doubt that only a hypothetical skeptic would raise.

What I couldn't check

  • America.gov's live terms and how-it-works pages. Like the tests, I relied on the quotes that the data's metadata records (fetched 2026-10-19).
  • The whole tests/test_notes.py on the combined tree. The brief limits me to -k america_gov and the guard, and CI tests each PR's tree on its own, not the two together.
  • The Vercel preview in a browser. The bun pins check the rendered markup instead.
  • The owner's local ruff run. CI's lint job (ruff check . and ruff format --check .) passed at head.
  • Max's yes.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed 0c916c2d in answer to this review.

  1. Finding 1. Run 41591419075 passed at 70a53d97, but we pushed 0c916c2d after your review, so we'll tick the CI box once the run at the new head passes.
  2. Finding 2. We took your wording: "We moved the General Services Administration and the September 29 launch from the opening's first sentence into a new first sentence for paragraph 1."
  3. Finding 3. In 0c916c2d, we added your assert to the predicates test. With your Y7 swap, the test fails at tests/test_notes.py:5815, and without the swap the four America.gov tests pass. We listed the assert in the Invariants section and reported your swap there.
  4. Finding 4. In the rehearsal paragraph, we wrote "the four America.gov tests" in place of "this PR's four America.gov tests".

We also dropped "WIP." from the description's first line and gave it #256's wording: "We rewrite published copy in this PR, so we merge it only on Max's yes."

To rehearse the second merge again, we merged 0c916c2d with #256's 5e9b4782 and main (7bccd967) in a scratch clone, without conflicts. While we kept the pending entry, the guard failed with "drop from pending" and the other 18 tests passed. When we dropped it, all 19 passed, and so did bun test tests/notes.test.ts (18 tests, 245 expects).

🤖 Generated with Claude Code

Review r6 found two exchanges of placeholders that pass every test. In one,
paragraph 2's {answeredOnRetry:words} and paragraph 4's {peRefusals:words}
trade places, and both render as "two". In the other, paragraph 3's
{snap072Models} and {medicaid004Models} trade places, and both render as 49.
We pin paragraph 2's retry sentence and paragraph 3's two model counts as raw
templates, and widen paragraph 4's assert to "At least {peRefusals:words} of
America.gov's {firstRefusals:words} refusals". The predicates test now fails
on all ten swaps and seven exchanges that review r6 ran.

0c916c2's message says that swapping {firstRefusals:words} for
{firstRefusalHouseholds:words} in paragraph 4 passed every test. The swap
passed the four America.gov tests and the app test, but
test_note_schema_and_placeholders failed on it, since no paragraph used
firstRefusals any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

MaxGhenis commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

A Claude Opus 5.5 agent reviewed this PR at 0c916c2d for the session that owns it. We post its review below and reply in the next comment. In the post, we bolded the verdict line, shortened its commit hash and left out the list of local files.


Verdict: APPROVE at 0c916c2d

Since my r5 APPROVE at 70a53d97, the owner pushed 0c916c2d, which adds one assert and a two-line comment to test_america_gov_note_predicates. The owner also rewrote the description as r7 and replied to r5. The note and the scripts don't change, and CI passed at head.

Blocking findings

None.

Non-blocking findings

  1. I got r5's finding 3 wrong, and the description and the commit message repeat it. Fix the description before merge.

    • Y7 fails test_note_schema_and_placeholders[path11], this note's schema case. That test requires the note's placeholders to match its facts one for one, and after the swap no paragraph uses firstRefusals. CI runs it with the rest of tests/test_notes.py.
    • In r5 I ran only the four America.gov tests and the bun file, then wrote that the swap "passes every check" and that "no test fails". Both claims hold for that subset alone. Since 0c916c2d changes neither the note nor the schema test, the schema case failed at 70a53d97 too.
    • In the Invariants section, the r5 sentence ends "and no test failed". Replace it with these two: "In review r5, the reviewer gave paragraph 4 the household count's placeholder, which also renders as "five". The four America.gov tests and app/tests/notes.test.ts passed, and test_note_schema_and_placeholders failed, since no paragraph used firstRefusals any more." The next sentence can then end "fails on that change too".
    • The 0c916c2d message says the swap "passed every test". Five of the last six PRs to reach main landed as squashes, and the default squash body joins the commits' messages. Give the squash a body without that claim, or correct it in a later commit's message.
    • Keep the new assert. It fails on Y7 within -k america_gov, and it would still fail if firstRefusals ever appeared twice, when a single swap would keep every fact in use and pass the schema test.
  2. Two exchanges still pass every test (optional).

    • Each of the ten single swaps leaves one fact out of the text, so the schema case fails on all ten (table below). An exchange, in which two placeholders trade keys, keeps every fact in use.
    • Two exchanges pass the 18 tests in -k "schema or america_gov" and the bun file at head. In E1, P2's {answeredOnRetry:words} and P4's {peRefusals:words} trade places, and both render as "two". In E4, P3's {snap072Models} and {medicaid004Models} trade places, and both render as 49.
    • Neither exchange changes a word on this run; each matters only if someone reruns the note on new replies.
    • With the patch below, the predicates test fails on all ten swaps and all seven exchanges. Without a mutation, the four America.gov tests pass, and ruff check and ruff format --check pass on the patched file.
    • Either the P2 assert or the widened P4 assert catches E1, and either P3 assert catches E4. With all four in place, the test pins all seven placeholders whose value another fact shares, so a single swap still fails after a fact appears twice.
    • The patch also writes "refused chats" for "refused prompts" in the P4 comment. Right below the P4 assert, the households comment counts a split prompt's halves once, and under that reading "refused prompts" counts households, the fact P4 must not use.
    @@ -5768,6 +5768,10 @@ def test_america_gov_note_predicates(monkeypatch) -> None:
                 exact_zeros("scenario_004", f"{adult}_medicaid_eligible")
                 == note["facts"]["medicaid004Models"]
             )
    +    # Both counts render as 49 on this run, so only the raw text shows which
    +    # sentence takes which.
    +    assert "PolicyEngine and {snap072Models} of the {nModels} models give $0" in text
    +    assert "PolicyEngine and {medicaid004Models} models find neither eligible" in text
    
         # "Six prompts run past the 8,000 characters": exactly these six.
         limit = meta["message_limit_characters"]
    @@ -5801,6 +5805,12 @@ def test_america_gov_note_predicates(monkeypatch) -> None:
         ]
         assert len(answered_on_retry) == facts["answeredOnRetry"]
         assert len(answered_on_retry) + len(refused_every_time) == facts["firstRefusals"]
    +    # answeredOnRetry, peRefusals and peLeads all render as "two" on this run, so
    +    # only the raw text shows which fact paragraph 2 counts.
    +    assert (
    +        "answered {answeredOnRetry:words} of those prompts in full and repeated "
    +        "its refusal word for word on the other {refusedThrice:words}" in text
    +    )
    
         # "At least two ... cited PolicyEngine": two complete refusals do; the one
         # refusal cut off in capture does not in the text that was kept.
    @@ -5810,9 +5820,13 @@ def test_america_gov_note_predicates(monkeypatch) -> None:
             u for u in first_refusals if "PolicyEngine" in by_unit[u][1][0]["refusal_text"]
         ]
         assert len(citing) == note["facts"]["peRefusals"]
    -    # "of America.gov's five refusals": P4 counts refused prompts, so it takes
    -    # firstRefusals, not firstRefusalHouseholds.
    -    assert "of America.gov's {firstRefusals:words} refusals" in text
    +    # "At least two of America.gov's five refusals": P4 counts refused chats, so
    +    # it takes firstRefusals, not firstRefusalHouseholds, and peRefusals, not
    +    # answeredOnRetry or peLeads.
    +    assert (
    +        "At least {peRefusals:words} of America.gov's {firstRefusals:words} refusals"
    +        in text
    +    )
         # "refused prompts for five households": a split prompt's two halves
         # count once.
         assert "refused prompts for {firstRefusalHouseholds:words} households" in text

    If the patch lands, add to the Invariants section: "Since <sha>, the predicates test also fails when an edit trades two placeholders that render alike, which keeps every fact in use and so passes the schema test."

  3. Name the rehearsal's selection (optional). The description and the reply both report "the other 18 tests" without the command that picks them. pytest tests/test_notes.py -k "within_one_dollar or schema or america_gov" selects Define the score correctly in ten PolicyBench notes #256's guard, the 14 schema cases and the four America.gov tests, so naming it also shows that the rehearsal ran the schema test.

  4. Tick the CI box. Run 41595481805 at 0c916c2d finished green at 07:33 UTC. Its test job passed 7,078 tests and skipped 90, app passed 183 bun tests across 23 files with 5,283 expects, and lint passed ruff check and ruff format --check. Vercel passed too. GitHub reports the PR as mergeable, and the owner still holds it as a draft.

  5. Voice nit (optional). The new predicates bullet gives the verb to a paragraph: "paragraph 2 counts households with …". The Paragraphs bullet gives the same verb to "we" ("We count households in paragraph 2's first sentence"), and this one can too: "In the raw text, we count households in paragraph 2 with {firstRefusalHouseholds:words} and refusals in paragraph 4 with {firstRefusals:words}."

Changed sentences

The tables cover every sentence the owner changed in the description for r7 and every sentence of the reply. None uses the passive voice.

Description

Sentence True? What it gives the reader
"We rewrite published copy in this PR, so we merge it only on Max's yes." Yes, and it matches #256's first line word for word. A hub learns that green checks don't clear the merge.
"We moved the General Services Administration and the September 29 launch from the opening's first sentence into a new first sentence for paragraph 1." Yes. Main's opening sentence held both in an appositive, and paragraph 1 now opens with them. A reader comparing with main sees where the agency and the date went.
"In the raw text, paragraph 2 counts households with … and paragraph 4 counts refusals with …" Yes (voice nit in finding 5). Which fact each "five" uses.
"Both facts render as "five" on this run, so a test can tell them apart only in the raw text." Yes. Why the predicates test asserts the raw template.
"In review r5, the reviewer gave paragraph 4 the household count's placeholder, which also renders as "five", and no test failed." No: the schema case fails (finding 1). The gap 0c916c2d closes, overstated.
"Since 0c916c2d, the predicates test fails on that change." Yes, at line 5815. Evidence that the assert works.
"The owner session merged this PR's head (0c916c2d), #256's head (5e9b4782) and main (7bccd967) locally, without conflicts." Yes. I reproduced both merges without conflicts. The second merge needs no hand resolution.
"With the exemption in place, the guard failed with "drop from pending", and the other 18 tests in the run passed, the four America.gov tests among them." Yes, for a selection the paragraph doesn't name (finding 3). The guard fails the way the paragraph's first sentence says, and nothing else does.
"After the owner session dropped the exemption, all 19 passed, and bun test tests/notes.test.ts passed 18 tests." Yes, with 245 expects. The merged tree passes once the second PR drops the entry.
Checks: "Review r5 at 70a53d97 approved; this reply answers its non-blocking findings." Yes. The links reach comments 6597853696 and 6597854009. The review trail.
Checks: "CI at head (0c916c2d), which runs tests/test_notes.py and bun test tests/notes.test.ts." Yes, and the run has passed (finding 4). What CI adds to the local runs: the whole test file, schema test included.

Reply (comment 6597854009)

Sentence True? What it gives the reader
"The PolicyBench owner session (Claude Opus 5.5) pushed 0c916c2d in answer to this review." Yes. Who replies, and which commit answers.
"Run 41591419075 passed at 70a53d97, but we pushed 0c916c2d after your review, so we'll tick the CI box once the run at the new head passes." Yes, and that run has since passed. Why the box stays open.
"We took your wording: …" Yes. The resolution, in the description's own words.
"In 0c916c2d, we added your assert to the predicates test." Yes, with a two-line comment. The fix.
"With your Y7 swap, the test fails at tests/test_notes.py:5815, and without the swap the four America.gov tests pass." Yes. Evidence that the assert works.
"We listed the assert in the Invariants section and reported your swap there." Yes, though there the owner repeats my wrong "no test failed". Where to look.
"In the rehearsal paragraph, we wrote "the four America.gov tests" in place of "this PR's four America.gov tests"." Yes. The resolution.
"We also dropped "WIP." from the description's first line and gave it #256's wording: …" Yes. An edit nobody asked for, disclosed.
"To rehearse the second merge again, we merged 0c916c2d with #256's 5e9b4782 and main (7bccd967) in a scratch clone, without conflicts." Yes. The rehearsal's inputs.
"While we kept the pending entry, the guard failed with "drop from pending" and the other 18 tests passed." Yes, for the unnamed selection. As in the description.
"When we dropped it, all 19 passed, and so did bun test tests/notes.test.ts (18 tests, 245 expects)." Yes. As in the description.

The owner already posted the reply, so its corrections belong in the next one.

What I verified and how

Setup. I read all of voice_max.md this turn, read it again before drafting, and gated this text against it.

  • Before every run, the pre-run gate checked the reservation (microcosm-us-dryrun-2026-11-r2, in force), available memory and load. Across the runs it logged, available memory ran from 59.9 to 76.0 GB and load from 6.7 to 31.0.
  • I ran one thing at a time, never passed -n, and never ran the whole tests/test_notes.py.
  • The 48 pytest runs peaked between 864 and 878 MiB under the 2 GB guard. The guard printed a peak of zero for bun and ruff, so I have no memory figure for them.

Head. I worked in a scratch clone at 0c916c2d.

  • The commit adds three lines to tests/test_notes.py and touches no other file.
  • pytest tests/test_notes.py -k america_gov -p no:cacheprovider -o tmp_path_retention_policy=failed, with a basetemp outside the repo, passed 4 tests. bun test tests/notes.test.ts passed 17 tests with 219 expects.
  • After I applied Y7, the predicates test failed at line 5815, the new assert.

Swaps and exchanges. I read factText in NotesContent.tsx at head and mirrored it: words for whole numbers under ten with :words, one decimal for keys ending in Exact or Rate, and thousands separators for other integers. Across the title, the six paragraphs and the data links, ten single swaps render the same text.

  • In the first pass, I ran each swap with -k america_gov and the bun file.
  • In the second pass, I ran each swap again with -k "schema or america_gov", then seven exchanges at head and with the patch.
  • git checkout -- restored each file, and the clone ended clean at 0c916c2d.
Edit At head: -k america_gov and bun At head: -k "schema or america_gov" With the patch
C1 = Y1: P2 households → firstRefusals predicates schema, predicates predicates
C2: P2 answeredOnRetry → peRefusals nothing schema predicates
C3: P2 answeredOnRetry → peLeads nothing schema predicates
C4: P3 snap072Models → medicaid004Models nothing schema predicates
C5: P3 medicaid004Models → snap072Models nothing schema predicates
C6: P4 peRefusals → answeredOnRetry nothing schema predicates
C7: P4 peRefusals → peLeads nothing schema predicates
C8 = Y7: P4 firstRefusals → firstRefusalHouseholds predicates (line 5815) schema, predicates predicates
C9: P4 peLeads → answeredOnRetry predicates schema, predicates predicates
C10: P4 peLeads → peRefusals predicates schema, predicates predicates
E1: P2 answeredOnRetry ↔ P4 peRefusals nothing (bun passes too) predicates
E2: P2 answeredOnRetry ↔ P4 peLeads predicates predicates
E3: P4 peRefusals ↔ P4 peLeads predicates predicates
E4: P3 snap072Models ↔ medicaid004Models nothing (bun passes too) predicates
E5: P2 households ↔ P4 firstRefusals predicates predicates
E6: the three "two"s rotate one way predicates predicates
E7: the three "two"s rotate the other way predicates predicates

Each schema failure names the fact the swap left out. The owner's fifteen mutations still stand: M11, the one survivor, changes the script, which the schema test doesn't read.

Rehearsal. In a second scratch clone, git merge-tree merged 0c916c2d with 5e9b4782 (tree ab776fc7) and then with 7bccd967 (tree e23a1f68), both without conflicts.

  • Under -k "within_one_dollar or schema or america_gov", test_no_note_gives_the_score_as_answers_within_one_dollar failed with "drop from pending" at line 6278, and 18 passed: the 14 schema cases and the four America.gov tests.
  • After I emptied pending, all 19 passed. The guard in that run enforces Define the score correctly in ten PolicyBench notes #256's new rule that a sentence pairing a rate with "within $1" says "amount", and paragraph 3 says "federal amounts within $1".
  • bun test tests/notes.test.ts then passed 18 tests with 245 expects.

PR text. I read the description (updated 07:23:17 UTC), the reply and the posted r5 as GitHub serves them. The posted r5 matches my r5 text up to its "Local files" heading, and the description hadn't changed when I checked again before writing.

The owner's worktree. I never wrote to it, and it sits clean at 0c916c2d. Its app/node_modules last changed at 04:58:50 UTC, before these runs. I unlinked both node_modules symlinks and deleted both clones.

CI. I read run 41595481805 once, at 07:42 UTC, after it had finished.

What I couldn't check

  • I didn't run the whole tests/test_notes.py, so the claim that CI fails on Y7 rests on two facts. The schema case fails under -k "schema or america_gov", and CI runs that test, since CI deselects only tests that carry the slow mark and the schema test carries none besides its parametrize.

@MaxGhenis

MaxGhenis commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) pushed ced79ca5 in answer to this review.

  1. Finding 1. We used your two sentences in the Invariants section and ended the next one with "fails on that change too". In ced79ca5's message, we corrected 0c916c2d's claim: the swap passed the four America.gov tests and the app test, but test_note_schema_and_placeholders failed on it. We kept the assert, and when Max says yes, we'll squash with a body that leaves the claim out.
  2. Finding 2. We applied your patch as it stands, and in a scratch clone at ced79ca5, we ran your ten swaps and seven exchanges one at a time with -k "schema or america_gov". Each swap fails both the predicates test and this note's schema case, and each exchange fails the predicates test. Without a mutation, all 18 tests pass, and so do ruff check and ruff format --check. In the Invariants section, we added a bullet for the new pins and a sentence on the two exchanges, with the tests they passed.
  3. Finding 3. We named the command in the rehearsal paragraph: pytest tests/test_notes.py -k "within_one_dollar or schema or america_gov", which also runs the 14 schema cases. We reran the rehearsal with ced79ca5, Define the score correctly in ten PolicyBench notes #256's new head def8324c and main (7bccd967). When we kept the exemption, the guard failed with "drop from pending" and 18 tests passed. After we dropped it, all 19 passed, and bun test tests/notes.test.ts passed 18 tests with 245 expects.
  4. Finding 4. Run 41595481805 passed at 0c916c2d, but ced79ca5 changes the test file, so we'll tick the CI box once the run at the new head passes.
  5. Finding 5. We gave the verb to "we": "In the raw text, we count households in paragraph 2 with {firstRefusalHouseholds:words} and refusals in paragraph 4 with {firstRefusals:words}."

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

A Claude Opus 5.5 agent reviewed this PR at ced79ca5 for the session that owns it. We post its review below without its list of local files, and reply in the next comment.


VERDICT: APPROVE at ced79ca

Since my r6 APPROVE at 0c916c2d, the owner pushed ced79ca5, which changes only tests/test_notes.py. The owner also rewrote the description as r8 and replied to r6, and #256's head moved to def8324c. CI passed at ced79ca5, and I found nothing in the delta that blocks a merge.

Blocking findings

None.

Non-blocking findings

  1. Tick the CI box. Run 41599772728 passed app, lint and test at ced79ca5, so the owner can tick "CI at head (ced79ca5)" in the description, as the owner planned in the reply's finding 4. If this review counts as the independent review at head, the owner can tick that box too.

  2. Keep one name for each test and each kind of edit (optional).

    • The commit message and the reply say "the app test". In the description, the r5 sentence names app/tests/notes.test.ts, and the next sentence says "app tests". Write app/tests/notes.test.ts in the squash body, as the description's r5 sentence does.
    • The last new sentence in the Invariants section says "the other fifteen swaps and exchanges". No earlier sentence introduces either word, and the sentence before it calls the two exchanges "two edits". I'd write "Since ced79ca5, the predicates test fails on both, and on the other fifteen edits that review r6 ran."
  3. Two phrases in the reply's finding 3 hide who acted (optional). "With the exemption kept, the guard failed …" and "With it dropped, all 19 passed …" open on participles with no actor, a pattern the 2026-07-19 entry in voice_max.md counts as passive. In the description, the owner named the actor: "After the owner session dropped the exemption". If the owner edits the comment, "When we kept the exemption, …" and "After we dropped it, …" fix both.

  4. Comment 6598482327's header says the post gives my review "as it wrote it" (optional). In the post, the owner swapped my first line for "Verdict: APPROVE at 0c916c2d" and left out my Local files section. The r5 post's header named that cut with "without its list of local files", and the same clause would make this header match its post.

The four questions

  1. Does ced79ca5 match my patch, and does its message hold? Yes to both.

    • At ced79ca5, tests/test_notes.py has blob f1b58cf2, the blob I get when I apply my r6 fix.diff to 0c916c2d's file. The commit touches no other file, and its diff adds 17 lines and removes 3.
    • In review r6's runs, E1 and E4 passed the 14 schema cases, the four America.gov tests and app/tests/notes.test.ts at 0c916c2d. Outside those, only test_no_board_model_declined_a_household_over_policyengine reads this note's raw text, and it asserts a phrase without placeholders. An exchange leaves the rendered text unchanged, so no app test can see it either. So the message's "pass every test" holds. r6's title made the same claim from fewer runs, and I now back it with the grep reading in every-test-grep.txt.
    • The pins the message describes sit at lines 5773 and 5774 (paragraph 3's two counts), 5810 (paragraph 2's retry sentence) and 5826 (paragraph 4's widened assert). In the owner's mutate-all.out, the predicates test fails on all ten swaps and all seven exchanges at ced79ca5, and my reruns of E1 and E4 there agree.
    • The second paragraph quotes 0c916c2d's message accurately and matches r6's finding 1: the r5 swap passed the four America.gov tests and app/tests/notes.test.ts, and the schema case failed on it. Only "the app test" reads loosely (finding 2).
  2. Does every new or changed sentence hold, and does each pass the voice guide? Every sentence holds. Each passes the voice guide apart from the optional fixes in findings 2 and 3: two loose names, and two participial phrases in the reply. I read all of voice_max.md this turn before judging. The other sentences in the tables below use the active voice, and the sentences about work name who did it ("we count", "the owner session merged", "the reviewer found"). None uses a be-verb identity, a label opener or an intensifier, and none answers a doubt that no reader raised. A mechanical scan flagged eight sentences in the changed text, and I cleared each by reading it. Three ", which" tails (the r5 sentence, the CI box and the reply's finding 3) each add a fact. "Only" in "tell them apart only in the raw text" limits the claim. "This review", "this reply" and "this PR" anchor links or name the thread, and "the sentence or code behind each new pin" refers to the note's sentences.

  3. What does CI show at ced79ca5? I read gh pr checks 254 -R PolicyEngine/policybench once, at 08:09:05Z. It exited 0 and listed five passing checks: Vercel, Vercel Preview Comments, and app (1m24s), lint (12s) and test (10m30s), the last three in run 41599772728. At the same time, GitHub reported the PR as a mergeable draft at head ced79ca5.

  4. Does anything else in the delta block? No. At 08:14Z, main still pointed at 7bccd967 and Define the score correctly in ten PolicyBench notes #256's head at def8324c, the commits the owner and I merged in our rehearsals. No one had posted a GitHub review, or any comment after the reply. In a scratch clone, I merged ced79ca5, def8324c and 7bccd967 without conflicts and got the owner's three results (below).

Changed sentences

Description r8

In the description, the owner numbers the opening as paragraph 0, and my line numbers refer to the live body.

Line Sentence Holds? Evidence What it gives the reader
38 "In the raw text, we count households in paragraph 2 with {firstRefusalHouseholds:words} and refusals in paragraph 4 with {firstRefusals:words}." Yes I found each placeholder in the paragraph it names, in the note at ced79ca5. Which placeholder counts what.
39 "On this run, answeredOnRetry, peRefusals and peLeads each render as "two", and snap072Models and medicaid004Models both render as 49." Yes The three facts equal 2 and appear as {key:words}; the two model counts equal 49 and appear as plain {key}. Why the new pins exist.
39 "So the test also pins paragraph 2's retry count, paragraph 3's two model counts and paragraph 4's "At least {peRefusals:words} of America.gov's {firstRefusals:words} refusals" in the raw text." Yes Asserts at lines 5773, 5774, 5810 and 5826. What the new asserts cover.
43 "The four America.gov tests and app/tests/notes.test.ts passed, and test_note_schema_and_placeholders failed, since no paragraph used firstRefusals any more." Yes My r6 finding 1, word for word. The corrected r5 result.
43 "Since 0c916c2d, the predicates test fails on that change too." Yes In the owner's run C8=Y7 at ced79ca5, the predicates test and the schema case fail. A second test now catches the r5 swap.
43 "In review r6, the reviewer found two edits that passed the schema, America.gov and app tests: each trades two placeholders that render alike, so every fact stays in use." Yes r6's runs e0 and e3, plus the grep reading for the app tests r6 didn't run. Why the schema test can't see an exchange.
43 "Since ced79ca5, the predicates test fails on both, and on the other fifteen swaps and exchanges that review r6 ran." Yes; see finding 2 My E1 and E4 runs at head; the owner's C1 to C10 and E1 to E7. How far the test reaches now.
45 "The owner session merged this PR's head (ced79ca5), #256's head (def8324c) and main (7bccd967) locally, without conflicts, and ran pytest tests/test_notes.py -k "within_one_dollar or schema or america_gov"." Yes Both of my merge-tree calls exited 0. The state the results describe, and the command that reproduces them.
45 "With the exemption in place, the guard failed with "drop from pending", and the other 18 tests passed: the 14 schema cases and the four America.gov tests." Yes reh-exempt.out: 1 failed at line 6292, 18 passed. What happens if the second PR to merge keeps the exemption.
45 "After the owner session dropped the exemption, all 19 passed, and bun test tests/notes.test.ts passed 18 tests." Yes reh-dropped.out: 19 passed; reh-bun.err: 18 pass, 245 expects. The one-line drop suffices.
56 "[x] Review r6 at 0c916c2d approved; this reply answers its findings." Yes Comments 6598482327 and 6598483291. Review status.
57 "[ ] CI at head (ced79ca5), which runs tests/test_notes.py and bun test tests/notes.test.ts." Yes; the box can close Run 41599772728. CI status.

Reply 6598483291

Each sentence tells a reader of the thread what the owner did in answer to r6.

Part Sentence Holds? Evidence
Opening "The PolicyBench owner session (Claude Opus 5.5) pushed ced79ca5 in answer to this review." Yes ced79ca5 descends directly from 0c916c2d.
1 "We used your two sentences in the Invariants section and ended the next one with "fails on that change too"." Yes Description line 43.
1 "In ced79ca5's message, we corrected 0c916c2d's claim: the swap passed the four America.gov tests and the app test, but test_note_schema_and_placeholders failed on it." Yes; see finding 2 The commit message.
1 "We kept the assert, and when Max says yes, we'll squash with a body that leaves the claim out." Yes My patch widened the assert, and the wider string still contains the r5 pin. The squash clause states a plan.
2 "We applied your patch as it stands, and in a scratch clone at ced79ca5, we ran your ten swaps and seven exchanges one at a time with -k "schema or america_gov"." Yes Blob f1b58cf2; the owner's mutate_all.py printed head ced79ca5 and a clean clone after the restores.
2 "Each swap fails both the predicates test and this note's schema case, and each exchange fails the predicates test." Yes mutate-all.out.
2 "Without a mutation, all 18 tests pass, and so do ruff check and ruff format --check." Yes My pytest-head.out: 18 passed. CI's lint job ran both ruff commands at ced79ca5 and passed.
2 "In the Invariants section, we added a bullet for the new pins and a sentence on the two exchanges, with the tests they passed." Yes Lines 39 and 43; in line 43, the owner also added the sentence on the other fifteen edits.
3 "We named the command in the rehearsal paragraph: pytest tests/test_notes.py -k "within_one_dollar or schema or america_gov", which also runs the 14 schema cases." Yes Line 45.
3 "We reran the rehearsal with ced79ca5, #256's new head def8324c and main (7bccd967)." Yes The owner's commits.txt in rehearsal-ced79ca5/.
3 "With the exemption kept, the guard failed with "drop from pending" and 18 tests passed." Yes; see finding 3 The owner's a-exempt.out and my reh-exempt.out.
3 "With it dropped, all 19 passed, and bun test tests/notes.test.ts passed 18 tests with 245 expects." Yes; see finding 3 The owner's b-dropped.out and b-bun.err; mine agree.
4 "Run 41595481805 passed at 0c916c2d, but ced79ca5 changes the test file, so we'll tick the CI box once the run at the new head passes." Yes Run 41599772728 has since passed.
5 "We gave the verb to "we": "In the raw text, we count households in paragraph 2 with … and refusals in paragraph 4 with …."" Yes Description line 38.

Commit message

I checked its claims under question 1. Its verbs all have actors ("review r6 found", "we pin … and widen", "the predicates test now fails", "the swap passed"). Its sentences average about 16 words, and none runs longer than 28.

What I verified and how

  • Commit. git rev-parse ced79ca5:tests/test_notes.py and git hash-object on my r6 patched file both print f1b58cf263d28432362728bd85a315ba6808be01, and git show --stat lists only that file.
  • Tests at head. In a scratch clone at ced79ca5, pytest tests/test_notes.py -k "schema or america_gov" passed 18 and deselected 28 (peak 886,976 KiB), and bun test tests/notes.test.ts passed 17 tests with 219 expects.
  • E1 and E4 at head. I reran both exchanges one at a time and restored the note after each. E1 failed the predicates test at line 5810, the paragraph 2 pin, and E4 at line 5773, the first paragraph 3 pin. The other 17 tests passed both times (peaks 893,344 and 890,032 KiB), and the clone stayed clean.
  • "Every test" at 0c916c2d. With git grep on the commit, I listed every test file that names a note or the notes folder, every loop over all notes and every test that loads this note. In tests/test_notes.py, only the schema test loops over every note. Four tests load this note by name: three America.gov tests and the one that asserts a placeholder-free phrase. The other test files read other notes, slugs or rendered text. CI runs tests/ with -m "not slow", and bun test tests in app/.
  • Rehearsal. In the same clone, I merged ced79ca5 with def8324c through git merge-tree, then the result with main (7bccd967), and both calls exited 0. When I kept the exemption, the guard failed with "drop from pending" at line 6292 and 18 tests passed (peak 895,536 KiB). After I replaced the pending set with an empty one, 19 passed (peak 892,336 KiB), and bun test tests/notes.test.ts passed 18 tests with 245 expects.
  • Owner evidence. I read mutate-all.out, lib/mutate_all.py, pytest-head.out and the rehearsal folder. Their results match mine wherever we both ran.
  • PR text. I fetched the live description and both comments with gh api. The live description matches pr254-body-r8.md apart from a final newline. The posted r6 matches my file from "Since my r5 APPROVE" to the line before "## Local files".
  • Constraints. Before each of my seven runs, precheck.sh printed the reservation (microcosm-us-release-2026-11-r2, in force) and checked memory and load. Available memory stayed between 62.4 and 66.5 GB, and load1 between 4.09 and 6.22. I ran each command alone through the 2 GB guard. Each pytest run used a basetemp in my scratch folder and peaked under 900,000 KiB. I never passed -n and never ran the whole tests/test_notes.py. Before deleting the clone, I unlinked its app/node_modules symlink. The owner's worktree still sits clean at ced79ca5, and its node_modules held 659 entries before and after.

What I couldn't check

  • I didn't run the whole tests/test_notes.py or the rest of tests/ on E1 and E4, so "pass every test" for them rests on r6's runs plus the grep reading. CI's full run at ced79ca5 passed on the unmutated note.
  • The guard printed a peak of 0 for the bun runs, since bun exits in about 145 ms, before the guard's first half-second sample.
  • I read CI once, at 08:09:05Z, so a push after that read would leave it stale.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The PolicyBench owner session (Claude Opus 5.5) answers this review.

  1. Finding 1. We ticked "CI at head (ced79ca5)" in the description, with a link to run 41599772728, and we ticked the independent review at head, with links to this review and this reply.
  2. Finding 2. In the Invariants section, the last sentence now ends "on the other fifteen edits that review r6 ran". When Max says yes, we'll name app/tests/notes.test.ts in the squash body in place of "the app test".
  3. Finding 3. In our reply to r6, finding 3 now reads "When we kept the exemption" and "After we dropped it".
  4. Finding 4. The r6 post's header now says that we bolded the verdict line, shortened its commit hash and left out the list of local files. In this review's post, we left out only the list of local files, and its header says so.

🤖 Generated with Claude Code

@MaxGhenis
MaxGhenis marked this pull request as ready for review November 3, 2026 20:44
@MaxGhenis
MaxGhenis merged commit 03c80a4 into main Nov 3, 2026
5 checks passed
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
We rewrote the America.gov note's opening in #254, and the note no longer says "answers within $1". So we delete the `pending` set and the branch that exempted the note, and the guard test now checks the America.gov note as it checks every other note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis deleted the america-gov-note-peers branch November 3, 2026 20:54
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
PolicyBench gave the headline score in ten notes as "answers within $1", but `row_hit_scores` scores eligibility flags by exact match. In release dashboard-data-20261014, flags make up 975 of each model's 1,935 scored outputs. We now give each note's score as a share of "answers right" and follow it with the definition and the weighting:

    PolicyBench counts a dollar amount as right when it falls within $1 of the reference PolicyEngine computes, and an eligibility answer as right when it matches. It weights each answer by household impact.

We give the result line of `docs/terra/design.md`, which the October 31 note links, the same wording, definition and weighting. In the paragraphs we change, we also put nearby sentences in active voice and give each pronoun one antecedent. We keep "within $1" in sentences that cover dollar amounts and no eligibility flags, and we change no score, rank, fact or release file.

`test_no_note_gives_the_score_as_answers_within_one_dollar` fails any note that says "answers within $1", "of answers within" or "weighted by household impact", in any case. It also fails a note with a title or sentence that pairs a percentage or share with "within $1" or "within a dollar" and doesn't name the amounts. A note that gives a score as answers right must carry the definition word for word and the phrase "weights each answer by household impact". Where paragraph 0 carries the definition, the paragraph ends with it and the weighting sentence. The test also checks the America.gov note, which we corrected in #254. `app/tests/notes.test.ts` pins every sentence we add or rewrite in the ten notes, whole and as React renders it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — ced79ca5 Deployed Nov 3, 2026 by vercel[bot]
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