Skip to content

Publication writes the removed and image_count_changed records (RR2, RR1) - #216

Merged
guijacquemet merged 4 commits into
mainfrom
claude/records-rr1-rr2
Nov 8, 2026
Merged

guijacquemet merged 4 commits into
mainfrom
claude/records-rr1-rr2

Conversation

@guijacquemet

@guijacquemet guijacquemet commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

What changed

publish_description now writes the two Spec record types that it did not write before (experiment-v1 §4.6, §10, vendored at 2975e0e), in the same single atomic append as the reconfirmation records (all or nothing with the TOML, rollback unchanged).

New parameters: removals: tuple[Removal, ...] = () (the user's confirmations with their dates, the existing description_removal.Removal) and recorded_on: str | None = None, on publish_description and on publish_locked (added to main by the draft-file PR; the merge of main keeps both). New pure module run/description_records.py derives the lines by comparing the candidate with the published file. No code reads the clock.

removed (RR2).

  • A published unit is removed when neither its source folder labels nor its IDs (after confirmed ID corrections) are in the candidate, so a folder rename or an ID correction is not a removal.
  • Each removed unit is a unit line with all six keys, labels exactly as in the published file.
  • A condition, repeat or technical repeat whose ID is held nowhere after the removal also gets its own line (keys it does not name are null). Entity lines come first (condition, repeat, technical repeat, each by ID), then unit lines once each, by (condition ID, repeat ID, technical repeat ID).
  • confirmed_on is the date of the first removal answer that names one of its units.
  • A dropped unit that no removal names, or a removal naming a unit the candidate keeps, is a ValueError before anything is written. Refusals (R_*) still take priority.

image_count_changed (RR1, RR3). One line per member of a confirmed repeat whose image_count changed, whether or not the same publication changes anything else (a removal, a new member, an ID correction, a reopening). Members are matched through the confirmed ID corrections; a member the candidate no longer holds has no new count and is covered by its removed lines. Lines carry the published IDs and labels, ordered by (condition ID, repeat ID); technical_repeats is [{"id","source_folder"}] sorted by ID. A count change alone still reopens nothing and needs no confirmation. recorded_on is required when any line is due and must be a real YYYY-MM-DD date (ValueError otherwise, nothing written); it is never copied into confirmed_on.

Order in the appended block: reconfirmations, removed, image_count_changed.

Vendored Spec re-pinned to 2975e0e

Done as in #208: tests/spec_fixtures/PIN.toml (commit, fixtures_tree, blob of docs/experiment-v1.md; tools/audit/refval.py blob is unchanged), the copied docs/experiment-v1.md and fixtures/README.md (the only fixture-side file that differs; no fixture or validator changed), and SPEC_COMMIT in draft_format.py with docs/conformance.md. Every fixture is exact; the cross-check against the reference validator has 0 differences (37 valid, 135 invalid, 13 transitions, round trip on 50 files).

Existing tests changed

test_p15_new_fovs... (now expects the image_count_changed record, and the missing-date error), test_p08_..., test_removing_a_condition_... and test_p20_removing_the_last_member... now pass removals= (without it a dropped unit has no confirmation date, which the Spec requires). test_a_removed_technical_repeat_... removes a unit of a member, so that member's count falls with it: it used to publish with no count line and now passes recorded_on and asserts the count line is written (RR3). The new module tests/test_spec_records.py is added to EXPECTED_MODULES. run/description_records is registered as a pure layer.

Regression tests

tests/test_spec_records.py (14 tests): removed unit, repeat, condition and technical repeat with exact lines; canonical JSON text with null keys and read_records; the user's date, not the clock; unconfirmed or foreign removal refused; nothing written on refusal; rollback when the records write fails; image-count line (old/new counts, recorded_on, no confirmed_on), date required, multi-member order; and the RR3 test test_a_removal_and_a_count_change_in_one_publication_write_both_in_order (a removal and count changes of two members in one publication write the removed lines then the image_count_changed lines, in order, and they pass read_records).

  • RR3 test on the branch tip before this change (merged main, new pin, tests kept): 1 failed (no image_count_changed line written beside the removal). The original RR1/RR2 regression run against the old source (e1d7c18) was 17 failed, 42 passed.
  • New code: python tools/check.py: ruff check and format clean, 4569 passed, 4 skipped (the 4 skips are file-system-case and file-mode tests, pre-existing), code rules clean. The PR was previously reported at 4233 passed, 4 skipped; the difference is the tests main gained in the meantime plus the one new test here.

Other open preprocessing PRs will conflict on CHANGELOG; both entries were kept in the merge of main.

Owner decisions (2026-11-08)

  • RR3 (Spec PR 13, merged; Spec main 2975e0e): image_count_changed is written for every confirmed member whose image_count changed at a publication, even when the same publication changes other things. A count change alone still reopens nothing and needs no confirmation. Implemented here; before this change the line was written only when nothing else in the file differed.
  • RR2 choices confirmed as built: one entity line per vanished ID; unit lines written once after all entity lines; the date of the first removal answer per entity; published IDs when a removal is combined with an ID correction. Spec PR 13 also aligned conformance P35 to "entity lines first, then each unit line once".

🤖 Generated with Claude Code

https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
…75e0e

Owner decision RR3 (Spec PR 13): image_count_changed is written for every
confirmed member whose image_count changed, also when the same publication
changes other things. Members are matched through the confirmed ID
corrections; a member the candidate no longer holds is covered by its
removed records. Vendored Spec re-pinned to 2975e0e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
@guijacquemet
guijacquemet merged commit db6110d into main Nov 8, 2026
7 checks passed
@guijacquemet
guijacquemet deleted the claude/records-rr1-rr2 branch November 8, 2026 07:08
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.

2 participants