Sprint: 6 Dates: 2026-10-12 - 2026-10-16 Sprint Goal: Restore trustworthy rotated dynamic/mixed-content positioning in rendered output and the canvas, then deliver the first grouped Address Control so operators can manage address blocks as one unit.
| Story | Size | Status | Tasks |
|---|---|---|---|
| Keep rotated dynamic and mixed-content fields positioned consistently across records | 5 points | Done | - [x] Decide and document the canonical pivot rule for variable-width rotated content, with the expected lower-risk path being fixed-anchor rotation for elements containing at least one field run - [x] Update the CLI render geometry so dynamic and mixed-content rotated TextDraws no longer compute a corrected anchor from each record's resolved text width, while rotated static elements keep the Sprint 4 center-pivot behavior unchanged - [x] Update desktop canvas drawing, hit-testing, and rotate-handle geometry so the preview uses the same pivot rule the CLI uses for dynamic/mixed elements, restoring canvas/render parity - [x] Add unit tests for the pivot decision and regression tests proving two records with different resolved lengths render at the same position for the same rotated dynamic element - [x] Extend the existing real-DLL rotation verification where needed, and live-verify against a real CSV/template that the rendered PDF no longer drifts record-to-record |
| Group lines into a single, movable Address Control | 13 points | Done | - [x] Design the Address Control model on both desktop and CLI sides: one control anchor, ordered line list, per-line mixed-content runs, per-line font/content/collapse settings, and automatic line spacing - [x] Add designer UI to create an Address Control, manage its line list, and add/remove/reorder lines without assigning each line an independent canvas position - [x] Implement two-level canvas interaction: select/move/resize the whole control as one unit while allowing an individual line's content and collapse setting to be edited - [x] Persist and reload the full Address Control structure in XML, documenting the new container shape in TEMPLATE_FORMAT.md; existing text-element templates must remain unchanged - [x] Expand the CLI parser/render pipeline so one Address Control becomes ordered text draws with the same mixed-content resolution and collapse behavior shown in the designer - [x] Verify Address Control collapse behavior reuses or preserves the existing per-line collapse semantics, and log any remaining same-X grouping ambiguity as future technical debt only if it remains relevant after implementation - [x] Unit tests: model, line-list operations, selection/movement behavior, save/reopen, CLI parse/render expansion, per-line default-collapse behavior, and preview/render parity - [x] Live actual-built-artifact verification: create a custom Address Control, add/reorder mixed-content lines, move it as a unit, save/reopen, and render against the real sample CSV |
logs/impediment_log.md. Neither blocks this sprint's committed items.Sequenced by product risk first, then feature dependency/surface area.
| Batch | Story | Why it's gated here |
|---|---|---|
| 1 | Keep rotated dynamic and mixed-content fields positioned consistently across records | Highest product risk because it fixes already-shipped print-output correctness and restores canvas/render parity before more composite text work builds on the same geometry. |
| 2 | Group lines into a single, movable Address Control | Depends on Sprint 5's mixed-content model, which is Done. Pull second so the team starts this larger GUI-heavy feature after the shipped-output defect is under control. |
| Day | Date | Completed | Planned | Blocked/At risk |
|---|---|---|---|---|
| 1 | 2026-10-12 | Sprint 6 planned. Backlog refinement completed for the rotation-positioning defect: story marked Ready and sized at 5 points after code inspection. | Begin Batch 1. Decide the canonical pivot rule, then update the render/canvas geometry with regression coverage before touching Address Control work. | GUI automation reliability needs deliberate attention before/during Batch 2; not blocking Batch 1. |
| 1 | 2026-10-12 | Batch 1 (“Keep rotated dynamic and mixed-content fields positioned consistently across records”, 5 points) done, all 4 ACs met with one explicitly chosen scope trade-off. Pivot decision: any rotated element containing at least one field run now rotates around its fixed authored (x, y) anchor; purely static rotated text keeps the Sprint 4 bounding-box-center correction unchanged. CLI implementation: RenderEngine marks dynamic/mixed TextDraws with UsesFixedRotationPivot, and DebenuPdfRenderer uses the authored anchor directly for those draws instead of calling GetTextWidth(draw.Text) and recomputing a center from each record's resolved value. Canvas implementation: CanvasElementEditor and TemplateCanvasControl use the same pivot rule for draw transforms, hit-testing, handle positioning, and drag-to-angle math, so variable-width content no longer gets canvas geometry based on a design-time placeholder center. Documentation: TEMPLATE_FORMAT.md now states the two pivot rules explicitly. Tests: full suite passes at 336/336 (dotnet test code/EnvelopeRenderer.slnx): 94 CLI tests and 242 desktop tests. New coverage includes render-engine fixed-pivot propagation for rotated dynamic and mixed elements, static rotated text preserving center-pivot mode, dynamic canvas hit-testing/handle/drag geometry around the fixed anchor, and a real-DLL regression (DebenuPdfRendererRotationTests.AddPage_FixedRotationPivot_UsesTheAuthoredAnchorForDifferentTextWidths) proving two different text widths produce rotated transforms with the same authored anchor. Live artifact checks: built the desktop executable successfully (dotnet build code/src/EnvelopeRenderer.Desktop/EnvelopeRenderer.Desktop.csproj, 0 warnings/errors); rendered the existing rotated dynamic sample template (sample-envelope-template2.xml) through the built CLI against the real 392-record sample CSV, exit 0 with PROGRESS complete ... completed=392 and a 2,375,011-byte PDF; rendered the actual WinForms TemplateCanvasControl from the built assemblies to sprint6-canvas-rotated-dynamic-smoke.png and visually confirmed the page, static label, and rotated {Full Name} dynamic element all drew correctly. The trade-off: variable-width dynamic/mixed content no longer uses exact bounding-box-center rotation, by design, because that center is not stable across records; fixed-anchor rotation is the stable, schema-free rule chosen for print alignment and preview/render parity. The High-impact technical debt item opened on 2026-10-09 is resolved. |
Begin Batch 2 (“Group lines into a single, movable Address Control”). Start with the model/schema decision and the GUI automation reliability hardening action from the Sprint 5 retrospective before driving the larger canvas/list-management UI. | None for Batch 1. Batch 2 remains GUI-heavy; automation reliability is an active risk to manage, not a blocker. |
| 1 | 2026-10-12 | Batch 2 (“Group lines into a single, movable Address Control”, 13 points) done, all 6 ACs met. Implemented a first composite element type with AddressControlLayout/AddressControlLineLayout in the designer and TemplateAddressControl/TemplateAddressControlLine in the CLI parser model: one X/Y anchor, width, automatic line baselines from each line's font size and lineSpacing, ordered per-line mixed-content runs, per-line font/color/collapse settings, and default-on collapse inside controls. Designer UI now creates an Address Control, lists its lines, edits the selected line with the existing {Column} mixed-content convention, supports add/remove/reorder, moves the whole control as one selection, and resizes the group from a right-edge canvas handle or the width property. Persistence uses a new <addressControl> container with <line> children; standalone text templates remain on their existing legacy shapes. CLI parsing/rendering expands one control into ordered TextDraws while preserving XML render order across ordinary <text> and <addressControl> nodes. Collapse behavior reuses the existing line-collapser semantics: every child line shares the control's X by construction, so control grouping and the same-X stack rule agree; no new same-X technical debt was introduced. Docs: TEMPLATE_FORMAT.md now documents the container, line content forms, default-on collapse, line-spacing rule, and current no-wrap/no-clip width behavior. Tests: full suite passes at 349/349 (dotnet test code/EnvelopeRenderer.slnx): 101 CLI tests and 248 desktop/core tests. Desktop executable builds cleanly (dotnet build code/src/EnvelopeRenderer.Desktop/EnvelopeRenderer.Desktop.csproj, 0 warnings/errors). Live artifact checks: rendered a temp <addressControl> template through the built CLI against the real 392-record sample CSV, exit 0 with PROGRESS complete ... completed=392, 2,377,358-byte PDF, and grep-confirmed first-page strings including WILLIAM EDWARD ZIMMERMAN JR, 4900 BC/EJ RD, and EAST JORDAN, MI 49727-9765; rendered the actual WinForms canvas from built assemblies to sprint6-address-control-canvas-smoke-resolved.png, visually confirming resolved sample text, blank-line collapse, selection border, and resize handle; rendered the actual TemplateDesignerForm through a live WinForms show/layout cycle to sprint6-address-control-form-smoke-fixed.png, visually confirming the Add Address Control toolbar action, right properties panel, content/width/line-list rows, and line add/remove/reorder controls. One verification improvement came directly from the Sprint 5 retrospective action: the full-form screenshot caught a real dock-order bug hiding the properties panel, which was fixed before completion. |
Move Sprint 6 to product-owner Sprint Review. | None. |
Date: 2026-10-12 Product-owner verdict: Sprint goal met in full.
dotnet test code/EnvelopeRenderer.slnx: 101 CLI, 248 desktop/core); desktop executable builds with 0 warnings/errors; live checks included a real 392-record CLI render and actual WinForms canvas/form bitmap smokes.width is a designer resize box today, not render-time wrapping/clipping; whole-control rotation remains out of scope and only a future candidate.Powered by TurnKey Linux.