Repository navigation
PP-4: manifest version 2, row keys, per-file plain-stack confirmation - #110
Conversation
Move only, so the manifest v2 and per-file confirmation work that follows grows no oversized file: - axis_review.py: check_mapping, review_axes, channel_count and their helpers (from axes.py, 717 -> 470 lines); - sources.py: check_sources and its texts (from manifest.py, 732 -> 581 lines). Importers now use the new modules, and the package re-exports the same names. The baseline entries are re-keyed with tools/check.py --rename. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
…mation
Design v0.4 §1, §3, §6 (spec revision 4, PP-4). Breaking: every v1 run is
recomputed.
- Manifest version "2":
- per file, roles and axes_from (header | confirmed) are required, by
the reader and the writer; pixel_sizes are recorded by role with
value, unit and source (recorded_sizes.RecordedSize; header for now);
- per mask: size, mtime_ns, roles, axes_from and shared (mask_record,
B3);
- an optional conversion_record_sha256.
A version 1 manifest is still read, but no row of it is reused ("the
earlier run was written before v0.4.0, without the axis check").
- fingerprint.Fingerprint and fingerprint.RowKey are one rule for "the
same file, read the same way" (audit D5): fingerprint, labels, axes,
roles, axes_from, the read path, and the row-changing settings.
run/entries.py builds the entries and sorts the files by row key, moved
out of run_experiment, which shrinks.
- axis_check.ConfirmedAxes: a confirmation covers only the files it was
given for (audit 2 B-1). A plain stack outside it is the error
plain_stack_not_confirmed. A plain AxisMapping still confirms every file
the run finds. The notebook passes its files in PP-10; the CLI's reuse
of the recorded mapping comes in PP-7.
- NarrowRange moves to narrow_ranges.py so manifest.py stays under 600
lines. Tests share tiff_tree.write_plain.
Docs: contract §2/§9, user guide message, plan §12 Q47, AGENTS.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
…t from annotations - A plain stack whose confirmed roles put X before Y (TXY) is the error axes_x_before_y: nothing is ever read transposed. The message recommends saving again with Y before X, or OME-TIFF copies (owner decision). - tools/check.py leaves tests out of the private-docstring rule, as Ruff already ignores ANN and D there (owner decision). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
Conflicts: tools/check.py keeps main's noqa count over every source; the baseline is main's keyed format, lowered to this branch's code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
Audit 2 B-1 and design v0.4 §3: a plain stack that is new *or changed* must be confirmed again. ConfirmedAxes named files by path only, so a plain stack rewritten under the same name stayed confirmed and was read with the roles confirmed for its old contents. - ConfirmedAxes.files now maps each file to its Fingerprint when it was confirmed; fingerprint.confirm_axes records it. - run_experiment drops confirmed files whose fingerprint changed or that are gone (fingerprint.unchanged_confirmation), so such a plain stack is plain_stack_not_confirmed. The pure axis check stays free of I/O. - run_experiment's counts come from the Comparison (161 executable lines, baseline lowered from 166). - header_axis_issue's docstring no longer claims a header naming X before Y is refused: only confirmed roles of unnamed axes are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
|
Independent review of PP-4 (design v0.4 rev 4 §1, §3, §6, §9). Finding, fixed in Verified:
For later, not blocking:
Generated by Claude Code |
This is PP-4 of the v0.4.0 plan (
preprocessing-design-v0.4.mdrevision 4, §1, §3, §6 and §8). It is breaking: every v1 run is recomputed. It is based on main, with PP-0, PP-2 and PP-3 merged.Commits: a move-only commit, the features, the X-before-Y follow-up, a merge of main, and a review fix.
Summary
Move only (commit 1):
review_axes,check_mappingandchannel_countmove fromaxes.pytoaxis_review.py;axes.pygoes from 717 to 434 lines.check_sourcesmoves frommanifest.pytosources.py. In commit 2,NarrowRangemoves tonarrow_ranges.py.tools/check.py --rename.Features (commit 2):
rolesandaxes_from(headerorconfirmed) are required; the reader and the writer both refuse an entry without them.pixel_sizesper file: one entry per role X, Y, Z, T, each withvalue,unitandsource. The source isheaderfor now; PP-8 addsstatedandpixels. An uncalibrated axis has value and source null, never a guessed value.size,mtime_ns,roles,axes_fromandshared(mask_record, B3).conversion_record_sha256.fingerprint.Fingerprintandfingerprint.RowKeygive one rule for "the same file, read the same way" (audit D5). The key is the fingerprint, labels, axes, roles,axes_from, the read path and the row-changing settings.run/entries.pybuilds the manifest entries and sorts files into new, changed and unchanged by row key.run_experiment, which went from 195 to 172 executable lines.axis_check.ConfirmedAxes(audit 2 B-1): a confirmation covers only the files it names, as they were when confirmed:fingerprint.confirm_axesrecords each file'sFingerprint, andrun_experimentdrops files changed since (review fixacc6fa7).plain_stack_not_confirmed, and is never read with roles confirmed for other files.AxisMappingstill confirms every file the run finds.e9108d2): a plain stack confirmed with X before Y (TXY) is the erroraxes_x_before_y; nothing is read transposed.Notes for review
Not wired in this PR:
--axes(PP-7).For now,
ConfirmedAxesis enforced through the API.Read path: it is part of the row key (spec §1), so moving the experiment folder recomputes its rows. A test covers this.
Settings: settings that change every row are still reported once, as the rebuild reason. Row keys are compared with the current settings on both sides, so the new/changed/unchanged counts stay per file.
Test edits:
test_masks.pynow checks only the mask path; the full mask entry is checked intest_manifest_v2.py.plain()helper is shared astiff_tree.write_plain.Tests
tests/test_manifest_v2.py(12 tests):axes_fromand pixel sizes; a plain stack recorded as confirmed and uncalibrated;Fingerprint;plain_stack_not_confirmednames only the unconfirmed file); named images need no confirmation.fingerprintandConfirmedAxesdo not exist there.tests/test_x_before_y.py(9 tests): X-before-Y confirmations refused.test_a_plain_stack_changed_since_its_confirmation_is_not_coveredfails without the fix.tools/check.py --rules, pytest with.[dev,notebook,zarr]), atacc6fa7:https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
Generated by Claude Code