# Sprint Backlog
**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.
## Committed Items
| 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 `TextDraw`s 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 |
## Notes
- Capacity signal: recent completed totals are **20, 19, 18, 18, and 15 points**. Sprint 5's 15-point total was an intentional under-commit around a high-risk 13-point story, not a failed capacity signal. This plan commits **18 points**, the proven low end from Sprints 3-4 and below the older 20-point ceiling.
- Planning rationale: the rotation-positioning story is pulled first because it fixes a High-impact defect in already-shipped PDF output and an already-shipped canvas/render parity acceptance criterion. The Address Control story is pulled second because its dependency ("Mix static text and CSV fields within a single text element") is Done and it remains the next major feature slice.
- Sprint 5 retrospective action items carried in: continue empirical vendor/spec/format verification before render- or format-affecting changes; continue live actual-built-artifact verification for GUI-facing stories; and deliberately harden GUI verification automation reliability before or during the Address Control story, since coordinate-space/DPI and window-focus issues have each surfaced once in the last two sprints.
- Impediments: template asset path strategy (absolute vs. relative) and UNC timeout/retry behavior remain open in `logs/impediment_log.md`. Neither blocks this sprint's committed items.
- Carried over from previous sprint: none (Sprint 5 completed both committed stories).
- Not committed: the 1,000,000-record PDF file-size mitigation remains open technical debt but does not block this sprint's committed scope; no committed story renders near that ceiling.
## Execution Order
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. |
## Daily Scrum Log
| 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 `TextDraw`s 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 `` container with `` children; standalone text templates remain on their existing legacy shapes. CLI parsing/rendering expands one control into ordered `TextDraw`s while preserving XML render order across ordinary `` and `` 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 `` 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. |
## Sprint Review Outcome
**Date:** 2026-10-12
**Product-owner verdict:** Sprint goal met in full.
- "Keep rotated dynamic and mixed-content fields positioned consistently across records" is accepted. The user-reported shipped-output defect is fixed with a stable authored-anchor pivot for dynamic/mixed rotated text, static rotated text remains on the prior center-pivot path, and canvas/render parity for the touched scenario is restored.
- "Group lines into a single, movable Address Control" is accepted. The delivered control covers create, add/remove/reorder lines, per-line mixed-content editing, default-on/toggleable collapse, whole-control move/resize, XML save/reopen, and direct CLI rendering.
- Verification baseline at review: **349/349 tests passing** (`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.
- No new backlog item is required from the review. Documented scope notes: Address Control `width` is a designer resize box today, not render-time wrapping/clipping; whole-control rotation remains out of scope and only a future candidate.
- Retrospective carry-in: the Sprint 5 action to harden GUI verification automation produced value immediately by catching the hidden properties-panel dock-order bug before release.