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 (2 of 4 stories Done — “Snap elements to grid and guides” Sprint 7, “Select multiple elements at once on the canvas” Sprint 10 Batch 2; “Align and distribute multiple elements” Ready, committed as Sprint 10 Batch 3, depends on the multi-selection now shipped; “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) |
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).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.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).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.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).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.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.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..exe: load headers, bind a dynamic field, rebind it, with the mapping honored on the next CLI render.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.logs/impediment_log.md) — still non-blocking for the Sprint 4 candidates named above.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.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.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.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.logs/impediment_log.md).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.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.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.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.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.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.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.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.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.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.width is not yet render-time wrapping/clipping, and whole-control rotation remains an out-of-scope future candidate.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.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.backlog.md's table previously said “5 of 7,” a stale count corrected this review to the epic's actual 6 total stories).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.{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.logs/impediment_log.md).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.dev-team's own sizing note recommended against committing both epic-08 stories in the same sprint. Clean pull for Sprint 6.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.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.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.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).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.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).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.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.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.scrum-master/dev-team at planning, not a commitment.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.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.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..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.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.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).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).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.(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).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.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.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).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.logs/impediment_log.md) — confirmed still Open, unresolved since 2026-09-04, and still non-blocking for every Sprint 8 candidate named above.backlog/epics/08_composite_address_controls.md. Full daily detail: backlog/sprints/sprint-8.md.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..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.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.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.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).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).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.scrum-master facilitated with product-owner/dev-team input, immediately following Sprint 10
backlog refinement above.
backlog/sprints/sprint-10.md.logs/impediment_log.md) — still non-blocking for this sprint's committed
items.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.
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_...).epics/04_live_preview_and_record_navigation.md.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.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.backlog/epics/04_live_preview_and_record_navigation.md.
Full daily detail: backlog/sprints/sprint-9.md.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.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.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.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.logs/impediment_log.md) — still non-blocking.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.”
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.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.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.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.epics/04_live_preview_and_record_navigation.md.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.scrum-master facilitated with product-owner/dev-team input, immediately following Sprint 9
backlog refinement above.
backlog/sprints/sprint-9.md.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.backlog/sprints/sprint-8.md.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.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.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.logs/impediment_log.md) — still non-blocking for this sprint's committed items.Powered by TurnKey Linux.