Skip to content

Fix multi-row AF CSV round-trips and validate writer output#8

Merged
ssweber merged 15 commits into
mainfrom
dev
Apr 7, 2026
Merged

Fix multi-row AF CSV round-trips and validate writer output#8
ssweber merged 15 commits into
mainfrom
dev

Conversation

@ssweber

@ssweber ssweber commented Apr 7, 2026

Copy link
Copy Markdown
Owner
  • CSV: preserve multi-row AF round-trips, including pinned/tall AF blocks away from row 0, multiple tall blocks in one rung, and generic tall continuation rows
    
  • Encode: suppress AF summary data when a rung contains multi-row AFs, avoiding grid misalignment and Click paste crashes
  • SCR decode: restore omitted wiring for generic tall AF continuation rows
  • CSV writer: fail loudly when emitted CSV rows lose decoded rung semantics by reparsing writer output and checking for row, condition, or AF mismatches before writing to disk

ssweber and others added 15 commits April 7, 2026 12:20
…ro pinned rows

The AF summary block (appended to the last AF cell when 2+ AFs exist)
was being emitted even when a multi-row AF (e.g. retained timer) was
present. Native Click captures omit the summary in that case — the
extra 32 bytes misaligned the grid and crashed Click on paste.

Also updates csv/converter.py and csv/writer.py to support pinned AF
instructions (timer/counter/shift/drum) at any row position, not just
row 0. This enables rungs like coil-at-row-0 + timer-at-row-1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3-row rung with coil at AF row 0 and retained timer at AF row 1 with
.reset() pin on row 2. Verified via Click paste round-trip.

Regenerates instr-6row-multi-output.bin (affected by AF summary
suppression) — needs re-verification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers the inspect_cells workflow for comparing native vs encoded
binaries, cell header field reference, and known pitfalls (AF summary
suppression, tall instruction visual_rows).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…grid

Use RowAst type for _parse_rung_row() parameter instead of object, and
use walrus operator in _grid.py generator to let ty narrow the type
across the for/if split. Also adds verified instr-6row-multi-output
golden fixture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
_consume_active_row unconditionally absorbed all blank rows following a
block, even after the block was full. This caused timer/counter/shift/drum
blocks to reject rungs with extra condition rows below the block.

Add _max_continuations() gate so blocks stop consuming once full (timer=1,
counter=2, shift=2, drum=3) and remaining rows flow through as normal
rung rows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ssweber ssweber merged commit 311e459 into main Apr 7, 2026
4 checks passed
@ssweber ssweber deleted the dev branch April 7, 2026 19:47
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