Skip to content

experiments: meter close-up reading, tap-to-confirm and two retake checks - #16

Merged
AidenJohnston merged 13 commits into
mainfrom
t3/meter-closeup
Sep 27, 2026
Merged

AidenJohnston merged 13 commits into
mainfrom
t3/meter-closeup

Conversation

@SamGu-NRX

@SamGu-NRX SamGu-NRX commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

What changed

The app photographs the electric meter so Base can read its meter number and class label, and a homeowner must not be asked for photos again. This PR adds experiments/meter-closeup/. It measures, on 80 openly licensed meter photos, what the phone can decide on its own, and gives the iOS owner a spec to port. Each question's pass criteria were committed before its run.

Answers

  • Reading works. Apple's on-device Vision read the full meter number on 71 of 73 photos (97%, 95% interval 91–99%), and the US class label on 20 of 22.
  • Use tap-to-confirm for every meter. The number-finding rules were frozen on the odd-numbered photos (a77876c) before the rest were scored. The held-out set is split by physical meter, so it holds only meters the rules never saw. On those 34 photos, no rule reaches the 95% precision needed to fill the number in unasked; the best is right on 5 of 7. The top three candidates held the number on 27 of 34 (79%), counting the two photos Vision could not read as misses; over the 32 it read, 27 of 32 (84%). The earlier write-up reported 28 of 33 (85%): it dropped the unread photos and let one meter sit on both sides. Neither verdict changed. The app shows three candidates, a barcode match first, plus "none of these".
  • Two retake checks work on the phone: whole-photo sharpness of 6.68 or less (AUC 0.96, rejects 0 of 75 good photos), and a top candidate 33.9 px tall or less (AUC 0.86, rejects 2 of 75). Glare, framing and hand shake have no phone-side check.

Layout, per experiments/README.md

The README is now a front door of about 200 words. METHODS.md says how each number was made and how far to trust it. PORTING.md is the spec for the iOS owner, and FIELD_TEST.md checks both thresholds on an iPhone. Each file in results/ opens with the command that generated it.

Review fixes

  • Resume. A partial sweep could be resumed as complete, and the analysis accepted missing levels. Each photo's rows now go to one file through an atomic rename. degrade.expected_levels gives the exact levels each photo takes, from the same rule that skips a level in the sweep. Resume skips only a photo whose file holds exactly those levels under the current label, and make q2 refuses to run, naming any photo that falls short. The sweep also creates its directory before its first save, so a fresh data directory runs.
  • Leak scanner. The scanner skipped every CSV cell shaped like a decimal, so an identifier printed with one dot went unchecked. It also skipped cells beyond the header. Now every cell is scanned except those in the measurement columns listed in leakcheck.py. Tests plant a synthetic dotted identifier in an ordinary column, in a surplus cell and after an empty first line, and each is caught. No real identifier was found.
  • OCR input. Vision read the saved JPEG while the checks ran on the pixels before encoding. Both now use the decoded JPEG. The full re-sweep changed no read result; the focus threshold moved from 6.63 to 6.68.

Keeping meter numbers out of the repository

manifest.csv stores meter numbers as HMAC-SHA256 digests, keyed outside git and in the METER_HMAC_KEY repository secret, so they cannot be reversed by trying every number. make leakcheck scans every tracked file in the repository for any identifier a reader transcribed, from four digits up. Pull-request code never receives the key: the keyed check runs in CI only on main, after merge or when dispatched from main, and the branch writer runs it locally before review. This branch's earlier history was rewritten to remove example meter numbers and unkeyed digests. Since then, main has been merged in, not rebased.

Verification

  • make check: ruff clean; 84 unit tests pass. They include a rebuild, Keep and ingest round trip for a corrected label; a changed number box forcing a new sweep; field-test checks on unrecompressed pixels; note scrubbing across every separator; a fresh-directory run of the real sweep_image, checked against the expected levels; empty, partial and interrupted sweep files; and dotted identifiers in ordinary, surplus and headerless cells.
  • make leakcheck, run locally at the head: "no transcribed identifier in 108 files across the repository".
  • make sweep and make q2 reran all 3,309 degraded reads on the JPEG-consistent code. All 71 photos pass the exact completeness check, and make q2 output is unchanged by the later fixes. make q1 and make q45 regenerated the other tables.
  • CI's "Meter close-up checks" runs lint and tests on pull requests. "Meter close-up leak check" runs after merge, so it shows as skipped here. The Vision reader needs macOS and the photos, so CI does not run it.
  • The sweep reran under the measurement-code digest and reproduced all 3,309 rows exactly.

Risk

  • Two AI readers made the labels. Which printed identifier counts as the meter number was one reader's choice, and it decides half of the number-finding misses. Base needs to say which identifier it uses.
  • Commons photos are mostly clean close-ups, so homeowners' photos will read less often. Both thresholds need the iPhone field test before shipping.
  • Commits from before the history rewrite may stay reachable on GitHub by their old IDs.

Checklist

  • The scope is focused; related changes belong together
  • I explained what changed and why
  • N/A: before/after images and video. The PR adds an experiment folder and changes nothing in the app.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
house-scanning-web Ignored Ignored Preview Sep 26, 2026 10:36am UTC

@github-actions github-actions Bot added the size:XL 500-999 effective changed lines. label Sep 26, 2026
@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 36760c2e-0f84-46a8-b873-f5da4a616bf5

📥 Commits

Reviewing files that changed from the base of the PR and between e53e9b3 and 34fb2eb.

⛔ Files ignored due to path filters (4)
  • experiments/meter-closeup/manifest.csv is excluded by !**/*.csv
  • experiments/meter-closeup/results/locate_per_image.csv is excluded by !**/*.csv
  • experiments/meter-closeup/results/locate_per_image_dev.csv is excluded by !**/*.csv
  • experiments/meter-closeup/results/sweep_rows.csv is excluded by !**/*.csv
📒 Files selected for processing (31)
  • .github/workflows/meter-closeup.yml
  • docs/00-overview.md
  • docs/how-it-works.html
  • experiments/meter-closeup/FIELD_TEST.md
  • experiments/meter-closeup/METHODS.md
  • experiments/meter-closeup/Makefile
  • experiments/meter-closeup/PORTING.md
  • experiments/meter-closeup/README.md
  • experiments/meter-closeup/identifier_digests.txt
  • experiments/meter-closeup/results/clean.md
  • experiments/meter-closeup/results/locate.md
  • experiments/meter-closeup/results/locate_dev.md
  • experiments/meter-closeup/results/sweep.md
  • experiments/meter-closeup/src/meter_eval/analyze.py
  • experiments/meter-closeup/src/meter_eval/clean.py
  • experiments/meter-closeup/src/meter_eval/commons.py
  • experiments/meter-closeup/src/meter_eval/degrade.py
  • experiments/meter-closeup/src/meter_eval/fieldtest.py
  • experiments/meter-closeup/src/meter_eval/labels.py
  • experiments/meter-closeup/src/meter_eval/leakcheck.py
  • experiments/meter-closeup/src/meter_eval/locate.py
  • experiments/meter-closeup/src/meter_eval/retake.py
  • experiments/meter-closeup/src/meter_eval/review.py
  • experiments/meter-closeup/src/meter_eval/sweep.py
  • experiments/meter-closeup/tests/test_fieldtest.py
  • experiments/meter-closeup/tests/test_fixes_p1.py
  • experiments/meter-closeup/tests/test_leakcheck.py
  • experiments/meter-closeup/tests/test_locate.py
  • experiments/meter-closeup/tests/test_metrics.py
  • experiments/meter-closeup/tests/test_review_keep.py
  • experiments/meter-closeup/tests/test_sweep_resume.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added size:XXL 1,000+ effective changed lines. and removed size:XL 500-999 effective changed lines. labels Sep 26, 2026
@SamGu-NRX SamGu-NRX changed the title experiments: meter close-up readability eval (S5) experiments: measure on-device meter close-up reading and retake thresholds Sep 26, 2026
@vercel

vercel Bot commented Sep 26, 2026

Copy link
Copy Markdown

Deployment failed for project house-scanning-web with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/sam-gus-projects-7a4b6082?upgradeToPro=build-rate-limit

@SamGu-NRX SamGu-NRX changed the title experiments: measure on-device meter close-up reading and retake thresholds experiments: meter close-up reading, retake thresholds and number finding Sep 26, 2026
@SamGu-NRX SamGu-NRX changed the title experiments: meter close-up reading, retake thresholds and number finding experiments: meter close-up reading, number finding and retake checks Sep 26, 2026
@SamGu-NRX SamGu-NRX changed the title experiments: meter close-up reading, number finding and retake checks experiments: meter close-up reading, tap-to-confirm and two retake checks Sep 26, 2026
@SamGu-NRX
SamGu-NRX marked this pull request as ready for review September 26, 2026 13:15
@codemetrics-ai

Copy link
Copy Markdown

Note

Review skipped

Codemetrics is installed on this repository, but it hasn't been added to your team yet.

To enable AI code reviews for this repo, go to your dashboard and add house-scanning to your team's repositories.

@SamGu-NRX SamGu-NRX mentioned this pull request Sep 26, 2026
2 tasks done
AidenJohnston added a commit that referenced this pull request Sep 26, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

Before this merges, please cut its write-up to the experiment format in #33 (experiments/README.md). The README should stay under about 200 words: the question and pass criteria, the command, the result with its numbers, and what it changed. Put generated tables in results/ with the command that made them. docs/00 already carries the one-line finding.

@SamGu-NRX SamGu-NRX left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Main-track review findings at the pinned head. Fixes belong to the branch writer; no source changes made by this caretaker.

Comment thread experiments/meter-closeup/src/meter_eval/sweep.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/leakcheck.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/sweep.py
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T09:54:42.482498Z c8c666a Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b199613b43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/meter-closeup.yml
Comment thread experiments/meter-closeup/Makefile
Comment thread experiments/meter-closeup/Makefile Outdated
Comment thread experiments/meter-closeup/src/meter_eval/sweep.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/locate.py Outdated
Comment thread experiments/meter-closeup/manifest.csv Outdated
… scanner and OCR input

The README becomes a front door in the experiments/README.md format.
Method and trust go to METHODS.md, the app spec to PORTING.md, and the
iPhone check to FIELD_TEST.md; each results file names the command that
made it.

Review fixes:
- Each photo's sweep rows are written to one file by an atomic rename;
  resume skips only complete, current photos, and the analysis refuses
  missing or incomplete levels, naming the photos.
- The leak scanner exempts decimals only in named measurement columns,
  so an identifier printed with dots is scanned.
- Checks are computed on the decoded JPEG that Vision reads. Read results
  are unchanged; the focus threshold moves from 6.63 to 6.68.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

The write-up now follows the experiment format from #33, in 5b78ded (after merging main in 73fa467, without rewriting history).

  • README.md is a front door of about 200 words: the question and pass criteria, the command, the result with its numbers, and what it changed.
  • METHODS.md says how each number was made and how far to trust it.
  • PORTING.md is the spec for the iOS owner, and FIELD_TEST.md checks the thresholds on an iPhone.
  • Each generated table in results/ opens with the command that made it.

The same commit fixes the caretaker's three review findings (see those threads). The only number that moved is the focus threshold, from 6.63 to 6.68. The line in docs/00 stays true. CI is green, including the leak check.

@SamGu-NRX SamGu-NRX left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Repair verification found four remaining reproducibility/privacy-check defects. The committed threshold data independently reproduces 6.68; these findings concern fresh-run and completeness behavior, not a demonstrated change to those committed read outcomes.

Comment thread experiments/meter-closeup/src/meter_eval/sweep.py
Comment thread experiments/meter-closeup/src/meter_eval/leakcheck.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/sweep.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/analyze.py Outdated
…tory, full CSV leak scan

Second-review fixes:
- degrade.expected_levels gives the exact (family, level) set each photo
  takes, from the same rule apply() uses to skip a level. Resume and the
  analysis both require exactly that set under the current label, so an
  empty, partial or scale- and edge-less file is swept again, not
  accepted or skipped forever.
- The sweep creates its directory before saving the first work JPEG, so
  a fresh data directory runs.
- The leak scanner scans cells beyond the header and files with an empty
  first line; only named measurement columns stay exempt.

The committed sweep passes the exact check for all 71 photos and the
analysis output is unchanged, so no re-sweep was needed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…off PRs, harden the sweep cache

Codex review fixes:
- A manifest note held a four-digit utility plate number: note scrubbing
  and the leak scanner both started at five digits. Both now start at four,
  and the scanner catches the old note in every earlier commit.
- Pull-request code no longer receives METER_HMAC_KEY. The keyed leak
  check runs after merge and on demand; pull requests get lint and tests.
- make sweep fails when either shard fails.
- Sweep rows carry a digest of the measurement code, so a code change
  forces a re-sweep. The re-sweep reproduced all 3,309 rows exactly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A manual dispatch could target any branch and run that branch's scanner
with METER_HMAC_KEY. The keyed job now requires refs/heads/main for both
push and dispatch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@codex review

@SamGu-NRX

Copy link
Copy Markdown
Owner Author

Independent verification at 51a5804: the keyed workflow now runs only on main, and PR CI correctly skips it. CI run 36294891886 passes the unit checks. The preceding code repair at e93e7ab passed 62 tests; a separate local scanner check found no known transcribed identifier in 42 files. All 3,309 sweep outcomes were unchanged after excluding the new code-digest metadata. The fitted blur cutoff remains 6.68 and is not a field-accuracy guarantee. The historical disclosure remains open, and the physical-meter split is being corrected separately. No merge-readiness claim.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51a5804a08

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread experiments/meter-closeup/src/meter_eval/sweep.py
Comment thread experiments/meter-closeup/src/meter_eval/locate.py
Comment thread experiments/meter-closeup/src/meter_eval/fieldtest.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/locate.py
Comment thread experiments/meter-closeup/src/meter_eval/labels.py
Comment thread experiments/meter-closeup/src/meter_eval/match.py
Comment thread experiments/meter-closeup/src/meter_eval/review.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/match.py
Comment thread experiments/meter-closeup/src/meter_eval/clean.py
Photos of one meter now share a side, keyed by the labelled number's HMAC
digest. A meter with any odd-numbered photo, which the rules saw, goes
wholly to the design side; photos with no labelled number are never held
out. One meter crossed the old photo split. Held out now: top three
27/32 = 84% (was 28/33 = 85%), first 20/32 (21/33), barcode precision
5/7 (6/8). Both criteria still fail. The frozen design-half record and
the retake thresholds are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
SamGu-NRX added a commit that referenced this pull request Sep 27, 2026
t3/meter-closeup regenerated its sweep from decoded JPEGs at 5b78ded and
moved the retake threshold from 6.63 to 6.68; the #16 caretaker reproduced
it with no change in which photos read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
SamGu-NRX and others added 2 commits September 27, 2026 00:16
…fe field-test files, end-to-end ranking

Codex review 5328852981 fixes:
- A person's corrected meter number now joins identifier_digests.txt, so
  the leak check recognizes it.
- The field test keeps its working images in a private temporary folder,
  so it never overwrites, deletes or rescores a file in the photo folder.
- The held-out ranking headline counts photos Vision did not read as
  misses: top three 27/34 = 79% and first 20/34 = 59%. The rates over read
  photos (27/32, 20/32) stay in results/locate.md as conditional figures.

As the manager authorized, docs/00-overview.md and docs/how-it-works.html
now say about 4 in 5 held-out photos (27 of 34) instead of 85%.

Other verified findings are follow-ups in #103.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c863299fd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread experiments/meter-closeup/src/meter_eval/leakcheck.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/review.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/locate.py Outdated
Comment thread docs/how-it-works.html
…s corrections, no tied barcode promotion

Codex review 5329005766 fixes:
- leakcheck scans non-CSV files whole with normalize()'s separator rules,
  so an identifier written as 123/4567 or across a line break is caught.
- Keep after a correction confirms the corrected number, and
  labels.build() uses a kept correction as the human-confirmed label.
- A read inside two same-length barcode payloads is not promoted, so the
  ranking no longer depends on set order. The full re-sweep reproduced
  all 3,309 rows; no result changed.
- The how-it-works chart description now says 27 of 34 (79 percent).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a4d9ed5210

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread experiments/meter-closeup/src/meter_eval/leakcheck.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/locate.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/commons.py
…t unread photos in rule precision

Codex review 5329524921 fixes:
- leakcheck scans every tracked file from the repository root, not only
  this folder, and the keyed job runs on every push to main.
- Rule precision and recall count every agreed photo, so a wrong pick on
  a photo Vision did not read is a false positive. Held out, the
  tallest-line rule moves from 10/32 to 10/34 and the standalone rule
  from 22/32 to 22/33. No number quoted in the README, METHODS or docs
  changes; the re-sweep reproduced all 3,309 rows.
- commons find creates the data directory before writing candidates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8c666a9cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread experiments/meter-closeup/src/meter_eval/labels.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/review.py
Comment thread experiments/meter-closeup/src/meter_eval/fieldtest.py
Comment thread experiments/meter-closeup/src/meter_eval/fieldtest.py Outdated
Comment thread experiments/meter-closeup/src/meter_eval/fieldtest.py
@SamGu-NRX

Copy link
Copy Markdown
Owner Author

@greptileai

@greptile-apps

greptile-apps Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 1/5

[Low risk] Adds an isolated meter-reading experiment with documentation.

The PR is not ready to merge because barcode handling can miss an available number or promote the wrong one, and the experiment can retain stale measurements or erase a human label correction.

Fix All in CodexFindings

  1. P1 Barcode-only numbers are missed ▶
  2. P1 Unrelated barcodes become confirmed ▶
  3. P1 Changed inputs retain stale measurements ▶
  4. P1 Review rebuild loses corrections ▶
  5. P2 Field-test command uses wrong directory ▶
  6. P2 Fresh ranking run lacks directory ▶
Fix with agent prompt
### Issue 1
experiments/meter-closeup/src/meter_eval/locate.py:87-89
**Barcode-only numbers are missed.** If Vision decodes the meter number from a barcode but finds no digit-bearing text line, this function creates no candidate. The app then asks for a retake even though it has the number. The committed result for m12 shows exactly this: its barcode contains the number, but it has no candidates.

### Issue 2
experiments/meter-closeup/src/meter_eval/locate.py:95-101
**Unrelated barcodes become confirmed.** When a text token of six or more characters appears inside a uniquely shortest barcode payload, this code replaces the token with that entire payload and marks it confirmed, without checking whether the barcode identifies the meter. On a plate with multiple identifiers, a wrong number can gain the confirmation score, appear first, and be treated as needing no readability check when tapped.

### Issue 3
experiments/meter-closeup/src/meter_eval/sweep.py:89-99
**Changed inputs retain stale measurements.** If an image is replaced without changing its dimensions, or `make q1` produces a different number box without changing the applicable levels, resume still accepts the old rows. It checks the label, code and level set, but not those measurement inputs, so `make q2` can report read rates and thresholds calculated from the previous image or box.

### Issue 4
experiments/meter-closeup/src/meter_eval/review.py:64
**Review rebuild loses corrections.** After a human correction is ingested and the manifest is rebuilt, a rebuilt review page still displays reader 1’s original number. In a fresh browser session, keeping that displayed number exports no correction; ingest replaces the previous answers, and the next manifest build marks the original number as human-confirmed. This can erase the corrected ground-truth label.

### Issue 5
experiments/meter-closeup/FIELD_TEST.md:7-11
**Field-test command uses wrong directory.** These instructions tell the reader to run `uv run python -m meter_eval.fieldtest` from the photo folder, but `meter_eval` is installed by the experiment project. Unless it was separately installed in the photo folder, the documented command cannot import the module, blocking the prescribed iPhone threshold check.

### Issue 6
experiments/meter-closeup/src/meter_eval/locate.py:190-192
**Fresh ranking run lacks directory.** On a fresh data directory, `make q45` opens `ocr/scan.jsonl` without creating `ocr/`. `make images` creates only `images/`, and `q45` does not depend on `q1`, which normally creates `ocr/`. Running `q45` directly therefore fails before its first OCR read.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary

The PR adds a reproducible meter-photo OCR experiment, candidate ranking, retake thresholds, an iOS porting specification, and a keyed repository leak check. The review found gaps in barcode-only candidate handling, barcode confirmation, sweep freshness and human-label review; two documented experiment commands also need adjustment.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Meter photo] --> B[Vision text and barcodes]
  B --> C[Rank candidates]
  C --> D[Tap to confirm or retake]
  A --> E[Clean read and number box]
  E --> F[Degradation sweep]
  F --> G[Retake thresholds]
  H[Human label review] --> I[Manifest labels]
  I --> E
  I --> F
Loading

Reviews (1) · Last reviewed commit: "experiments(meter-closeup): scan the who..."

Comment thread experiments/meter-closeup/src/meter_eval/locate.py
Comment thread experiments/meter-closeup/src/meter_eval/locate.py
Comment thread experiments/meter-closeup/src/meter_eval/sweep.py
Comment thread experiments/meter-closeup/src/meter_eval/review.py
Comment thread experiments/meter-closeup/FIELD_TEST.md
Comment thread experiments/meter-closeup/src/meter_eval/locate.py
SamGu-NRX and others added 3 commits September 27, 2026 09:16
… keep corrections across rebuilds, digest sweep inputs, measure field photos unrecompressed

- labels.scrub replaces every digit the leak check could count toward an identifier, with
  separators dropped as normalize() drops them, so "12/345" and "12:345" no longer survive.
- The review page starts from ingested answers and shows a correction in place of the
  readers' number; ingest merges instead of replacing, so Keep in a new browser confirms the
  correction.
- Sweep rows carry a digest of the photo bytes, number box and degradation levels; a changed
  box forces a new sweep even when the same levels run.
- The field-test command measures each photo's own decoded pixels and hands Vision a lossless
  PNG, never a JPEG re-encode.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…asurement unchanged

All 3,309 rows reproduce; only the code and input digest columns differ.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AidenJohnston
AidenJohnston merged commit a02dc6f into main Sep 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ effective changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants