Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

81KB

Product Backlog

Index of all epics, ordered by priority (top = highest priority). Each epic is its own file under backlog/epics/.

Order Epic File Status
1 End-to-End Text Rendering Slice epics/01_end_to_end_text_rendering_slice.md In Progress (2 of 3 stories Done — Sprint 1)
2 Template Designer GUI Foundation epics/02_template_designer_gui_foundation.md Done (7 of 7 stories — Sprint 2, 4, 6)
3 CSV Integration and Field Mapping epics/03_csv_integration_and_field_mapping.md Done (4 of 4 stories — Sprint 4)
4 CLI Rendering Engine and Debenu Integration epics/05_cli_rendering_engine_and_debenu_integration.md Done (6 of 6 stories — Sprint 1-5)
5 Live Preview and Record Navigation epics/04_live_preview_and_record_navigation.md In Progress (2 of original 3 stories Done — Sprint 7; the new wrap/clip core story also Done — Sprint 9; “Add a live wrap/clip indicator for text elements” (re-scoped, 3 pts) and “...Address Control lines” (8 pts) remain Ready; “Warn on text overflow before render” provisionally sized at 5 pts, still Not Ready until both land)
6 Composite Address Controls and Mixed-Content Text epics/08_composite_address_controls.md Done (4 of 4 stories — Sprint 5, 6, 8; whole-control rotation delivered Sprint 8, see Sprint 8 Review outcome below)
7 Layout Efficiency and Operator Tooling epics/06_layout_efficiency_and_operator_tooling.md In Progress (1 of 4 stories Done — Sprint 7; “Select multiple elements at once on the canvas” and “Align and distribute multiple elements” Ready as a dependent pair, “Undo and redo layout changes” Ready, feasibility-checked 2026-10-19, still highest-uncertainty)
8 Dynamic and Network Image Handling epics/07_dynamic_and_network_image_handling.md Not Started (still blocked behind 2 open impediments; confirmed still non-blocking — both Composite Address Controls and Layout Efficiency still sit ahead of it in this table's order — see Sprint 8 refinement outcome below)

Notes

  • Prioritization favors the requirements document's recommended vertical slicing: deliver a text-only end-to-end workflow first, then layer images, shapes, and operator-efficiency tooling.
  • The CLI/rendering epic now sits ahead of preview in the ordered backlog because it is a direct dependency for the first demonstrable PDF-generating slice.
  • The top five epics now contain sprint-ready stories for the first one to two sprints of MVP work.
  • Open requirement questions that may affect ordering: path strategy for template assets and timeout behavior for slow UNC shares.

Sprint 1 Review outcome (2026-09-11)

  • Sprint 1's 5 committed stories are Done; verification detail and any caveats are recorded story-by-story in backlog/epics/01_end_to_end_text_rendering_slice.md and backlog/epics/05_cli_rendering_engine_and_debenu_integration.md. Full summary: backlog/sprints/sprint-1.md (Sprint Review Outcome section).
  • Recommend pulling “Time-box the first high-volume benchmark” (epics/05, 5 points, Ready) early in Sprint 2 refinement/planning alongside whatever else is pulled from epics 2-3 — it's a cheap, high-information risk check that's now overdue (not re-run since Sprint 1 Batch 2) rather than a reason to reorder the epic list itself.
  • New stories added from this review: “Harden production configuration delivery for CLI runtime settings” (epics/05) and “Surface real warning counts in progress and completion reporting” (epics/07). Neither is urgent for Sprint 2's likely candidates (epics 2-3 touch neither CLI configuration nor warnings).
  • The two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) do not block Sprint 2's likely candidate epics (2 and 3) — neither of those epics’ stories touch images or network asset paths. They only need to be resolved before epic 7 (Dynamic and Network Image Handling) stories are pulled into a sprint; recommend deciding them during backlog refinement once epic 7 nears the top of the backlog, per “delay firm decisions to the last responsible moment,” rather than treating them as urgent now.

Sprint 2 Review outcome (2026-09-18)

  • Sprint 2's 5 committed stories (the full Template Designer GUI Foundation epic plus the high-volume benchmark spike, 19 points) are Done; verification detail is recorded story-by-story in backlog/epics/02_template_designer_gui_foundation.md and backlog/epics/05_cli_rendering_engine_and_debenu_integration.md. Full summary: backlog/sprints/sprint-2.md (Sprint Review Outcome section).
  • Material finding, not a defect in this sprint's delivery: the benchmark spike found the render path badly misses the product's “100,000 records at 300 DPI in under 10 minutes” hard constraint — throughput degrades from ~399 rec/s to ~15 rec/s and falling at realistic scale, projecting 45-90+ minutes for a full 100k run (5x-10x+ over target), most likely due to Debenu Quick PDF Library 10.13's own document model rather than this repo's code. Full data: code/BENCHMARK.md. Strong recommendation: prioritize the new “Investigate and address high-volume render throughput degradation” story (epics/05, Ready, not yet sized) at or near the top of Sprint 3, ahead of or alongside CSV Integration — this is a High-impact item that directly threatens a hard product constraint (project_config.md) and gets worse, not better, the longer higher-volume-dependent feature work (CSV integration at scale, eventual 1M-record ceiling) is built on top of an unfixed render path.
  • The stretch item (“Load CSV headers and sample rows into the desktop app,” epic 3) was not pulled in Sprint 2; it remains the natural first CSV Integration story for Sprint 3.
  • No changes to the two open impediments (template path strategy; UNC timeout/retry) — still non-blocking for Sprint 3's likely candidates (CSV Integration and the throughput investigation touch neither template image paths nor network shares).

Sprint 3 planning outcome (2026-09-21)

  • scrum-master facilitated with dev-team sizing; committed 18 points against a 19-20 point velocity range: the throughput-degradation story (newly sized at 8 points — see backlog/epics/05_cli_rendering_engine_and_debenu_integration.md), then “Load CSV headers and sample rows,” “Create a dynamic text token from a CSV column,” and “Re-map an existing dynamic field” (epic 3, in backlog order). Full plan: backlog/sprints/sprint-3.md.
  • Not committed (capacity discipline): “Collapse blank optional address lines consistently” (5 pts, would overcommit) and “Harden production configuration delivery for CLI runtime settings” (2 pts, not urgent) — both clean pulls for Sprint 4.

Sprint 3 Review outcome (2026-09-22)

  • All 4 committed Sprint 3 stories (18/18 points) are Done; each is verified against its acceptance criteria with real, non-simulated evidence, recorded story-by-story in backlog/epics/05_cli_rendering_engine_and_debenu_integration.md (throughput story) and backlog/epics/03_csv_integration_and_field_mapping.md (the CSV Integration chain). Full daily detail: backlog/sprints/sprint-3.md.
  • Sprint goal met in full. The throughput risk carried in from Sprint 2 review is closed with a confirmed root cause (Debenu's internal document model) and a measured mitigation (batch+merge) — the 100k-record benchmark now completes in 315s, ~47.5% under the 10-minute target, a real completed run rather than an extrapolation. The first slice of CSV field mapping is delivered end-to-end and live-verified against the real built .exe: load headers, bind a dynamic field, rebind it, with the mapping honored on the next CLI render.
  • One new open technical-debt item carried forward, not a defect in this sprint's delivery: the throughput mitigation's per-batch font re-embedding cost extrapolates to ~4.5-5 GB in output file size at the product's stated 1,000,000-record ceiling, over the 2 GB constraint (logs/technical_debt_log.md, 2026-09-21 entry). No committed story renders anywhere near that scale, so this does not block Sprint 3 or any currently-planned Sprint 4 work, but it should be picked up and resolved before any future story commits to rendering near the 1,000,000-record ceiling — two candidate fixes (count-aware batch sizing; subsetted rather than fully-embedded fonts per batch) are already noted in the debt log.
  • “Collapse blank optional address lines consistently” (epic 3, 5 points, Ready) is now unblocked — its dependency (“Create a dynamic text token from a CSV column”) is Done — and is a clean, natural pull for Sprint 4 alongside “Harden production configuration delivery for CLI runtime settings” (epic 5, 2 points, Ready), both already identified as deliberately-deferred-not-dropped at Sprint 3 planning.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking for the Sprint 4 candidates named above.

New feature added during backlog refinement (2026-09-22)

  • User requested the ability to rotate text/dynamic field elements at an arbitrary angle. product-owner clarified scope directly with the user (angle range, UI interaction, pivot point) before writing the story, then split it into two dependent stories in epics/02_template_designer_gui_foundation.md (previously fully Done, now reopened): “Set a rotation angle for text and dynamic field elements” (properties-panel numeric entry, persistence, and render-side rotation about the bounding-box center — 8 points) and “Rotate elements by dragging a handle on the canvas” (interactive drag handle, depends on the first story — 5 points). dev-team sized both against real code inspection, confirming the vendor Debenu API (DrawRotatedText, GetTextWidth/GetTextAscent/GetTextDescent) supports the underlying capability but has no “rotate about center” primitive, so the center-pivot math is genuine new work, not a pass-through. Both pass the Definition of Ready; recommend against splitting further.
  • Placement recommendation (product-owner, not yet ordered into a sprint): slot these two stories immediately after the two items already flagged as clean Sprint 4 carryover from Sprint 3 planning — “Collapse blank optional address lines consistently” (epic 3, 5 pts) and “Harden production configuration delivery for CLI runtime settings” (epic 5, 2 pts) — rather than ahead of them, since neither carryover item depends on rotation and both were already committed-to in spirit at Sprint 3 planning. Note for Sprint 4 planning: those two carryover items (7 pts) plus both rotation stories (13 pts) sum to exactly 20 points, matching the top of this team's 19-20 point velocity range — scrum-master/dev-team should treat that as a ceiling-level coincidence to watch, not a target to hit, and should still leave normal grooming buffer per AGENTS.md's guidance. This ordering is a recommendation only; the human product owner can reprioritize the rotation stories ahead of the carryover items if rotation is more urgent than sequencing suggests.

Sprint 4 Review outcome (2026-09-29)

  • All 3 committed Sprint 4 stories (18/18 points) are Done; each is verified against its acceptance criteria with real, non-simulated evidence, recorded story-by-story in backlog/epics/02_template_designer_gui_foundation.md (both rotation stories) and backlog/epics/03_csv_integration_and_field_mapping.md (blank-line collapse). Full daily detail: backlog/sprints/sprint-4.md.
  • Sprint goal met in full. The CSV Integration and Field Mapping epic is now Done outright (4 of 4 stories). The Template Designer GUI Foundation epic is also Done outright again (6 of 6 stories, having been reopened for the rotation work). Test suite grew to 288/288 (up from 223 at Sprint 3 close).
  • No new technical debt logged this sprint. The one open item carried in from Sprint 3 (1,000,000-record file-size risk) remains untouched and non-blocking, as expected — nothing this sprint touched the render batching/font-embedding path.
  • One honestly-reported, non-blocking note from dev-team's own verification: a testing-tooling focus glitch (SetForegroundWindow failing once during GUI automation) briefly misdirected some keystrokes during Batch 3's live verification; caught immediately from screenshot evidence and worked around, confirmed to be a tooling artifact rather than a product defect — no product-facing gap, not logged as technical debt.
  • “Harden production configuration delivery for CLI runtime settings” (epic 5, 2 points, Ready) remains uncommitted, as planned — still a clean pull whenever it's prioritized, not urgent per the product owner's standing note.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md).

New epic added during backlog refinement (2026-09-29)

  • User requested, ahead of closing Sprint 4, the ability to compose an “address control” — a group of lines (mixing static text and CSV fields) placeable as one unit on both the canvas and the rendered PDF. product-owner gathered requirements directly with the user across two rounds of clarifying questions (composition model, single-anchor movement, collapse-default behavior, and — the highest-impact fork — whether mixed static+field content is scoped to the control or general) before writing anything down.
  • Recorded as a new epic, epics/08_composite_address_controls.md, with two dependent stories: “Mix static text and CSV fields within a single text element” (a general upgrade to every text element in the designer, not just control lines — confirmed explicitly with the user) and “Group lines into a single, movable Address Control” (a fully custom, operator-built line list with single-anchor movement and automatic spacing, default-on-but-toggleable per-line blank-collapse). Full requirements, including several explicit “Development Team design decision” flags for details not resolved with the user, are in that epic file.
  • Sized 2026-09-29 by dev-team with real code inspection: both stories landed at 13 points each — the largest single stories this team has sized to date (previous ceiling was 8). Both individually pass the Definition of Ready (each plausibly fits a single sprint against the 18-20 point velocity range), so both are marked Ready.
  • Placement recommendation (product-owner): do not commit both to the same sprint. They are hard-dependent (Story 2 cannot start meaningfully until Story 1's run-sequence content model exists) and together total 26 points — over a full sprint's capacity on their own, before any other backlog item is considered. Plan “Mix static text and CSV fields within a single text element” for the next sprint that picks up this epic, and “Group lines into a single, movable Address Control” for the sprint after, mirroring how the Sprint 3 CSV-mapping chain and Sprint 4 rotation chain were sequenced across (or within) sprints by dependency. dev-team's sizing note also flags one deliberate design call worth carrying into implementation: the Address Control owns a single X/Y anchor with lines auto-spaced relative to it (not N independently-positioned children), which as a byproduct means AddressLineCollapser's existing same-X grouping rule already produces correct per-control collapse behavior with no changes needed — qa-tech-debt should log a low-priority future-hardening note about the pre-existing “unrelated elements coincidentally sharing X” ambiguity this leaves unchanged, not required by either story's acceptance criteria as written.
  • Story 1 also carries a noted (not required) fallback split if a future sprint's capacity gets tight: a core vertical slice (data model, backward-compatible persistence, render resolution, a minimal bracket-syntax editor, single-color highlighting) versus a polish layer (protected token-chip editing, per-run canvas highlighting) — see the story's own sizing note for detail.

Defect found in already-shipped rotation feature (2026-10-09)

  • User reported rendered records with rotated text appearing to render at inconsistent positions. product-owner confirmed the root cause by code inspection before writing anything down: rotating a dynamic or mixed-content element pivots around a bounding-box center computed from that record's own resolved text width (DebenuPdfRenderer.AddPage/RotatedTextAnchorCalculator), so the pivot — and therefore the rendered position — shifts whenever resolved text length differs between records. Rotated static (fixed-text) elements are unaffected, which is why Sprint 4's own live verification didn't catch this. A second, compounding finding: this also breaks the rotation story's own already-shipped AC4 (canvas and rendered PDF must share the same pivot), since the canvas measures a fixed design-time placeholder rather than any record's actual resolved text.
  • Logged as a new Open, High-impact entry in logs/technical_debt_log.md (2026-10-09) and written up as a full story, “Keep rotated dynamic and mixed-content fields positioned consistently across records” (backlog/epics/02_template_designer_gui_foundation.md), with candidate fix directions recorded but not decided (anchor-point pivot vs. a canonical/representative width). dev-team sized it at 5 points on 2026-10-12 after inspecting the actual render/canvas geometry.
  • Priority decision for Sprint 6 (product-owner, user confirmed by “continue”): treat this as the first pull for the next sprint because it is a defect in already-shipped, real print-output positioning, not a new feature. The most common way to trigger it (any rotated field bound to a CSV column, or any mixed-content line with a field run) is a realistic combination now that both rotation (Sprint 4) and mixed content (Sprint 5) exist. Put it ahead of “Group lines into a single, movable Address Control,” while still pulling the Address Control story second if capacity allows.

Sprint 6 planning outcome (2026-10-12)

  • scrum-master facilitated with product-owner and dev-team input after the user confirmed the post-retro pause point with “continue.” Committed 18 points: “Keep rotated dynamic and mixed-content fields positioned consistently across records” (5 pts, epic 2, High-impact shipped defect) first, then “Group lines into a single, movable Address Control” (13 pts, epic 8, unblocked by Sprint 5's mixed-content story). Full plan: backlog/sprints/sprint-6.md.
  • Capacity signal: recent completed totals are 20, 19, 18, 18, and 15 points. The Sprint 5 15-point total was an intentional under-commit around the team's largest story rather than a missed-capacity signal, so Sprint 6 commits 18 points at the proven low end of the prior 18-20 range, not the ceiling.
  • Sprint 5 retrospective action carried in explicitly: harden GUI verification automation reliability before/during the Address Control work, because GUI automation friction has now appeared in two consecutive sprints and the Address Control story will need list-management and two-level-selection verification.
  • Not committed: any 1,000,000-record file-size mitigation and the two open path/UNC impediment decisions. They remain non-blocking for Sprint 6's committed scope.

Sprint 6 execution update (2026-10-12)

  • Batch 1, “Keep rotated dynamic and mixed-content fields positioned consistently across records” (5 pts), passed the dev-team Definition-of-Done check and was later accepted in Sprint Review. The High-impact rotation-positioning technical debt item from 2026-10-09 is resolved. Full evidence is recorded in backlog/sprints/sprint-6.md and backlog/epics/02_template_designer_gui_foundation.md.
  • Batch 2, “Group lines into a single, movable Address Control” (13 pts), passed the dev-team Definition-of-Done check and was later accepted in Sprint Review. The first composite Address Control is implemented end-to-end: designer model and UI, whole-control move/resize, per-line mixed content and default-on collapse, XML save/reopen, CLI parse/render expansion, and docs. Full evidence is recorded in backlog/sprints/sprint-6.md and backlog/epics/08_composite_address_controls.md. Sprint 6's committed 18/18 points are now Done.

Sprint 6 Review outcome (2026-10-12)

  • Product-owner verified both committed Sprint 6 stories against acceptance criteria (verdict: sprint goal met in full). Full verification notes are recorded story-by-story in backlog/epics/02_template_designer_gui_foundation.md and backlog/epics/08_composite_address_controls.md; detailed execution evidence is in backlog/sprints/sprint-6.md.
  • The rotated dynamic/mixed-content positioning defect is accepted as fixed: dynamic and mixed rotated text now use a stable authored-anchor pivot, static rotated text keeps the already-verified center-pivot behavior, and the High-impact technical debt item from 2026-10-09 remains resolved.
  • The Composite Address Controls and Mixed-Content Text epic is now Done outright. The first Address Control is usable end-to-end: create, manage lines, edit per-line mixed content, move/resize as a group, save/reopen XML, and render directly through the CLI.
  • No new product backlog item is required from the review. Two scope notes remain intentionally documented rather than treated as defects: Address Control width is not yet render-time wrapping/clipping, and whole-control rotation remains an out-of-scope future candidate.
  • Scrum/process observation to carry into retrospective: the Sprint 5 GUI-verification reliability action paid off. The full-form smoke caught a real dock-order bug hiding the properties panel before review, and the bug was fixed within the sprint instead of escaping.

Sprint 6 Retrospective outcome (2026-10-12)

  • scrum-master ran the retrospective (backlog/sprints/sprint-6-retrospective.md). Confirmed full follow-through on all three Sprint 5 action items — the fifth clean full-follow-through sprint in a row — with the GUI-verification action paying off directly by catching the hidden properties-panel dock-order bug before review.
  • Sprint 7 planning carry-ins: include an actual built-form smoke for any GUI story touching form layout/properties/toolbar actions; keep product-risk-first ordering during planning; and size future composite-element stories from cross-layer code inspection, not visible UI alone.
  • No kit-level edit proposed. The full-form-smoke insight is team verification practice and fits the existing Definition of Done rather than exposing a gap in the Scrum kit.

Sprint 5 Review outcome (2026-10-09)

  • Both committed Sprint 5 stories (15/15 points) are Done; each is verified against its acceptance criteria with real, non-simulated evidence, recorded story-by-story in backlog/epics/08_composite_address_controls.md (“Mix static text and CSV fields”) and backlog/epics/05_cli_rendering_engine_and_debenu_integration.md (“Harden production configuration delivery”). Full daily detail: backlog/sprints/sprint-5.md.
  • Sprint goal met in full. The mixed-content capability is the largest single story this team has delivered (13 points), and its highest-risk acceptance criterion (existing templates must render identically) was proven, not assumed — dev-team built the actual pre-Sprint-5 CLI binary from a git worktree and byte-compared real output, controlling for Debenu's own internal nondeterminism to isolate a genuine zero-regression result. The CLI Rendering Engine and Debenu Integration epic is now Done outright (6 of 6 stories — note: backlog.md's table previously said “5 of 7,” a stale count corrected this review to the epic's actual 6 total stories).
  • Product-owner confirmed dev-team's production-configuration decision (keep the existing env-var-then-key.txt mechanism unchanged) rather than treating it as pre-approved — the reasoning holds up independently given this product's single-workstation, non-technical-operator deployment model and the absence of any packaging story yet to justify a stronger mechanism. Flagging this decision for the human user's awareness specifically, since it's a licensing/deployment judgment call, not a pure engineering one, and remains revisitable if the distribution model changes.
  • No new technical debt logged this sprint. One disclosed, accepted trade-off (not a defect): the bracket-syntax {Column Name} editing convention will mis-parse a literal {...} in static text not meant as a field token — documented in TEMPLATE_FORMAT.md as a known limitation of the faster-to-deliver approach, not a hidden gap.
  • “Group lines into a single, movable Address Control” (13 pts, epic 8) is now unblocked — its dependency (“Mix static text and CSV fields”) is Done — and is the clean next pull for Sprint 6, per dev-team's own sizing-note recommendation against combining both epic-08 stories in one sprint.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md).

Sprint 5 planning outcome (2026-10-05)

  • scrum-master facilitated. Velocity range holds at 18-20 points, now off four data points (20, 19, 18, 18) — the last two sprints both landed exactly on their commitment. Committed 15 points, deliberately below the low end of the range: “Mix static text and CSV fields within a single text element” (13 pts, epic 8 — this team's largest single story to date) plus “Harden production configuration delivery for CLI runtime settings” (2 pts, epic 5). Extra buffer beyond the usual ~10% grooming reserve is intentional given the 13-point story's real structural risk (a breaking model change, no reusable UI pattern to copy). Full plan: backlog/sprints/sprint-5.md.
  • Not committed (capacity + dependency discipline): “Group lines into a single, movable Address Control” (13 pts, epic 8) — hard-depends on this sprint's mixed-content story landing first, and dev-team's own sizing note recommended against committing both epic-08 stories in the same sprint. Clean pull for Sprint 6.

Sprint 4 planning outcome (2026-09-28)

  • scrum-master facilitated. Velocity range tightened to 18-20 points (three data points: 20, 19, 18 completed in Sprints 1-3, the last with zero scope change). Committed 18 points at the low end of the range rather than the 20-point ceiling, per the standing “reserve ~10% for grooming” guidance: “Collapse blank optional address lines consistently” (5 pts, epic 3 — completes that epic outright), plus the full rotation chain from epic 2 — “Set a rotation angle for text and dynamic field elements” (8 pts) then “Rotate elements by dragging a handle on the canvas” (5 pts, depends on the former). Full plan: backlog/sprints/sprint-4.md.
  • Not committed (capacity discipline, explicit stretch item): “Harden production configuration delivery for CLI runtime settings” (2 pts) — still not urgent per product-owner's standing note on that story; pull only if the committed three finish early.

Sprint 7 planning outcome (2026-10-19)

  • scrum-master facilitated Sprint 7 planning. Capacity signal now has six data points (Sprints 1-6: 20, 19, 18, 18, 15, 18), a stable 18-20 point range; Sprint 6 landed exactly on an 18-point commitment with zero scope change. Committed 18 points: the full epic 4 Ready pair — “Render an accurate, record-specific preview of the current template” (8 pts) then “Jump to a specific record number” (5 pts, depends on the former) — plus one epic 6 stretch item, “Snap elements to grid and guides” (5 pts, no dependencies). Full plan: backlog/sprints/sprint-7.md.
  • Planning reasoning: the epic 4 pair alone (13 pts) was clearly under the proven range, so a second pull was weighed rather than left uncommitted. “Snap elements to grid and guides” was chosen over the other two Ready epic 6 candidates specifically because it is self-contained (no CLI/XML surface, no dependency on any other story) and needs only a canvas-only smoke per its own story notes — the lowest-risk way to reach 18 points. “Select multiple elements at once on the canvas” + “Align and distribute multiple elements” (10 pts combined) were deliberately kept as a pair rather than split across sprints (splitting them would repeat the anti-pattern epic 8 avoided in Sprints 5-6, since the prerequisite alone delivers little standalone operator value); together with the epic 4 pair they would total 23 points, over range. “Undo and redo layout changes” (13 pts) was left uncommitted per its own sizing note, which recommends against pairing this backlog's highest-uncertainty estimate with another large/novel story in the same sprint (the epic 4 preview story is itself non-trivial) and recommends a short document-cloning feasibility check before it is committed to any sprint.
  • Product-risk-first ordering (Sprint 6 retrospective carry-in) was applied to sequencing: the epic 4 pair is pulled first because it closes a known-shape defect class (divergent per-record text-resolution paths) that already caused the 2026-10-09 rotation-positioning defect; “Snap elements to grid and guides” is pulled last as the lowest-risk item to flag first if the sprint runs short on time.
  • Verified rather than assumed (Sprint 6 retrospective carry-in): both committed epic 4 and epic 6 stories’ 2026-10-16 sizing notes already cite specific real code paths inspected (TemplateCanvasControl, AddressBlockPreviewCalculator, RenderEngine, TemplateDesignerForm for the preview story; CanvasElementEditor.DragTo/BeginDrag/EndDrag and TemplateCanvasControl's paint routine for snap-to-grid), so no re-sizing was needed at planning time.
  • Sprint 6 retrospective carry-in on built-form smokes is written into each committed story's tasks: both epic 4 stories require a full built-form smoke (they touch TemplateDesignerForm layout); “Snap elements to grid and guides” requires only a canvas-only smoke, per that story's own scope note (no form-layout/properties-panel/toolbar surface touched).
  • Not committed: the epic 6 multi-select/align pair (10 pts) and undo/redo (13 pts) — both clean candidates for Sprint 8 planning, per the reasoning above. “Warn on text overflow before render” (epic 4) remains Not Ready, still blocked on the open product question for the human product owner about what “overflow” means. No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior) — still non-blocking for this sprint's committed items.

Sprint 7 backlog refinement outcome (2026-10-16)

  • Per state.md's carried-in instruction, product-owner re-verified epic 4's “Ready” label (index previously said Ready) rather than trusting it, since it had not been touched since the 2026-09-04 onboarding refinement — before rotation (Sprint 4), mixed content (Sprint 5), and the Address Control (Sprint 6) all shipped.
  • Real code inspection finding, epic 4: TemplateCanvasControl draws every standalone text element from element.DisplayText (the raw bracket-token string), never a per-record resolved value — “Preview the current layout with a selected CSV record” does not exist yet except for the one already-shipped Address Control preview path. The one “sample record” in use today is hardcoded to the CSV's first loaded row via the bounded, 20-row CsvPreviewLoader; there is no operator record selection anywhere in the app. This means the original 5-point estimate for that story was stale and materially understated. Rewrote the story with explicit ACs (reuse one shared resolution routine across CLI render/canvas/preview to avoid a third divergent implementation — the exact class of drift that caused the 2026-10-09 rotation defect — plus rotation-pivot and Address Control parity, plus a built-form smoke per the Sprint 6 retrospective action) and re-sized it at 8 points (epics/04_live_preview_and_record_navigation.md).
  • Also found, epic 4: the CLI's CsvRecordSource is already a proven forward-only streaming reader at 100k+-record scale, so “Jump to a specific record number” can reuse it via skip/take without new indexing infrastructure — de-risking that story, but it still needs to move off the bounded 20-row loader, so it was re-sized from 3 to 5 points. “Warn on text overflow before render” could not be re-sized or marked Ready at all: no template element has any bounding-width concept today (TextElementLayout has no Width property; AddressControlLayout.Width is an unenforced resize handle only), so “overflow” is currently undefined behavior. This is logged as an open question for the human product owner in the epic file rather than decided unilaterally — see epic 4's Story 3 conversation notes for the two concrete options.
  • Real code inspection finding, epic 6: its three stories were still onboarding-era placeholders (no Conversation notes, unconfirmed T-shirt sizes). Rewrote all three as full Card/Conversation/Confirmation stories. Found no multi-select exists anywhere in the app (CanvasElementEditor/TemplateCanvasControl each hold at most one selected item), so “Align and distribute multiple elements” was split into a new prerequisite, “Select multiple elements at once on the canvas” (5 pts), plus the alignment/distribution story itself (5 pts, depends on the prerequisite). Found no undo/redo infrastructure of any kind exists; sized “Undo and redo layout changes” at 13 points and flagged it explicitly as the highest-uncertainty estimate in the backlog (no prior story of this shape to size against), with a design option noted for dev-team to evaluate (coarse-grained whole-document snapshotting, reusing the existing TemplateLayoutXmlSerializer-proven document model, instead of a fine-grained command pattern per mutation type) rather than mandated. “Snap elements to grid and guides” stayed contained (5 pts) — no multi-select or undo dependency. All four stories pass the Definition of Ready.
  • Epic 7: confirmed both open impediments in logs/impediment_log.md (template asset path strategy; UNC timeout/retry behavior) are still Open, unresolved since 2026-09-04. Per the “delay firm decisions to the last responsible moment” principle applied at every prior review, epic 7 remains non-blocking for Sprint 7 — epic 6 (now 4 fully-Ready stories) still sits ahead of it in priority order, and epic 4's core preview story is the clear highest-priority pull regardless. Did not resolve the impediments this session; recommend revisiting only once epic 6 is substantially spent and epic 7 nears the top.
  • No reordering of the epic index was warranted. Epic 4 stays 5th and epic 6 stays 6th — the code-inspection findings changed sizing and scope, not relative priority. Product-risk-first reasoning (Sprint 6 retrospective carry-in) actually reinforces keeping epic 4 first: its core preview story exists specifically to prevent the same canvas/render-drift defect class already seen once in production (the 2026-10-09 rotation-positioning bug).
  • Recommended Sprint 7 candidate: “Render an accurate, record-specific preview of the current template” (8 pts) then “Jump to a specific record number” (5 pts) — epic 4's full Ready slice, 13 points, sequenced together since the second hard-depends on the first. This is both next in backlog order and the highest real product risk currently in the Ready set (a known-shape defect class, not a hypothetical). As an optional stretch item to round out capacity toward the team's proven 18-20 point range, “Snap elements to grid and guides” (epic 6, 5 pts) has no dependency on anything else and is a clean, low-risk pull if the core 13 points finish early — this is a recommendation for scrum-master/dev-team at planning, not a commitment.
  • Open question for the human product owner: epic 4's “Warn on text overflow before render” needs a decision on what “overflow” means before it can be written with testable acceptance criteria or sized (page-edge overflow only, vs. adding a real enforced width/wrap boundary to elements first). Not blocking for Sprint 7 either way, since neither recommended candidate depends on it.

Sprint 7 Review outcome (2026-10-19)

  • All 3 committed Sprint 7 stories (18/18 points) are Done; each is verified against its acceptance criteria with real evidence, recorded story-by-story in backlog/epics/04_live_preview_and_record_navigation.md (the epic 4 pair) and backlog/epics/06_layout_efficiency_and_operator_tooling.md (grid/guide snapping). Full daily detail: backlog/sprints/sprint-7.md.
  • Sprint goal met in full. Verification was independent, not a rubber-stamp of dev-team's own report: read TextResolver.cs, RotationPivotCalculator.cs, TemplatePreviewBuilder.cs/PreviewTextDraw.cs, TemplatePreviewControl.cs, and TemplateDesignerForm.cs's wiring directly, and traced every auto-refresh path (canvas ElementsChanged_previewControl.Invalidate() on drag/rotate/content-commit/rebind/X-Y edits, plus template open) to confirm the “refreshes after a layout edit, a field remapping, or a different record” acceptance criterion is actually wired, not just claimed. Confirmed TemplatePreviewBuilderTests genuinely mirrors RenderEngineTests’ scenario shapes (collapse, mixed content, both rotation-pivot rules, Address Control expansion, z-order, unknown-column failure) rather than testing something narrower. Confirmed CsvRecordNavigator is a true full-file forward-only reader (no bounded 20-row shortcut) via both its source and CsvRecordNavigatorTests’ record-25-of-30 case. Confirmed GridSnapper/CanvasElementEditor.DragTo/TemplateCanvasControl snap continuously mid-gesture (not only on release) via CanvasElementEditorTests’ explicit mid-drag assertion, and confirmed by grep that TemplateLayoutXmlSerializer has no grid/snap-related change — the “no template format change” acceptance criterion holds.
  • Test-count plausibility check performed in place of re-running the suite: this review session has no shell/build tool access, so dotnet test was not re-run directly. Instead, independently counted [Fact]/[Theory]/[InlineData] attributes across every test file in both EnvelopeRenderer.Cli.Tests and EnvelopeRenderer.Desktop.Tests: 91 [Fact] + 10 [InlineData] rows = 101 CLI, and 219 [Fact] + 80 [InlineData] rows = 299 desktop, summing to exactly 400 — matching dev-team's reported 400/400 exactly, not approximately. This is strong circumstantial confirmation the reported count is real, though it does not substitute for an actual test run; recommend whoever next has shell access (dev-team or scrum-master) do a real dotnet test pass as routine hygiene before the next sprint starts.
  • One caveat on evidence depth, disclosed rather than smoothed over: dev-team's live built-.exe verification (reflection harness driving the real assemblies, screenshots) was not independently re-run this review — this session had no way to build or launch the desktop app. The claims were cross-checked against the underlying code instead (e.g., the fixed-anchor rotation pivot claim is directly supported by RotationPivotCalculator.Compute's implementation and its own unit tests proving two different measured widths yield the same anchor), which is solid but is code-level verification, not a re-observed screenshot. Flagging this as a review-process limitation for the human product owner's awareness, not a defect in the sprint's delivery.
  • Technical debt reviewed, confirmed reasonable to leave open: the 2026-10-19 Address Control line-overlap-at-small-font-sizes entry in logs/technical_debt_log.md is confirmed Low-impact and non-blocking on independent review — it is cosmetic (GDI+ MeasureString approximation), confined to the canvas/preview design-time surfaces, pre-existing since Sprint 6 (not a Sprint 7 regression, just newly re-observed because a second surface now shares the same measurement approach), and does not touch DebenuPdfRenderer/RenderEngine, the actual PDF render path. No pushback on dev-team's logging of it; agree it should stay open rather than block this sprint.
  • Explicit scope note: “Warn on text overflow before render” (epic 4) was not part of this sprint and remains Not Ready — still an open product question for the human product owner (what “overflow” means with no element having an enforced bounding width today). Not touched or marked Done here.
  • Epic 4 (Live Preview and Record Navigation) moves from “Partially Ready” to In Progress (2 of 3 stories Done); epic 6 (Layout Efficiency and Operator Tooling) moves from “Ready” to In Progress (1 of 4 stories Done — “Snap elements to grid and guides”). “Select multiple elements at once on the canvas” + “Align and distribute multiple elements” (10 pts combined, dependent pair) and “Undo and redo layout changes” (13 pts, highest-uncertainty estimate in the backlog) remain the natural next pulls for Sprint 8, per the Sprint 7 planning outcome's own reasoning.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking for likely Sprint 8 candidates (neither epic 6 story nor epic 7 touches image assets or network paths).

New stories added during backlog refinement (2026-10-19) — Address Control whole-unit rotation

  • The human product owner confirmed the “whole-control rotation remains out of scope” note from Sprint 6 Review (above) is now wanted. product-owner reopened epics/08_composite_address_controls.md from Done and wrote two dependent stories: “Rotate the whole Address Control as a single unit” (8 pts) and “Rotate the whole Address Control by dragging a handle on the canvas” (5 pts, depends on the former) — deliberately mirroring the exact two-story split this team already used for the original standalone-element rotation feature (epics/02, 2026-09-22).
  • Confirmed by code inspection before writing either story, not assumed from the parent request: unlike the standalone dynamic-text rotation-positioning defect fixed in Sprint 6 (whose bounding-box pivot was measured from each record's own resolved text width), the Address Control's box geometry (AddressControlLayout/TemplateAddressControl's Width/Height) is entirely author-set — Width is an explicit resize-handle value and Height derives only from each line's own authored font size/line-spacing, never from resolved text (TemplateCanvasControl.DrawAddressControl draws the box from control.X/Y/Width/Height alone). So rotating the whole control around its own box center is record-stable everywhere (canvas, Sprint 7 preview, real CLI render) without the anchor-pivot workaround the standalone defect fix needed — recorded as a deliberate scope note in the first story so future readers don't assume the two rotation features share that complexity. A second, real correctness requirement was also found and written into the story: the pivot must be computed from the control's authored geometry, not from any record's AddressLineCollapser-shifted line positions, so rotation stays stable across records that differ only in whether a blank line collapses.
  • dev-team sized both stories at 8 and 5 points respectively (13 total, matching the original standalone-element rotation pair's total) after inspecting RenderEngine.BuildAddressControlDraws, TemplatePreviewBuilder's address-control counterpart, TemplateCanvasControl.DrawAddressControl/HitTestAddressControl, CanvasElementEditor's existing per-element rotation machinery (HandlePosition/HitTestHandle/RotateDragTo/RotatePointAroundPivot/IsPointInRotatedBounds), and TemplateDesignerForm's already-present-but-disabled angle input for an Address Control selection. A genuine, code-confirmed scope reduction versus the original single-element rotation story: DebenuPdfRenderer needs no changes at all here, since the existing fixed-pivot rotation path added by the Sprint 6 defect fix already covers a rotated line once it's handed an already-correct anchor point — the new work is upstream rigid-group-rotation math (rotating each line's anchor around the control's box center before the existing draw call), needed independently on the CLI and desktop sides per this project's established split. Both stories pass the Definition of Ready and are marked Ready.
  • Not yet placed into a sprint — left for Sprint 8 planning (or an immediate same-session pull), per the human product owner's own call.

Sprint 8 backlog refinement outcome (2026-10-19)

(Note on numbering: epic references below use each epic's fixed file-based number, e.g. “epic 8” always means epics/08_composite_address_controls.md and “epic 6” always means epics/06_layout_efficiency_and_operator_tooling.md, matching every prior dated note in this file — this is independent of the reorderable “Order” column position in the table above.)

  • product-owner ran Sprint 8 backlog refinement after the human product owner confirmed the post-Sprint-7-retrospective pause point with “continue.” Verified every claim in the incoming summary against the real files rather than trusting it: backlog/backlog.md's epic table, epics/04_live_preview_and_record_navigation.md, epics/06_layout_efficiency_and_operator_tooling.md, epics/08_composite_address_controls.md, and logs/impediment_log.md all matched — no stale statuses found this time (contrast the 2026-10-16 refinement, which did find one).
  • Applied the three Sprint 7 retrospective carry-ins directly to the backlog rather than only noting them:
    1. Re-checked “Align and distribute multiple elements” (epic 6) against the built-form-vs-canvas-only smoke rule per the carry-in's own concern — found its Confirmation section had no built-form-smoke AC at all, unlike its prerequisite story. Added an explicit AC and Conversation note requiring a full built-form smoke if this story adds any new toolbar/menu affordance to trigger alignment/distribution (a real, plausible gap, not a hypothetical one — no such trigger exists today).
    2. Added a paired Conversation note to the same story: if executed immediately after its prerequisite in the same sprint, capture a fresh full-form screenshot rather than reusing the prerequisite's, directly restating the exact reuse mistake named in the Sprint 7 retrospective so it isn't repeated.
    3. The third carry-in (disclose lack of shell/build access and arrange an independent cross-check) is a review-session process practice, not something to encode into a story — left as-is, to be applied at the next Sprint Review that needs it.
  • Feasibility check performed on “Undo and redo layout changes” (13 points, epic 6), per this refinement's own instruction to do the check now rather than defer it again: read TemplateLayoutDocument.cs, TemplateLayoutXmlSerializer.cs, AddressControlLayout.cs, and TextElementLayout.cs directly. Confirmed the document model is a simple, flat, cleanly-cloneable object graph (two plain lists, no circular references, no UI-bound fields) and that a full serialize/deserialize round-trip already exists and is proven (TemplateLayoutXmlSerializer.Save/TryLoad, used for save/reopen) — a snapshot-based undo/redo design can reuse this exact path in-memory rather than inventing new clone logic. This is a real, code-inspection-backed de-risking of the 13-point estimate's core assumption, not a rubber-stamp; full reasoning recorded in epics/06_layout_efficiency_and_operator_tooling.md. Residual uncertainty is now isolated to the UI/mutation-wiring side (no prior story of this shape to size against), not the data-model side — this story can be treated as having a reasonably firm 13-point estimate for planning purposes, though still this backlog's largest single uncertainty and still not recommended for pairing with another large/novel story in the same sprint.
  • No re-litigation of already-correctly-sized Ready items, per this refinement's own instruction: the two Address Control whole-unit-rotation stories (epic 8, 8+5=13 pts) and the epic 6 multi-select/align pair (5+5=10 pts) were re-read in full and found sound on inspection — no rework needed.
  • Epic index reordered. Composite Address Controls and Mixed-Content Text (epic 8, formerly Order position 8) moves to Order position 6, ahead of Layout Efficiency and Operator Tooling (epic 6, now Order position 7) and Dynamic and Network Image Handling (epic 7, now Order position 8, unchanged in relative terms — still last, still Not Started). Reasoning: epic 8's two new Ready stories are a direct, explicit, recent human-product-owner request (“the user explicitly chose to queue this for Sprint 8 planning rather than implement it ad hoc,” per state.md) reversing a scope decision the same human product owner made only one sprint ago (Sprint 6 Review's “whole-control rotation remains out of scope” note) — a stronger, more specific priority signal than epic 6's pair, which is next in line by ordinary dependency/capacity sequencing but was not itself singled out as newly urgent by the human product owner. This is a recommendation, presented with reasoning, not a unilateral final call — the human product owner can leave the pair in either relative order. No change to epic 7 (images)‘s own relative position: both impediments in logs/impediment_log.md remain Open since 2026-09-04, and epic 7 still sits behind both epics now ahead of it, so it remains non-blocking.
  • Definition of Ready exit criteria checked: three fully Ready items/pairs are available — epic 8's rotation pair (13 pts), epic 6's multi-select/align pair (10 pts), and epic 6's undo/redo story (13 pts) — 36 points total, enough for 1-2 sprints per process/01_backlog_refinement.md's exit criteria. No Ready item is missing acceptance criteria or a size estimate (undo/redo's estimate is now feasibility-confirmed rather than merely asserted).
  • Recommended Sprint 8 candidate: epic 8's whole-control-rotation pair (“Rotate the whole Address Control as a single unit,” 8 pts, then “...by dragging a handle on the canvas,” 5 pts) as the definite first pull — 13 points, directly requested by the human product owner, and confirmed low technical risk (needs zero DebenuPdfRenderer changes, per its own sizing note). This alone sits below this team's proven 18-20 point range (six data points: 20, 19, 18, 18, 15, 18), so a genuine capacity trade-off exists for scrum-master/dev-team to weigh at planning: pairing it with epic 6's multi-select/align pair (10 pts) would total 23 points, a new high above the proven range and not a number this team has hit before, versus taking the rotation pair alone (13 pts, a new low, undercommitting relative to proven capacity) and leaving the multi-select/align pair as a clean Sprint 9 pull. Not recommending any combination that splits either hard-dependent pair mid-sprint, consistent with this team's established practice (Sprint 4's rotation chain, Sprint 7's preview pair). The undo/redo story (13 pts) is not recommended for Sprint 8 regardless of which option above is chosen — pairing it with the rotation pair (13+13=26) or the multi-select/align pair (13+10=23) both exceed anything this team has attempted, and its own sizing note already recommends against pairing it with another large/novel story.
  • Open question restated for the human product owner, not re-decided here: “Warn on text overflow before render” (epic 4, Live Preview and Record Navigation) has now been parked unresolved since 2026-10-16 across two backlog refinements. It remains non-blocking for every Sprint 8 candidate above, so it is not holding anything up — but it is the oldest open item in this backlog and worth a direct decision from the human product owner whenever convenient (does “overflow” mean page-edge overflow only, or does it require a new enforced per-element/control width boundary first).
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — confirmed still Open, unresolved since 2026-09-04, and still non-blocking for every Sprint 8 candidate named above.

Sprint 8 Review outcome (2026-10-26)

  • Both committed Sprint 8 stories (13/13 points) are Done; each is verified against its acceptance criteria with real evidence, recorded story-by-story in backlog/epics/08_composite_address_controls.md. Full daily detail: backlog/sprints/sprint-8.md.
  • Sprint goal met in full, directly delivering the human product owner's Sprint 6 Review reversal (“whole-control rotation remains out of scope”) — an Address Control can now be rotated as a rigid unit via the properties panel or a canvas drag handle, staying record-stable and visually consistent across the editing canvas, the Sprint 7 preview panel, and the real CLI-rendered PDF. Verification was independent, not a rubber-stamp: re-ran the full test suite directly (dotnet test, 433/433 passing — 326 desktop, 107 CLI, exactly matching dev-team's reported count) and read the actual persistence code (TemplateLayoutXmlSerializer.CreateAddressControl, TemplateXmlParser.ParseAddressControl) to confirm the new angle attribute round-trips with a 0 default on both the CLI and desktop sides independently. Confirmed the claimed new unit-tested classes genuinely exist (PointRotation.cs/PointRotationTests.cs, AddressControlRotateHandle.cs/AddressControlRotateHandleTests.cs) and that AddressControlLayout.BoxCenter is a pure function of authored geometry with no record input, supporting the pivot-stability acceptance criterion.
  • One caveat on evidence depth, disclosed rather than smoothed over: this review session did not rebuild or re-drive the actual desktop .exe itself, so dev-team's live built-form screenshot evidence (properties-panel wiring, canvas/preview/PDF visual parity, rotated hit-testing, live drag-to-rotate) was cross-checked against the underlying code rather than re-observed firsthand. Flagging this as a review-process limitation, consistent with how the Sprint 7 review disclosed the same kind of gap, not a defect in the sprint's delivery.
  • Technical debt reviewed, confirmed reasonable to leave open: the 2026-10-26 entry in logs/technical_debt_log.md (pre-existing Sprint 6 Address Control hit-test/move/resize logic remains WinForms-only and untestable, unlike this sprint's own newly-extracted, unit-tested rotation math) is confirmed Low-impact and non-blocking — a testability/maintainability gap with no known behavioral defect, and a proportional, in-scope call not to retroactively refactor already-shipped Sprint 6 code as part of this sprint's stories.
  • The Composite Address Controls and Mixed-Content Text epic is now Done outright (4 of 4 stories). No new product backlog item is required from this review.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking. “Complete the first text-only operator workflow” (epic 1, 5 pts) remains flagged from Sprint 8 planning as needing product-owner re-verification of its stale “Ready” label before ever being pulled — not resolved in this review, carried forward as-is.

New stories added during backlog refinement (2026-10-26) — adjustable width/height with text wrapping

  • Same-day, outside-formal-ceremony follow-up to the two live-build fixes above: the user asked for a way to make element/control boxes longer. product-owner clarified scope directly with the user across two rounds of questions (which controls; wrap vs. clip; which dimensions) before writing anything down. The answers — both standalone elements and Address Control; wrap text within the box but warn when it's happening; both width and height, with height acting as a hard clip boundary once wrapped content exceeds it — directly resolve the “Warn on text overflow before render” story's blocking open question, parked unresolved since the 2026-10-16 refinement across three separate refinement sessions (the single oldest open item in this backlog).
  • Wrote two new dependent stories in epics/04_live_preview_and_record_navigation.md: “Add an adjustable width and height with text wrapping to static and dynamic text elements” (the foundational, from-zero case — standalone elements have no width/height concept at all today) and “Add an adjustable width and height with text wrapping to Address Control lines” (extends the first story's engine to the composite control, whose Width exists today as a resize-handle- only value with no render effect, and whose Height doesn't exist as an independent value at all). This mirrors this team's own established general-capability-then-composite-control sequencing (Sprint 5 mixed content -> Sprint 6 Address Control).
  • Material de-risking finding, confirmed by code inspection, not assumed: grepped the vendor Debenu interop file before writing either story and found native wrap/box-drawing primitives this product has never called — DPLDrawWrappedText, DPLDrawTextBox, DPLGetWrappedTextHeight/ DPLGetWrappedTextLineCount (directly useful for the “detect when wrapping/clipping is happening” requirement) — meaning this feature very likely does not require inventing a from-scratch word-wrap algorithm. Flagged in the epic for dev-team to confirm the exact semantics empirically during sizing, the same way the original rotation story empirically confirmed DrawRotatedText's anchor behavior before committing to a design.
  • Updated “Warn on text overflow before render” (previously Not Ready, blocked on an undefined product question) to reflect the resolved question and re-scoped it as the full-CSV, all-records pre-render validation pass sitting on top of the new wrap/clip engine — distinct from the two new stories’ own live, single-sample-record canvas/preview indicator. It now depends on both new stories rather than being blocked on a product decision.
  • Not sized yet — flagged for dev-team at the next backlog refinement/Sprint 9 planning. Both new stories are explicitly marked “Not Ready (needs dev-team sizing)” in the epic file per the Definition of Ready's “rough size estimate provided by the Development Team” requirement; the standalone-element story is flagged as likely comparable to or larger than the 13-point “Mix static text and CSV fields” story given it touches all three render surfaces plus a wholly new geometry concept, with a possible further split recommended at sizing time if it doesn't fit one sprint even alone.

Sprint 10 planning outcome (2026-10-27)

scrum-master facilitated with product-owner/dev-team input, immediately following Sprint 10 backlog refinement above.

  • Capacity signal now has nine data points (Sprints 1-9: 20, 19, 18, 18, 15, 18, 18, 13, 13). The 18-20 range remains this team's proven, repeatable velocity; 15 and both 13s are documented, deliberate under-commits (Sprint 5's large/risky story, Sprint 8's fresh-priority story, Sprint 9's fresh-priority story), not capacity misses.
  • Committed 13 points: “Add a live wrap/clip indicator for text elements” (3 pts, epic 4) paired with epic 6's multi-select (“Select multiple elements at once on the canvas,” 5 pts) + align/distribute (“Align and distribute multiple elements,” 5 pts) dependent pair, pulled whole per this team's established practice. Full plan: backlog/sprints/sprint-10.md.
  • Reasoning for finally pulling epic 6's pair now, explicit rather than default: it has been Ready and waiting since Sprint 7 — deferred at Sprint 8 planning (Address Control rotation was a fresher, more urgent human request) and again at Sprint 9 planning (the wrap/clip core story was both fresher and ahead in table order). Neither reason applies with the same force this sprint: the wrap/clip chain's own next step is now only 3 points, leaving real spare capacity, and no new, fresher request has displaced epic 6 a third time. Continuing to defer a Ready, sized, 3-sprint-old pair without a stated reason would itself become the anti-pattern this team's own practice exists to avoid.
  • Why pairing (not a concern the “two large/novel stories” rule blocks): the established caution is about stacking two large, first-of-its-kind, architecturally risky stories in one sprint (e.g., Sprint 8's rejected rotation-drag-handle + multi-select combination). Here, only one side of the pairing — multi-select's new selection model — carries that character; the indicator story is small, additive, and touches no shared foundational state (it only reads existing box/rotation data to decide what to draw). This is a small-plus-one-large combination, not two-large, so the rule's concern does not apply.
  • Checked for anything else to round out capacity — nothing else fits. “...Address Control lines” (8 pts) depends on the indicator landing first and reusing its design, so pulling both in the same sprint would mean building the indicator and then immediately extending a still-warm design under time pressure rather than letting it settle — deferred to Sprint 11. “Undo and redo layout changes” (13 pts) alone would total 16 with the indicator, a reasonable combination in principle, but was not chosen over the multi-select/align pair given the pair's own 3-sprint-old deferral making it the more overdue commitment. “Complete the first text-only operator workflow” (5 pts) remains explicitly excluded pending its own stale-label re-verification.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking for this sprint's committed items.

Sprint 10 backlog refinement outcome (2026-10-27)

product-owner ran Sprint 10 backlog refinement after the human product owner confirmed the post-Sprint-9-retrospective pause point with “continue,” folding in the Sprint 9 retrospective's own flagged action item directly rather than deferring it.

  • Re-confirmed/re-sized “Support rotated wrapped text and a live wrap/clip indicator for text elements” as the retrospective asked, via real code inspection and a real, licensed end-to-end test rather than assumption. Confirmed DebenuPdfRenderer.AddPage's box branch already calls DrawRotatedTextBox for any rotated boxed draw, and both TemplateCanvasControl.DrawElement's and TemplatePreviewControl.DrawItem's box-mode draw already run inside the same rotation transform every other element uses — rotation composition was a byproduct of Sprint 9's own implementation shape, not deferred work as the original estimate assumed. Proved this with a real template (20°-rotated, 150x80pt boxed static element) rendered through the actual built EnvelopeRenderer.Cli.exe, visually confirming correct wrapped-and-rotated output, plus a new permanent regression test (DebenuPdfRendererWrapTests.AddPage_WithLicenseKey_RotatedBox_...).
  • Renamed and re-sized the story: “Support rotated wrapped text and a live wrap/clip indicator for text elements” (8 pts) becomes “Add a live wrap/clip indicator for text elements” (3 pts) — its former rotation-composition ACs are already satisfied, so all that remains is the passive visual indicator itself. Updated its dependency references in the Address Control wrap/clip story and “Warn on text overflow before render.” Full detail: epics/04_live_preview_and_record_navigation.md.
  • Real finding worth naming, not just the estimate change: verifying exact wrap/clip behavior under rotation via automated pixel-row counting turned out to be unreliable (a heavily-clipped rotated block can occupy more rasterized pixel rows than a taller, unclipped one, since rotation angle affects vertical footprint as much as line count does) — discovered while writing the new regression test, and documented directly in that test's own remarks so a future session doesn't rediscover the same dead end. The test was simplified to assert real content renders correctly rather than a specific row-count relationship; the stronger correctness evidence remains the direct screenshot inspection already performed.
  • No other Ready items needed re-verification. Epic 6's multi-select/align pair (10 pts) and undo/redo (13 pts) were already re-verified at Sprint 9's own refinement with no material change found; nothing has changed in that area since.
  • Recommended Sprint 10 candidate: “Add a live wrap/clip indicator for text elements” (3 pts) as a small, low-risk, self-contained pull — it has no dependency beyond Sprint 9's already-Done story. Given its small size, scrum-master/dev-team should weigh at planning whether to pair it with another Ready item to round out capacity, per this team's established practice of not leaving obviously-available capacity idle without a stated reason.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking. “Complete the first text-only operator workflow” (epic 1, 5 pts) remains flagged as needing re-verification before ever being pulled — not resolved in this refinement, carried forward as-is.

Sprint 9 Review outcome (2026-10-27)

  • The committed story (13/13 points) is Done; verified against all 6 acceptance criteria with real, non-simulated evidence, recorded in backlog/epics/04_live_preview_and_record_navigation.md. Full daily detail: backlog/sprints/sprint-9.md.
  • Sprint goal met in full. Independently re-ran the full test suite directly (dotnet test, 476/476 confirmed — 357 desktop, 119 CLI — not trusted from dev-team's report alone) and read the actual DebenuPdfRenderer.AddPage box-branch code, TemplateLayoutXmlSerializer/TemplateXmlParser's width/height persistence, and the new DebenuPdfRendererWrapTests/CanvasElementEditorTests directly to confirm the claims rather than rubber-stamping them.
  • Genuinely strong evidence quality, worth naming explicitly: this story's verification went beyond this project's usual bar — a real, licensed probe against the actual vendor DLL (not assumption) found and confirmed native Debenu wrap/box entry points before any implementation code was written, and the final live check was a true end-to-end pipeline run (a hand-written template through the real built EnvelopeRenderer.Cli.exe against the real 392-record sample CSV, with the resulting PDF rasterized and visually inspected showing genuine multi-line wrap and genuine height-based clipping) rather than a unit-level or mocked check.
  • Real de-risking finding accepted, not just noted: Debenu composes rotation and wrapping natively in one DrawRotatedTextBox call, meaning “Support rotated wrapped text and a live wrap/clip indicator for text elements” (8 pts, next in the epic 4 wrap/clip chain) is very likely already mostly satisfied by this story's shipped code for its rotation half. Confirmed this is correctly left un-re-sized rather than assumed complete — it still needs the live wrap/clip visual indicator (genuinely new UI) and an explicit confirming test for the rotated case. Agree with flagging it for re-sizing at the next backlog refinement rather than either silently keeping a stale 8-point estimate or unilaterally shrinking it without dev-team confirmation.
  • Process-improvement finding, carried to the retrospective, not corrected retroactively: the project's own Debenu license key (key.txt, repo root) was found this sprint after several earlier sprints’ reviews (Sprint 7's review; both DebenuPdfRendererIntegrationTests/ DebenuPdfRendererRotationTests) disclosed “no license key available locally” — those searches stopped one directory short of where both the resolver's own upward walk and the actual key live. This means some earlier evidence-depth caveats were avoidable tooling gaps, not genuine environment constraints. Not re-litigating those sprints’ already-accepted verification (they were independently corroborated by other means at the time per their own review records) — this is a forward-looking process fix, which scrum-master should weigh at the retrospective.
  • No new technical debt logged this sprint — the one open design question from planning (resize- handle coexistence) was resolved by a simpler design (one context-sensitive handle) than either option originally considered, not worked around.
  • Epic 4 (Live Preview and Record Navigation) status: 2 of its original 3 stories Done (Sprint 7) plus this new wrap/clip core story Done (Sprint 9); “Support rotated wrapped text...” (8 pts, flagged for re-sizing) and “...Address Control lines” (8 pts) remain Ready; “Warn on text overflow before render” (provisional 5 pts) remains Not Ready until both land.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking.

Sprint 9 backlog refinement outcome (2026-10-26)

product-owner ran Sprint 9 backlog refinement after the human product owner confirmed the post-Sprint-8-retrospective pause point with “continue,” folding in the Sprint 8 retrospective's action items (see state.md) and completing the sizing this session's own earlier ad hoc wrap/clip requirements-gathering left as “not yet sized.”

  • Re-verified epic 6's two Ready items (multi-select, undo/redo) before trusting them, since real code changed since their 2026-10-16/10-19 sizing (this session's own font-size resize handle and IsInteracting smoothness fix). No material change found — CanvasElementEditor.Selected is still a single reference, so multi-select's core scope is unchanged. One honest addition: “Undo and redo layout changes” should track the new font-size resize-drag as a mutation type alongside move/rotate — the same shape of mutation, not new complexity, so its 13-point estimate stands unchanged. Full detail: epics/06_layout_efficiency_and_operator_tooling.md's new 2026-10-26 re-verification note.
  • Sized the three new epic-4 wrap/clip stories via real code/vendor-API inspection, completing what this session's earlier ad hoc requirements-gathering left unsized:
    • “Add an adjustable width and height with text wrapping to static and dynamic text elements”: 13 points. Real de-risking finding: the vendor Debenu library already exposes native wrap/box-drawing entry points (DPLDrawWrappedText, DPLDrawTextBox, DPLGetWrappedTextHeight/LineCount) with confirmed parameter shapes, and GDI+ has an equivalent native rectangle-wrap capability for the canvas side — neither surface needs a hand-rolled word-wrap algorithm. Real risk found, not assumed: the desktop app and the CLI are two separate processes with no shared code path (confirmed no Debenu reference anywhere in EnvelopeRenderer.Desktop*), so canvas/preview wrap (GDI+) and the final PDF's wrap (Debenu) are two genuinely independent text engines that cannot be made to agree by construction the way every prior “shared TextResolver” fix could — scoped as an accepted, documented approximation (mirroring MeasureElement's existing language) rather than a blocking problem.
    • Found too large to respect as one story and split further at sizing time (the same fallback-split shape “Mix static text and CSV fields” itself once offered): “Support rotated wrapped text and a live wrap/clip indicator for text elements,” 8 points, carved out of the story above — rotation composed with wrapping has no precedent in this codebase, and the “warn this is happening” visual indicator is new UI, but both build directly on the core story's already-established model and native-call pattern rather than inventing a second one.
    • “Add an adjustable width and height with text wrapping to Address Control lines”: 8 points — reuses the two stories above's engine; real residual scope is the auto-computed-vs-explicit- Height interaction and per-line wrap allocation, comparable in shape to how “Group lines into a single, movable Address Control” reused Sprint 5's run model but still carried genuine new composite-element scope.
    • “Warn on text overflow before render” (already in the backlog, previously blocked on the now-resolved open question): provisional 5 points, sized by analogy to two already-Done patterns at this scale (RenderEngine's existing pre-flight validation pass; “Jump to a specific record number”‘s full-file scan) — explicitly flagged as provisional, to be re-confirmed once the three stories above's actual data model exists.
    • Total new scope: 34 points across four stories — larger than the entire 26-point Composite Address Controls epic, and realistically 2+ sprints on its own given this team's proven 18-20 point range. Full detail, findings, and Confirmation criteria for all four stories: epics/04_live_preview_and_record_navigation.md.
  • Epic ordering not changed, and this backlog's existing order already puts epic 4 ahead of epic 6 (position 5 vs. 7) — a standing order, not a new decision made here. The wrap/clip request is also a direct, fresh, explicit ask from the human product owner this same session, the same character of signal (“recent, explicit, human-directed”) that justified epic 8 jumping the queue for Sprint 8. Recommend the epic 4 wrap/clip chain as Sprint 9's first candidate on both grounds — standing table order and request freshness agree here, unlike epic 8's case where only the second reason applied. Epic 6's multi-select/align pair (10 pts) and undo/redo (13 pts) remain Ready and unchanged, next in line once the wrap/clip chain is underway.
  • Definition of Ready exit criteria checked: epic 6's multi-select/align pair (10 pts) and undo/redo (13 pts) remain Ready; three of the four new epic-4 stories are now Ready (13, 8, 8 pts); “Warn on text overflow before render” remains Not Ready (blocked on those three landing first, per its own dependency chain) despite carrying a provisional estimate. Combined Ready backlog: 52 points — comfortably enough for 2-3 sprints per this process's own exit criteria.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — confirmed still Open, unresolved since 2026-09-04, still non-blocking for every candidate above. “Complete the first text-only operator workflow” (epic 1, 5 pts) remains flagged from Sprint 8 planning as needing product-owner re-verification of its stale “Ready” label before ever being pulled — not resolved in this refinement, carried forward as-is.

Sprint 9 planning outcome (2026-10-26)

scrum-master facilitated with product-owner/dev-team input, immediately following Sprint 9 backlog refinement above.

  • Capacity signal now has eight data points (Sprints 1-8: 20, 19, 18, 18, 15, 18, 18, 13). The 18-20 point range from Sprints 1-4/6-7 still holds as the team's proven, repeatable velocity; both 15 (Sprint 5) and 13 (Sprint 8) are documented, deliberate under-commits around one large/risky or fresh story, not capacity misses — consistent with how Sprint 8 planning itself already treated Sprint 5's 15.
  • Committed 13 points: “Add an adjustable width and height with text wrapping to static and dynamic text elements” (epic 4) alone, as a deliberate under-commit — the same posture Sprint 5 and Sprint 8 each took around their own largest/riskiest or freshest story, not a default. Full plan: backlog/sprints/sprint-9.md.
  • Capacity reasoning, weighed explicitly: two larger combinations were considered and rejected. (a) Pulling this story's own dependent follow-up, “Support rotated wrapped text and a live wrap/clip indicator” (8 pts), in the same sprint would total 21 points — a new team-wide high (previous best 20) for a first-of-its-kind geometry/render capability with two real, cited unknowns (Debenu's exact wrap/box-call semantics, and how rotation composes with wrapping) still to be confirmed empirically. Unlike prior “pull the whole dependent pair” precedents (Sprint 4's and Sprint 8's rotation chains, Sprint 7's preview pair — each ≤13-18 points total), this story's own Conversation notes establish it is independently valuable and shippable without its follow-up (a resizable box that genuinely wraps/clips in the real PDF), so there is no “no independent value without its pair” pressure to pull both at once the way align/distribute has with multi-select. (b) Pulling epic 6's multi-select/align pair (10 pts) alongside this story (23 points total) was rejected for the same reason Sprint 8 rejected pairing multi-select with its own drag-handle story: stacking two large, genuinely novel, first-of-its-kind initiatives (a new multi-item selection model, and a new element-geometry/wrap-render model) in one sprint is exactly the risk profile this team has consistently avoided, and no external date/contractual pressure was cited to justify reaching for an unproven new high instead.
  • Checked for a smaller item to round out capacity — found none that cleanly fits, the same conclusion Sprint 8 planning reached for the identical reason: epic 6's multi-select cannot be pulled alone without its align/distribute pair per this team's own established “pull a hard-dependent pair whole or not at all” practice (multi-select's own card frames it as valuable standalone, but the team's precedent for this specific pair has been to sequence them together), and “Complete the first text-only operator workflow” (epic 1, 5 pts) remains explicitly flagged as a stale label needing re-verification before ever being pulled blind.
  • Sequencing recommendation for the epic 4 wrap/clip chain beyond Sprint 9: “Support rotated wrapped text and a live wrap/clip indicator” (8 pts) is the natural next pull once this sprint's story lands, then “Add an adjustable width and height with text wrapping to Address Control lines” (8 pts). Epic 6's multi-select/align pair (10 pts) and undo/redo (13 pts) remain queued and unchanged, available whenever a sprint's planning session chooses them over continuing the wrap/clip chain — no additional urgency signal has been given for either over the other.

Sprint 8 planning outcome (2026-10-26)

  • scrum-master facilitated with product-owner/dev-team input. Capacity signal now has seven data points (Sprints 1-7: 20, 19, 18, 18, 15, 18, 18), a stable 18-20 point range.
  • Committed 13 points: the full epic 8 whole-Address-Control-rotation pair — “Rotate the whole Address Control as a single unit” (8 pts) then “...by dragging a handle on the canvas” (5 pts, dependent) — as a deliberate, reasoned under-commit, not a capacity miss. Full plan: backlog/sprints/sprint-8.md.
  • Capacity reasoning, weighed explicitly rather than defaulted to the safe choice: the only other Ready work (epic 6's multi-select + align/distribute pair, 10 pts) must be pulled whole or not at all per product-owner's recommendation and this team's established practice (never split a hard-dependent pair across sprints — Sprint 4's rotation chain, Sprint 7's preview pair). That leaves only two real options: 13 points alone (a new low) or 23 points (13+10, a new high this team has never attempted; its best sprint to date, 20, was itself flagged at the time as a coincidence to watch, not a target). Decided against 23: although the two pairs are not formally dependent on each other, both land real changes in the same small set of GUI files (CanvasElementEditor, TemplateCanvasControl, TemplateDesignerForm) — this sprint's drag-handle story adds a new Address-Control-specific handle/hit-test/rotate-drag path in CanvasElementEditor, while multi-select would rework CanvasElementEditor.Selected from a single reference into a genuinely new multi-item selection model (no such concept exists anywhere today) — the same foundational, first-of-its-kind risk profile this team has consistently avoided pairing with another large/novel story in one sprint (per “Undo and redo layout changes”’ own sizing note). No external date/contractual pressure was cited anywhere in this backlog to justify reaching for an unproven new high just to avoid idle capacity.
  • Checked for a smaller item to round out capacity short of 23 — found none that cleanly fits. “Complete the first text-only operator workflow” (epics/01_end_to_end_text_rendering_slice.md, 5 pts, labeled Ready) is a placeholder from the original 2026-09-04 onboarding refinement, never re-verified since — the same staleness pattern that made epic 4's “Ready” label wrong at the 2026-10-16 refinement (it predates rotation, mixed content, the Address Control, and the live preview, which plausibly already satisfy its ACs). Pulling it blind would repeat that exact mistake rather than learn from it, so it was left uncommitted and is flagged here for product-owner re-verification (close outright, or confirm genuinely still open) at the next backlog refinement, rather than left to sit indefinitely. “Undo and redo layout changes” (13 pts) is both too large to be a rounding-out item and its own sizing note already argues against pairing it with another large/novel story. Nothing else in the backlog is currently Ready.
  • Epic reorder confirmed as scrum-master's own decision, not just inherited: epic 8 stays ahead of epic 6 in this file's Order table. It is a direct, recent, explicit human-product-owner request reversing a scope call the same human product owner made only one sprint ago (Sprint 6 Review), and it is exactly what this sprint commits to — keeping the stated backlog order and the actual sprint commitment consistent.
  • Recommended for Sprint 9: the multi-select/align pair (10 pts, epic 6) as its own clean, undisturbed sprint slice, deliberately not sharing a sprint with another novel canvas-selection rework. “Undo and redo layout changes” (13 pts) remains available whenever it can be paired appropriately — a future planning session should weigh that pairing explicitly rather than default to bundling it in with the multi-select/align pair.
  • No changes to the two open impediments (template asset path strategy; UNC timeout/retry behavior, both in logs/impediment_log.md) — still non-blocking for this sprint's committed items.

Powered by TurnKey Linux.