Repository navigation
Experiment design: one strict reader for other bricks (v0.3.4) - #59
Conversation
read_confirmed_design(path, expected_sha256=) -> ConfirmedDesign replaces CellPatcher's load_experiment_design and MorphoFeature's ExperimentDesign.read. It reads the file as this brick writes it and fills nothing in (exact header, one value per column, no outer whitespace, true/false only, no empty repeat group or count, D-e labels, no empty design), applies design_issues, checks the manifest's SHA-256, and hashes the bytes it parsed. Refusals raise DesignCheckError with ValidationIssues (missing_, unreadable_, changed_experiment_design, repeat_group_conflict, design_not_confirmed). Contract §16, plan question 40. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VbytvBRB9CmKQ5AAkhEFcv
Owner decision of 31 October 2026: when the user's edits to experiment_design.csv are read, repeat-group names follow the D-e identity rules (no NA-like value or empty, no outer whitespace) and confirmed_on is empty or an ISO date (YYYY-MM-DD). Both readers refuse a bad edit naming the line and column; an empty repeat_group no longer means the folder name. design_issues gives invalid_experiment_design for a design built through the API, so a run stops before writing, and write_experiment_design refuses to write such values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VbytvBRB9CmKQ5AAkhEFcv
Also tells CLI users that repeat_group must not be empty or NA and that confirmed_on is YYYY-MM-DD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VbytvBRB9CmKQ5AAkhEFcv
Contract §16 said read_confirmed_design applies the D-e case rule to repeat_group, but neither reader nor design_issues checked it, so Rep1 and rep1 were read as two repeat groups. Both readers now refuse it naming both lines and the column; design_issues reports it as invalid_experiment_design and the writer refuses it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WX6rdMV1r5jUPUR94kxV5a
|
Review (independent, from GitHub's current state at Fixed,
Checked, no change needed:
Follow-up (pre-existing, not changed here): when the notebook cannot read a saved design, Gate: main merged in ( Generated by Claude Code |
Core fix for v0.3.4 (owner decisions of 31 October 2026): one experiment-design reader for the other bricks, and typed checks on design edits. No version bump here.
Summary
read_confirmed_design(path, *, expected_sha256=None) -> ConfirmedDesignandDesignCheckError(aValueErrorcarryingissues).ConfirmedDesigngivespath,sha256(of the bytes parsed),design, read-onlyrepeat_groups({(condition, biological_repeat): repeat_group}, normalization's input),group_members()({group: {condition: biological_repeat}}),conditions,controlsandgroups.missing_experiment_design,unreadable_experiment_design,invalid_experiment_design,repeat_group_conflict,design_not_confirmed,changed_experiment_design.read_experiment_design(step 1 and the CLI) andread_confirmed_design. A bad edit is refused withDesignFormatErrornaming the line and column, for exampleexperiment_design.csv, line 2, column confirmed_on: '26/10/2026' is not a date in the form YYYY-MM-DD (for example 2026-10-26).repeat_groupfollows D-e: not empty,na,nan,none,null,n/aor<na>in any case, and no outer whitespace. An empty group no longer means the folder name.confirmed_onis empty orYYYY-MM-DD.design_issuesreports the same values asinvalid_experiment_design, sorun_experimentstops before writing anything.write_experiment_designrefuses to write them, so the brick only ever writes ISO dates; the notebook, CLI and run already fill dates withdate.isoformat()(tested).read_experiment_designstays lenient about the file's form (any-case booleans, BOM, outer spaces on other values).The two copies, and what is kept
Both copies call
read_experiment_designand thendesign_issues, then comparefile_sha256with the manifest's hash.load_experiment_designExperimentDesign.read(#110)missing_experiment_designmissing_experiment_designValidationIssues with codesDesignFormatErrorValueErrorexpected_sha256MappingProxyTyperecord()Where both copies agree, the shared reader is stricter and fills nothing in. It refuses:
TRUE,yes,1or empty for the booleans;It also applies the two typed checks above. Everything the brick writes is accepted, including a spreadsheet edit once a run has written it back (tested).
Tests
tests/test_confirmed_design.py(40 tests), shared reader:n/agroup, an empty group, and26/10/2026refused with the expected format in the message;tests/test_design.py, typed edits:26/10/2026refused with the exact message;YYYY-MM-DD.test_confirmed_design.pyfails at collection (read_confirmed_designmissing). Against the first commit of this PR, 24 of the typed-edit tests fail.PYTHONPATH=src):ruff check .passed,ruff format --check .passed,pytest1403 passed, 1 skipped (the root file-mode testtest_discovery.py:665).Behaviour change for users
A design file with an empty
repeat_group, an NA-like group, or a date such as26/10/2026is now refused by the notebook and CLI, where before it was read (and the empty group filled with the folder name). Release note needed.Follow-ups (other repositories, not edited)
load_experiment_design's body withread_confirmed_design(path, expected_sha256=manifest sha)and mapDesignCheckError.issuestoPreprocessingCheckError. Its no-manifest warning stays.ExperimentDesignfromConfirmedDesign(path, sha256, repeat_groups).🤖 Generated with Claude Code
https://claude.ai/code/session_01VbytvBRB9CmKQ5AAkhEFcv