Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

57KB

Project State

The single live “where are we right now” file. Read this FIRST at the start of any session that touches this repo - don't infer phase or sprint from conversation history. Updated LAST by whichever agent completes the current step, as documented in AGENTS.md under “Automated State-Driven Handoff.”

Phase: 3 - Sprint execution Leading agent: dev-team Process file: process/03_sprint_execution.md

Sprint: 10 planned (2026-10-27), not yet executed. Sprint goal: Let an operator select multiple canvas elements at once (rubber-band or modifier-click, mixing standalone elements and Address Controls) and align/distribute them together, while also finishing the epic-4 wrap/clip chain's live visual indicator. Current sprint backlog: backlog/sprints/sprint-10.md

Recent history (Sprint 9, closed 2026-10-27): Static/dynamic text elements shipped real adjustable width/height with native Debenu wrap/clip (13/13 points, sprint goal met in full); test suite 448/448 -> 476/476. Full detail: backlog/sprints/sprint-9.md, backlog/epics/04_live_preview_and_record_navigation.md, backlog/sprints/sprint-9-retrospective.md. A Proposed (not yet applied) process-improvement log entry awaits human review: the project's own Debenu license key (key.txt, repo root) was overlooked by at least two prior sprints’ searches — logged in logs/process_improvement_log.md (2026-10-27).

Sprint 10 backlog refinement (2026-10-27): Per the Sprint 9 retrospective's own action item, re-confirmed “Support rotated wrapped text and a live wrap/clip indicator for text elements” (previously 8 pts) via real code inspection and a new licensed end-to-end test — found its rotation-composition scope was already delivered as a byproduct of Sprint 9's implementation (confirmed: DebenuPdfRenderer.AddPage's box branch already calls DrawRotatedTextBox, and both canvas/preview box-mode draws already run inside the existing rotation transform). Renamed to “Add a live wrap/clip indicator for text elements” and re-sized down to 3 points — only the passive visual indicator itself remains. Full detail: backlog/backlog.md's Sprint 10 backlog refinement outcome, backlog/epics/04_live_preview_and_record_navigation.md.

Sprint 10 planning (2026-10-27): Committed 13 points: the now-3-point indicator story plus 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 — finally pulled after being Ready and deferred twice (Sprint 8, Sprint 9) for fresher, more urgent requests; neither reason applies a third time. Pairing the small indicator story with multi-select's genuinely novel selection-model work does not trip the established “two large/novel stories” caution, since only one side of the pairing carries that risk profile. Full reasoning: backlog/backlog.md's Sprint 10 planning outcome note.

Sprint 10 Batch 1 complete (2026-10-27), plus two ad-hoc corrections mid-batch: “Add a live wrap/clip indicator for text elements” (3/13 points) shipped — a new framework-free WrapClipDetector (Desktop.Core) drives a dashed-orange indicator on the canvas and preview panel, drawn inside the existing per-element rotation transform. Mid-batch, the human product owner raised two live-build issues, addressed together before continuing: (1) no way to delete a placed element or Address Control — added CanvasElementEditor.RemoveSelected()/TemplateCanvasControl.RemoveSelectedElement(), wired to Delete/Backspace and a new toolbar button; (2) the resize handle should control only box width, font size set elsewhere — removed the Sprint 8 uniform-font-scale handle behavior entirely; TextElementLayout.HasBox/TemplateElement.HasBox now mean “Width is set” alone, with Height independent and optional (new HasHeightClip flag), and DebenuPdfRenderer.AddPage gained a “Width alone, auto-height, no clip” render path (DrawWrappedText/GetWrappedText+DrawRotatedMultiLineText). Full suite 476/476 -> 488/488. Live-verified: a real licensed end-to-end CLI render (width-only, unrotated and rotated) showed correct auto-height wrap with no clipping; a reflection-driven built-form harness confirmed the real resize handle sets only Width, the real Delete key removes the selection, and a real canvas screenshot shows the wrap indicator correctly appearing. One disclosed caveat: the toolbar Delete button's PerformClick() didn't reliably fire in the synthetic harness (a WinForms quirk absent a real shown window) — proven correct via a direct method call instead. Full detail: backlog/sprints/sprint-10.md, backlog/epics/02_template_designer_gui_foundation.md, backlog/epics/04_live_preview_and_record_navigation.md.

Post-Sprint-10-Batch-1 user-reported regression fix (2026-10-27, handled outside formal ceremony, mid-Sprint-10): User reported that clicking on and moving a dynamic placeholder had become “not smooth any more.” Root cause found by direct Stopwatch instrumentation of TemplateCanvasControl.OnMouseDown (not guessed): SelectionChanged fired unconditionally on every left-click, including a click on an already-selected element (the normal way to start a drag), and TemplateDesignerForm's handler runs the full un-gated RefreshPropertiesPanel() every time — a cost (~40-60ms/click, measured) that only became perceptible once this sprint's added property-panel rows made the refresh heavier. Fixed by only raising SelectionChanged when the pre-click and post-click selection identity actually differ (RaiseSelectionChangedIfDifferent). Live-verified with the same instrumented harness: an already-selected element's second click dropped from ~50ms to 0.295ms; a genuine selection change still pays the warranted refresh unchanged. Full suite re-run: Desktop.Core 364/364, CLI 124/124 (fix isolated to the WinForms-only TemplateCanvasControl). Full detail: backlog/sprints/sprint-10.md, backlog/epics/02_template_designer_gui_foundation.md.

Sprint 10 Batch 2 complete (2026-10-27): “Select multiple elements at once on the canvas” (5/13 points) shipped — a strictly additive multi-select layer (CanvasElementEditor.MultiSelected for standalone elements, TemplateCanvasControl._multiSelectedAddressControls for Address Controls) alongside the existing single-selection fields, collapsing back to ordinary single-select whenever 0-1 items end up selected so no existing code path changed behavior. Rubber-band selection and modifier-click toggle both work across a mixed selection of elements and Address Controls; group drag moves the whole set by one shared delta, preserving relative offsets; every selected item is visibly highlighted; the properties panel shows “N items selected” and disables per-item editing. Full suite 364/364 -> 376/376 (Desktop.Core; CLI unaffected). Live-verified via a reflection-driven built-form harness (rubber-band, toggle, group-drag delta math, panel state, a real canvas screenshot) with one disclosed caveat (Control.ModifierKeys has no public setter, so modifier-click was verified by calling the same private toggle method directly rather than through a simulated key-press) and one pre-existing, unrelated cosmetic gap found and logged rather than fixed in-scope (a selection highlight border under-wraps a multi-word display string — logs/technical_debt_log.md, 2026-10-27). Full detail: backlog/sprints/sprint-10.md, backlog/epics/06_layout_efficiency_and_operator_tooling.md.

Sprint 10 Batch 3 complete (2026-10-27): “Align and distribute multiple elements” (5/13 points) shipped — Sprint 10's full committed scope (13/13 points) is now Done. New framework-free AlignmentCalculator (Desktop.Core) computes position deltas for 6 alignment edges and 2 distribution axes (center-to-center spacing, a documented MVP simplification) from a list of world-space bounding boxes; TemplateCanvasControl feeds it a mixed bounds list (standalone elements via a newly-public CanvasElementEditor.GetWorldBounds, Address Controls via a new GetAddressControlWorldBounds extracted from Batch 2's rubber-band code) and applies the deltas back. A new 8-button toolbar row triggers the operations, enabled only at 2+ selected items. Full suite 376/376 -> 388/388. Live-verified via reflection-driven harness including a fresh full-form screenshot (not reused from Batch 2, per this story's own carry-in note). Full detail: backlog/sprints/sprint-10.md, backlog/epics/06_layout_efficiency_and_operator_tooling.md.

Sprint 10 Review complete (2026-10-27): product-owner verified all 3 committed stories against acceptance criteria (verdict: sprint goal met in full, 13/13 points). Independently re-ran the full test suite (388/388 Desktop.Tests, 124/124 CLI.Tests, confirmed directly) and read the actual CanvasElementEditor/TemplateCanvasControl/AlignmentCalculator code rather than trusting dev-team's report alone. Confirmed both mid-sprint ad-hoc items (the click-smoothness fix; two newly-logged technical debt entries) are correctly scoped and non-blocking. No new backlog items required. Full detail: backlog/backlog.md's “Sprint 10 Review outcome” section.

Next action: Proceed directly into Sprint Retrospective (scrum-master leads, process/05_sprint_retrospective.md) per the automated state-driven handoff — this is the workflow's next designated pause point (per AGENTS.md): stop and wait for the user once the retrospective is written, before starting Sprint 11 planning. Candidates to weigh for Sprint 11, once resumed: “Add an adjustable width and height with text wrapping to Address Control lines” (epic 4, 8 pts, deferred from Sprint 10); “Undo and redo layout changes” (epic 6, 13 pts, now the last story in that epic); “Warn on text overflow before render” (epic 4, provisional 5 pts, still blocked); both epic 7 impediments (asset path strategy, UNC timeout/retry, open since 2026-09-04); “Complete the first text-only operator workflow” (epic 1, 5 pts) remains flagged as stale; the Proposed process-improvement log entry above awaiting a human decision; two technical debt items from Sprint 10's verification (Address-Control interaction logic still untested WinForms-only, growing with each new feature built on it; the selection-highlight width cosmetic gap), both Open/Low and non-blocking.

Phase reference

# Phase Leading agent Process file
0 Project onboarding product-owner + scrum-master process/00_project_onboarding.md
1 Backlog refinement product-owner (+ dev-team sizing) process/01_backlog_refinement.md
2 Sprint planning scrum-master facilitates process/02_sprint_planning.md
3 Sprint execution dev-team (+ scrum-master daily scrum) process/03_sprint_execution.md
4 Sprint review product-owner leads process/04_sprint_review.md
5 Sprint retrospective scrum-master leads process/05_sprint_retrospective.md
- Technical debt (continuous) qa-tech-debt process/06_technical_debt_management.md
- Portfolio/release planning (as needed) release-planner AGENTS.md - Multilevel Planning
- Process self-improvement (end of every retro) scrum-master process/07_process_improvement.md

After phase 5, loop back to phase 1 for the next sprint.

History

Date Phase completed Notes
2026-09-04 0 - Project onboarding Seeded project config, Definition of Done, initial epic backlog, and open questions from Envelope_Report_Generator_Requirements.md.
2026-09-04 1 - Backlog refinement Refined the top epics into sprint-ready stories, confirmed C#/.NET 10 as the application stack, and reordered the backlog for the first text-only MVP slice.
2026-09-04 2 - Sprint planning Created Sprint 1 around a conservative desktop-to-CLI text-only rendering spine and recorded the committed backlog in backlog/sprints/sprint-1.md.
2026-09-08 3 - Sprint execution (in progress) Held Daily Scrum #1 and turned the sprint backlog into a dependency-ordered execution plan (5 batches) in backlog/sprints/sprint-1.md. Still in phase 3 — not a phase transition, just the day's checkpoint.
2026-09-08 3 - Sprint execution All 5 batches Done: CLI render contract, real Debenu text-only rendering, stdout progress events, WinForms desktop launch shell (user-confirmed as the UI framework), and live progress/completion display. 106 tests passing end-to-end. Sprint goal met with real verified runs against the 392-row sample CSV.
2026-09-11 4 - Sprint review product-owner verified all 5 stories against acceptance criteria (verdict: sprint goal met, with two tracked caveats — see backlog/sprints/sprint-1.md's Sprint Review Outcome section). Updated backlog/backlog.md and epics 01/05/07 with Done notes and two new follow-up stories. Logged one process-improvement item (Watching) for the retrospective re: verifying GUI stories against the actual built artifact, not just an in-process harness — this is exactly what let the license-key bug (fixed same-day, see logs/technical_debt_log.md) through undetected.
2026-09-11 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-1-retrospective.md). Named two team-level strengths to keep (dependency-ordered batch swarming; “leave it better than you found it” plus honest gap self-reporting) and one lower-priority deferred idea (re-trigger the 100k-record benchmark when hot-path code changes). Decided the DoD/verification-gap item meets the bar for a proposed kit edit (single severe occurrence) and drafted specific wording for templates/definition_of_done.md. User approved the edit same-day; it was applied to the template (confirmed in logs/process_improvement_log.md, Status: Applied) — state.md briefly and incorrectly described this as still pending in a later note, corrected on 2026-09-14. Checked all four named anti-patterns; none found (one near-miss on thin GUI evidence named explicitly, addressed via the DoD edit and a Sprint 2 action item rather than swept aside).
2026-09-14 2 - Sprint planning scrum-master facilitated Sprint 2 planning with product-owner and dev-team. Committed 19 points: the overdue high-volume benchmark spike (pulled first per the retrospective action item) plus the full Template Designer GUI Foundation epic as one coherent vertical slice (canvas dimensions -> text placement -> properties panel -> save/reopen). CSV Integration stories deferred whole to Sprint 3 (3 of 4 hard-depend on this sprint's text-placement story); “Load CSV headers” kept as an explicit stretch item since it has no such dependency. Capacity treated as low-confidence off one data point (Sprint 1's 20 completed points). Recorded in backlog/sprints/sprint-2.md.
2026-09-14 3 - Sprint execution dev-team completed all 5 committed batches in dependency order (one interruption/resume mid-run due to a session rate limit, no work lost). Batch 1 (benchmark spike) found a material, previously-unknown risk: real-world throughput degrades from ~399 rec/s to ~15 rec/s and falling at ~100k-record scale, missing the 10-minute target by 5x-10x+, isolated to Debenu Quick PDF Library 10.13's document model — logged as a new Ready story plus a High-impact tech debt entry rather than fixed in-scope. Batches 2-5 delivered the full Template Designer GUI Foundation epic (canvas dimensions, text placement, properties panel, save/reopen), each verified live against the actual built .exe per the Sprint 1 retrospective's DoD edit. 195/195 tests passing. Stretch item not pulled (full committed slice prioritized over starting more scope).
2026-09-18 4 - Sprint review product-owner verified all 5 Sprint 2 stories against acceptance criteria (verdict: sprint goal met). Updated backlog/backlog.md and epics 02/05 with Done notes and verification detail; confirmed and endorsed dev-team's benchmark self-verification, framing it as a successful spike (story ACs met) surfacing a failing product metric (target missed), not a failed story. Recommended prioritizing the new throughput-investigation story at or near the top of Sprint 3.
2026-09-18 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-2-retrospective.md). Confirmed full follow-through on all four Sprint 1 retro action items (clean sprint, no drops) — notably, the Sprint 1-named “thin GUI evidence” weakness was concretely fixed this sprint via live actual-.exe verification on every GUI story. No kit-level edit proposed (one low-severity, single-occurrence daily-log arithmetic slip found; below the bar for a kit change, logged as a deferred watch item). Checked all four named anti-patterns plus the Sprint 1 status-theater near-miss; none found, with the status-theater near-miss specifically improved on rather than repeated.
2026-09-21 2 - Sprint planning scrum-master facilitated Sprint 3 planning with dev-team sizing support. Sized the previously-unsized “Investigate and address high-volume render throughput degradation” story at 8 points (bounded by its own time-boxed acceptance criteria plus a code-inspection-backed feasibility check, recorded in backlog/epics/05_cli_rendering_engine_and_debenu_integration.md). Committed 18 points (throughput story first, then the CSV Integration chain in backlog order) against a 19-20 point velocity range, deliberately leaving “Collapse blank optional address lines” and “Harden production configuration delivery” uncommitted for capacity discipline. Recorded in backlog/sprints/sprint-3.md.
2026-09-21 to 2026-09-22 3 - Sprint execution dev-team completed all 4 committed batches in dependency order across 2 daily-scrum entries. Batch 1 (throughput investigation, 8 points): confirmed the Debenu-internal-document-model hypothesis via a scaled-down real-DLL probe, implemented a batch+merge mitigation in DebenuPdfRenderer, and re-ran the full 100k-record benchmark to completion at 315s (~47.5% under the 10-minute target) — closing the High-impact debt item opened at Sprint 2 close, while honestly logging a new, narrower Medium-impact file-size risk at the 1,000,000-record ceiling rather than overclaiming full closure. Batches 2-4 (CSV Integration chain, 10 points): loaded CSV headers into the desktop app, bound a dynamic text field to a real column, and added rebind-without-repositioning — all live-verified against the real built .exe. 223/223 tests passing (up from 195).
2026-09-22 4 - Sprint review product-owner verified all 4 Sprint 3 stories against acceptance criteria (verdict: sprint goal met in full, no gaps). Updated backlog/backlog.md's epic status table and added a “Sprint 3 Review outcome” section; added an independent confirmation note to the throughput story in backlog/epics/05_cli_rendering_engine_and_debenu_integration.md. Confirmed the new file-size technical debt item as open-but-non-blocking; unblocked “Collapse blank optional address lines” for Sprint 4.
2026-09-22 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-3-retrospective.md). Confirmed full follow-through on all four Sprint 2 retro action items, the second clean full-follow-through sprint in a row — notably, the Sprint 2-named test-count arithmetic watch item did not recur. Named a new team strength (“verify spec/code before building,” caught a stale token-format assumption pre-implementation) and logged one low-severity, first-occurrence process watch item (product-owner's Sprint 3 review leaning on dev-team's pre-written verification notes for 3 of 4 stories) to logs/process_improvement_log.md rather than the sprint plan, per the kit/team-insight split — no kit edit made, revisit at Sprint 4 review. Checked all five named anti-patterns (including the Sprint 1 status-theater near-miss); none found.
2026-09-22 1 - Backlog refinement Mid-refinement, the user requested a new text/dynamic-field rotation capability. product-owner clarified scope directly with the user (angle range, UI interaction, pivot point), then wrote and readied two new dependent stories in backlog/epics/02_template_designer_gui_foundation.md (reopened from Done): “Set a rotation angle for text and dynamic field elements” (8 pts) and “Rotate elements by dragging a handle on the canvas” (5 pts). dev-team sized both with real code/vendor-API inspection (confirmed Debenu's DrawRotatedText rotates about an anchor point, not a center, so the center-pivot math is genuine new work). Both pass the Definition of Ready.
2026-09-28 2 - Sprint planning scrum-master facilitated Sprint 4 planning. Velocity range tightened to 18-20 points (Sprint 3 completed its exact 18-point commitment, zero scope change). Committed 18 points at the low end of the range rather than the ceiling: “Collapse blank optional address lines consistently” (5 pts, completes epic 3) plus the full rotation chain (8 + 5 pts, epic 2). “Harden production configuration delivery” (2 pts) deliberately left as an explicit stretch item. Recorded in backlog/sprints/sprint-4.md.
2026-09-28 to 2026-09-29 3 - Sprint execution dev-team completed all 3 committed batches in dependency order. Batch 1 (blank-line collapse, 5 points): new AddressLineCollapser row-height-shift geometry, collapsible XML attribute, and a dashed-orange canvas highlight distinguishing an unmapped column from a merely-blank one. Batch 2 (rotation angle property, 8 points): empirically confirmed against the real Debenu DLL that positive angle is counterclockwise, built RotatedTextAnchorCalculator for bounding-box-center pivot math, proved it with a pixel-ink-centroid regression test. Batch 3 (drag-to-rotate handle, 5 points): reused Batch 2's panel/canvas sync plumbing exactly as its sizing note predicted; live-verified with real Win32 mouse-drag input, saved-XML value matched the drag to full floating-point precision. 288/288 tests passing (up from 223). One honestly-reported testing-tooling glitch (not a product defect), correctly not logged as debt.
2026-09-29 4 - Sprint review product-owner verified all 3 Sprint 4 stories against acceptance criteria (verdict: sprint goal met in full). Updated backlog/backlog.md's epic status table and added a “Sprint 4 Review outcome” section; wrote independent confirmation notes for all 3 stories (dev-team was deliberately kept from pre-writing epic verification content this sprint). Both the Template Designer GUI Foundation and CSV Integration and Field Mapping epics are now Done outright.
2026-09-29 1 - Backlog refinement Ahead of closing Sprint 4, the user requested requirements for a new composite “Address Control” element (grouped lines mixing static text and CSV fields, single-anchor placement). product-owner gathered requirements across two rounds of clarifying questions and recorded a new epic, backlog/epics/08_composite_address_controls.md (2 dependent stories), deliberately left unsized per the user's own framing of “get requirements” before closing the sprint.
2026-09-29 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-4-retrospective.md). Confirmed full follow-through on all four Sprint 3 retro action items, the third clean full-follow-through sprint in a row — notably, the Sprint 3-named PO-review-independence watch item resolved structurally (dev-team was kept from writing epic verification content; product-owner wrote all 3 stories’ notes fresh and independently) and was closed out in logs/process_improvement_log.md rather than carried forward. Named a new positive signal (a sizing note's specific reuse claim was later confirmed exactly by the real implementation). No kit edits. Checked all anti-patterns including the PO-review-independence watch item explicitly; none found.
2026-09-29 1 - Backlog refinement dev-team sized epic 08's two stories with real code inspection: 13 points each (a new size ceiling for this team, previously 8). Story 1 (“Mix static text and CSV fields”) is a breaking model change to TextElementLayout with no existing UI to build from. Story 2 (“Group lines into a single, movable Address Control”) is the designer's first composite element kind; a deliberate sizing-time design call (single anchor, auto-spaced lines, not N independently-moved children) means the existing AddressLineCollapser grouping logic needs no changes. Both pass the Definition of Ready and are marked Ready, but product-owner recommends committing them to separate sprints given their combined 26-point size against 18-20 point velocity.
2026-10-05 2 - Sprint planning scrum-master facilitated Sprint 5 planning. Velocity range holds at 18-20 points (four data points: 20, 19, 18, 18). Committed 15 points, deliberately below the low end of the range given “Mix static text and CSV fields within a single text element”‘s (13 pts) size and structural risk: plus “Harden production configuration delivery for CLI runtime settings” (2 pts). “Group lines into a single, movable Address Control” (13 pts) left uncommitted per dev-team's own sizing-note recommendation against combining both epic-08 stories in one sprint. Recorded in backlog/sprints/sprint-5.md.
2026-10-05 3 - Sprint execution dev-team completed both committed batches (survived one transient background-agent API/network failure mid-run, resumed cleanly with no work lost). Batch 1 (mixed static/field text content, 13 points): replaced TextElementLayout/TemplateElement's exclusive StaticText/ColumnName with an ordered Runs list, keeping the old properties as computed back-compat projections so all 233 pre-existing tests passed unmodified. Proved backward compatibility by building the actual pre-Sprint-5 CLI binary from a git worktree and byte-comparing real output, controlling for Debenu's own internal nondeterminism. Batch 2 (production configuration hardening, 2 points): decided to keep the existing license-key mechanism unchanged, documented in CLI_CONTRACT.md. 330/330 tests passing (up from 288). One live-caught GUI bug fixed same-pass; one disclosed bracket-syntax editing limitation documented as an accepted trade-off.
2026-10-09 4 - Sprint review product-owner verified both Sprint 5 stories against acceptance criteria (verdict: sprint goal met in full). Updated backlog/backlog.md's epic status table (correcting a stale story count for epic 05 along the way) and added a “Sprint 5 Review outcome” section; independently confirmed dev-team's production-configuration decision rather than rubber-stamping it, flagging it to the user as a licensing/deployment judgment call. The CLI Rendering Engine and Debenu Integration epic is now Done outright.
2026-10-09 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-5-retrospective.md). Confirmed full follow-through on all three Sprint 4 retro action items, the fourth clean full-follow-through sprint in a row, one exceeded (backward-compatibility verification via a real historical-binary byte-comparison). Named a new action item: GUI verification automation reliability has now had two distinct issues in two consecutive sprints, worth hardening before Sprint 6's likely GUI-heavy Address Control story. No kit edits — both findings judged team/tooling-level, not Scrum-kit-level. Checked all anti-patterns including PO-review independence; none found.
2026-10-09 1 - Backlog refinement User reported rotated dynamic/mixed-content fields rendering at inconsistent positions per record. product-owner confirmed the root cause by code inspection (bounding-box-center pivot depends on each record's own resolved-text width; canvas preview doesn't reflect this either, breaking the rotation story's own already-shipped canvas/render-parity AC) before writing anything down. Logged as Open/High-impact in logs/technical_debt_log.md and written up as a full story in backlog/epics/02_template_designer_gui_foundation.md, not yet sized. Recommended for high priority in whatever's planned next, pending human product-owner confirmation.
2026-10-12 1 - Backlog refinement dev-team sized “Keep rotated dynamic and mixed-content fields positioned consistently across records” at 5 points after code inspection (DebenuPdfRenderer, RotatedTextAnchorCalculator, TemplateCanvasControl, CanvasElementEditor, RenderEngine). Story now passes Definition of Ready: clear ACs, no blocking dependency, plausible single-sprint scope. product-owner prioritized it first for Sprint 6 because it fixes already-shipped print-output correctness and canvas/render parity.
2026-10-12 2 - Sprint planning scrum-master facilitated Sprint 6 planning after the user confirmed the post-retro pause point with “continue.” Committed 18 points: the 5-point rotation-positioning defect first, then “Group lines into a single, movable Address Control” (13 pts). Recorded in backlog/sprints/sprint-6.md. Sprint 5 retrospective action carried in explicitly: harden GUI verification automation reliability before/during the Address Control story.
2026-10-12 3 - Sprint execution (in progress) dev-team completed Sprint 6 Batch 1, “Keep rotated dynamic and mixed-content fields positioned consistently across records” (5 pts). Chose the fixed authored (x, y) anchor as the canonical pivot for rotated dynamic/mixed content, leaving rotated static text on the existing center-pivot path. Updated CLI rendering, desktop canvas geometry, tests, docs, sprint notes, and the technical debt log. Verified with 336/336 tests, a real-DLL transform-anchor regression, a real 392-record CLI render of the rotated dynamic sample template, desktop build, and a WinForms canvas bitmap smoke. Sprint remains active with Batch 2 next.
2026-10-12 3 - Sprint execution dev-team completed Sprint 6 Batch 2, “Group lines into a single, movable Address Control” (13 pts), bringing Sprint 6 to 18/18 points Done. Added a new Address Control model on desktop and CLI, line-list UI, per-line mixed-content editing and default-on collapse, whole-control move/resize including a right-edge canvas handle, <addressControl> XML persistence, CLI parse/render expansion, and template-format docs. Verified with 349/349 tests, clean desktop build, a real 392-record CLI render from a temp Address Control template, an actual WinForms canvas bitmap smoke, and a full TemplateDesignerForm bitmap smoke that caught and fixed a dock-order bug hiding the properties panel.
2026-10-12 4 - Sprint review product-owner verified both Sprint 6 stories against acceptance criteria (verdict: sprint goal met in full). The rotated dynamic/mixed-content defect fix is accepted and the 2026-10-09 High-impact technical debt item remains resolved. The Composite Address Controls and Mixed-Content Text epic is now Done outright. No new backlog item required; two scope notes remain documented, not defects: Address Control width does not wrap/clip render text, and whole-control rotation remains out of scope.
2026-10-12 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-6-retrospective.md). Confirmed the fifth clean full-follow-through sprint in a row. Main action for Sprint 7: use actual built-form smokes for GUI stories that touch form layout/properties/toolbar actions. No kit-level edit proposed.
2026-10-16 1 - Backlog refinement product-owner ran Sprint 7 backlog refinement. Found epic 4's “Ready” label stale (unchanged since onboarding, predating rotation/mixed-content/Address Controls) - real code inspection showed the canvas preview never resolves per-record text at all, just raw bracket tokens. Rewrote and re-sized both stories: “Render an accurate, record-specific preview of the current template” (8 pts, up from 5) and “Jump to a specific record number” (5 pts, up from 3), both now Ready with ACs requiring one shared text-resolution routine (avoiding a third divergent implementation, the same drift class behind the 2026-10-09 rotation defect) and a built-form smoke. A third epic-4 story, “Warn on text overflow before render,” was left explicitly Not Ready - no element has any bounding-width concept today, logged as an open question for the human product owner, not blocking Sprint 7. Also converted epic 6's three placeholder one-liners into full sized stories: “Select multiple elements at once on the canvas” (5 pts, new prerequisite story, no multi-select exists), “Align and distribute multiple elements” (5 pts, depends on the former), “Snap elements to grid and guides” (5 pts), “Undo and redo layout changes” (13 pts, flagged as this backlog's highest-uncertainty estimate - no undo/redo infrastructure exists at all). Confirmed the two open impediments (asset path strategy, UNC timeout/retry) remain non-blocking since epic 7 stays behind epic 6. No backlog reordering - findings changed sizing/scope, not relative priority. Full reasoning in backlog/backlog.md's “Sprint 7 backlog refinement outcome (2026-10-16)” note.
2026-10-19 2 - Sprint planning scrum-master facilitated Sprint 7 planning. Velocity now has six data points (20, 19, 18, 18, 15, 18) - a stable 18-20 range. Committed 18 points: the full epic 4 pair (“Render an accurate, record-specific preview,” 8 pts; “Jump to a specific record number,” 5 pts, dependent) plus “Snap elements to grid and guides” (epic 6, 5 pts, no dependencies) - chosen over the other epic 6 candidates as the lowest-risk way to round out capacity (no CLI/XML surface, canvas-only smoke needed). Deliberately kept “Select multiple elements” and “Align and distribute” (10 pts combined, hard-dependent) out rather than splitting the prerequisite across sprints. Left “Undo and redo layout changes” (13 pts, this backlog's highest-uncertainty estimate) out entirely, recommending a short feasibility check before it's ever committed. Recorded in backlog/sprints/sprint-7.md; planning outcome note added to backlog/backlog.md.
2026-10-19 3 - Sprint execution dev-team completed all 3 committed batches (18/18 points). Batch 1 (record-specific preview, 8 pts): extracted a single shared TextResolver and RotationPivotCalculator (replacing two near-duplicate implementations each), built a framework-free TemplatePreviewBuilder/PreviewTextDraw mirroring RenderEngine, and a dedicated TemplatePreviewControl wired into TemplateDesignerForm via a deterministic TableLayoutPanel (avoiding a repeat of Sprint 6's dock-order bug). Live-verified via a real built-.exe reflection harness: rotated dynamic pivot stayed fixed across differently-sized names, Address Control collapse worked against real data. One new Low-impact tech debt logged (Address Control lines visually overlap at small font sizes - pre-existing GDI+ measurement approximation, doesn't affect the real PDF render path). Batch 2 (jump to record, 5 pts): new CsvRecordNavigator mirroring the CLI's proven CsvRecordSource pattern; live-verified navigating the real 392-record sample CSV including an out-of-range case. Batch 3 (grid/guide snapping, 5 pts): new GridSnapper wired into both CanvasElementEditor and TemplateCanvasControl; live-verified with a canvas-only smoke confirming mid-gesture snapping. 400/400 tests passing (up from 349).
2026-10-19 4 - Sprint review product-owner verified all 3 Sprint 7 stories against acceptance criteria by reading the actual new/changed code and test files (not just dev-team's summary) - confirmed the shared TextResolver/RotationPivotCalculator are genuinely used by canvas and preview alike, the preview auto-refreshes on every real edit path, collapse/mixed-content/Address-Control scenarios in TemplatePreviewBuilderTests genuinely mirror RenderEngineTests, record navigation is a real unbounded scan (not the 20-row preview cap), and grid snapping is continuous mid-drag with zero template-format changes. Verdict: sprint goal met in full. Lacking shell/build access this session, substituted an independent [Fact]/[Theory] count (matched 400/400 exactly) and code-level checks for a live dotnet test run and built-.exe re-verification - disclosed explicitly rather than presented as full re-verification. I (top-level session) ran dotnet test directly afterward and confirmed 400/400 (299 Desktop + 101 CLI) for real. Updated backlog/backlog.md's epic table and Sprint 7 Review outcome note, epics 04/06 with verification detail, and added a PO confirmation to the new Low-impact Address Control overlap tech debt entry (confirmed root cause confined to GDI+ canvas/preview measurement, doesn't touch the real PDF render path).
2026-10-19 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-7-retrospective.md). Sixth consecutive clean full-follow-through sprint: all three Sprint 6 carry-ins held (built-form smoke rule applied correctly - canvas-only smoke for the canvas-only grid-snap story was correct per the rule's own original wording, not a shortcut, though one minor nuance was named: Batch 2 reused Batch 1's full-form screenshot rather than capturing a fresh one after adding a new toolbar control; product-risk-first ordering confirmed; cross-layer code-inspection sizing confirmed via cited real method/class names in the 2026-10-16 sizing notes). New “Watching” item logged in logs/process_improvement_log.md (not a kit edit): this sprint's PO review lacked shell/build access and substituted a static test-attribute count plus code reading for a live dotnet test run - judged a first-occurrence tooling-access gap, explicitly distinct from the closed Sprint 3 PO-independence item, not severe enough for a kit change. No anti-patterns found. Three concrete action items carried into Sprint 8 planning (see Next action above).
2026-10-26 3 - Sprint execution dev-team completed both committed Sprint 8 batches (13/13 points). Batch 1, “Rotate the whole Address Control as a single unit” (8 pts): new angle attribute on <addressControl> (default 0) persisted independently on CLI and desktop; rigid-group rotation around the control's authored box center applied to RenderEngine.BuildAddressControlDraws, TemplatePreviewBuilder, and TemplateCanvasControl.DrawAddressControl; rotated-rectangle hit-testing added for selection and resize; a new shared PointRotation helper (Desktop.Core) and a CLI-side rotate-around-pivot helper, both unit tested; pivot-stability regression tests confirming collapse never shifts the pivot. Batch 2, “...by dragging a handle on the canvas” (5 pts): new framework-free AddressControlRotateHandle (Desktop.Core) providing hit-test/drag-angle math, wired into TemplateCanvasControl's mouse handlers and reusing Batch 1's existing properties-panel sync for free. Full suite grew to 433/433 (326 desktop, 107 CLI). Both batches live-verified via a reflection-driven built-.exe harness (CLI PDF content-stream inspection, canvas/preview screenshots, simulated real mouse drags), with fresh (not reused) full-form screenshots per batch per the Sprint 7 retrospective carry-in. One new Low-impact technical debt item logged (pre-existing Sprint 6 Address Control hit-test/move/resize logic remains WinForms-only, untestable by unit tests, unlike this sprint's own newly-extracted rotation math). Full detail: backlog/sprints/sprint-8.md.
2026-10-26 4 - Sprint review product-owner verified both Sprint 8 stories against acceptance criteria (verdict: sprint goal met in full). Independently re-ran the full test suite (433/433 confirmed directly via dotnet test, not trusted from dev-team's report) and read the actual persistence code (TemplateLayoutXmlSerializer.CreateAddressControl, TemplateXmlParser.ParseAddressControl) and the new unit-tested classes (PointRotation, AddressControlRotateHandle) directly, confirming the claims rather than rubber-stamping them. Disclosed that this session did not rebuild/re-drive the desktop .exe itself, so dev-team's live built-form screenshot evidence was cross-checked against code rather than re-observed - same kind of disclosed limitation as the Sprint 7 review. Confirmed the new Low-impact technical debt item as non-blocking. The Composite Address Controls and Mixed-Content Text epic is now Done outright (4 of 4 stories). Updated backlog/backlog.md's epic table and added a “Sprint 8 Review outcome” section; added Sprint Review verification notes to both stories in backlog/epics/08_composite_address_controls.md.
2026-10-26 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-8-retrospective.md). Eighth sprint, clean delivery, no drops on prior actions (two of three Sprint 7 items directly confirmed, the third correctly carried forward unchanged since its trigger condition - epic 6's pair being pulled - didn't occur this sprint). Revisited and updated the Sprint 7 “PO review tooling-access” watch item in logs/process_improvement_log.md: no recurrence this sprint (real dotnet test access, used directly), kept as “Watching” rather than closed. No kit-level edit. New non-kit insight logged for Sprint 9 consideration: evaluate extracting the pre-existing Sprint 6 Address Control interaction code (still WinForms-only/untestable) to a CanvasElementEditor-equivalent before/alongside any story that next deepens Address Control interaction logic. All anti-patterns checked; none found.
2026-10-26 3 - Sprint execution (ad hoc, outside formal ceremony) User reported choppy drag/rotate for a standalone dynamic/mixed-content element. Clarified scope with the user first, then confirmed root cause by code inspection: the properties panel's full refresh (including a from-scratch rebind-column-combo repopulation, real work only for single-column-bound elements) ran on every mouse-move tick of a drag/rotate gesture, not just at gesture end. Fixed via a new TemplateCanvasControl.IsInteracting property and cheap TemplateDesignerForm.RefreshInteractivePositionFields(), deferring the full refresh to OnMouseUp. Live-verified with a reflection-driven harness plus a true before/after comparison (temporary git worktree at the pre-fix commit): 60 synthetic drag ticks dropped from 88.56 ms/120 mid-drag combo-repopulations to 1.32 ms/0 mid-drag repopulations; same result for rotate. 433/433 tests still passing. Documented in backlog/epics/02_template_designer_gui_foundation.md.
2026-10-26 1 - Backlog refinement User asked to make control boxes “longer.” Too large for ad hoc coding, so handled as proper backlog work: product-owner clarified scope with the user across two rounds of questions (which controls, wrap vs. clip, which dimensions), resolving the “Warn on text overflow before render” story's blocking open question (parked since 2026-10-16). Wrote two new dependent, not-yet-sized stories in backlog/epics/04_live_preview_and_record_navigation.md for adjustable width/height with text wrapping (standalone elements, then Address Control), re-scoped “Warn on text overflow before render” to depend on both. Found via code inspection that the vendor Debenu library already exposes native wrap/box-drawing primitives (DPLDrawWrappedText, DPLDrawTextBox, DPLGetWrappedTextHeight), materially de-risking the likely implementation. No code written; needs dev-team sizing before Sprint 9.
2026-10-26 3 - Sprint execution (ad hoc, outside formal ceremony) User asked for a way to resize static/dynamic text elements. Clarified scope first (existing numeric Font size panel field vs. a canvas drag handle) — user wanted the handle. Since standalone elements have no independent Width/Height, the new handle uniformly scales FontSize. Added CanvasElementEditor.ResizeHandlePosition/HitTestResizeHandle/BeginResizeDrag/ResizeDragTo (Desktop.Core, 15 new unit tests) and a square canvas handle at the box's top-right corner, clamped to the panel's existing 1-1000pt bounds, bidirectionally synced via the smoothness fix's RefreshInteractivePositionFields. Live-verified through the real OnMouseDown/OnMouseMove/OnMouseUp pipeline: a click on the handle's real pixel position started a resize-drag, dragging outward grew a 12pt element to ~43pt (panel tracking live), dragging inward shrank it to the clamped 1pt floor. 448/448 tests passing. Documented in backlog/epics/02_template_designer_gui_foundation.md.
2026-10-26 1 - Backlog refinement product-owner ran Sprint 9 backlog refinement after the user confirmed the post-Sprint-8-retrospective pause point with “continue.” Re-verified epic 6's two Ready items (multi-select, undo/redo) against real code changes since 2026-10-19; no material change found. Sized the three new epic-4 wrap/clip stories via real code/vendor-API inspection: the standalone-element core story at 13 points (real de-risking finding: Debenu already exposes native DPLDrawWrappedText/DPLDrawTextBox/DPLGetWrappedTextHeight wrap/box primitives, and GDI+ has an equivalent rectangle-wrap capability, so neither engine needs a hand-rolled word-wrap algorithm; real risk found: the desktop app and CLI are separate processes with no shared wrap code path, so canvas/preview wrap is an accepted design-time approximation, not guaranteed PDF parity) — found too large to keep whole and split further into “Support rotated wrapped text and a live wrap/clip indicator” (8 points, carved out at sizing time) and “...for Address Control lines” (8 points). “Warn on text overflow before render” given a provisional 5-point estimate by analogy to two already-Done patterns at this scale. Total new Ready scope: 29 points across 3 stories (34 including the still-Not-Ready “Warn” story). Full detail: backlog/backlog.md's Sprint 9 backlog refinement outcome, backlog/epics/04_live_preview_and_record_navigation.md, backlog/epics/06_layout_efficiency_and_operator_tooling.md.
2026-10-26 2 - Sprint planning scrum-master facilitated with product-owner/dev-team input, immediately following backlog refinement. Capacity signal now has eight data points (20, 19, 18, 18, 15, 18, 18, 13), with both 15 and 13 treated as documented deliberate under-commits, not capacity misses. Committed 13 points: the epic-4 wrap/clip core story alone, a deliberate under-commit — rejected pairing it with its own 8-point dependent follow-up (would total 21, a new team-wide high for a first-of-its-kind capability with real unconfirmed vendor-API unknowns, and unlike prior “pull the whole pair” precedents this story is independently valuable and shippable alone) and rejected pairing it with epic 6's 10-point multi-select/align pair (23 total, stacking two large first-of-its-kind initiatives in one sprint, the same risk profile this team avoided at Sprint 8 planning). No smaller rounding-out item found, same conclusion as Sprint 8 planning. Recorded in backlog/sprints/sprint-9.md; full reasoning in backlog/backlog.md's Sprint 9 planning outcome note.
2026-10-27 3 - Sprint execution dev-team completed the sprint's single committed story, “Add an adjustable width and height with text wrapping to static and dynamic text elements” (13/13 points). A licensed real-DLL probe against the actual Debenu library, run before any implementation code, found and confirmed (via real rendered screenshots) native DrawTextBox/DrawRotatedTextBox/GetWrappedTextHeight/GetWrappedTextLineCount entry points that wrap, clip, and compose rotation with wrapping natively. TextElementLayout/TemplateElement gained nullable Width/Height (optional width/height XML attributes, both sides independently implemented); DebenuPdfRenderer.AddPage branches to the native calls when a draw has a box; canvas and preview panel approximate the same wrap/clip via GDI+'s native rectangle-bounded drawing (a documented design-time approximation). The resize-handle coexistence question was resolved by making the existing font-size handle context-sensitive (box mode vs. font-scale mode, chosen once at drag-start) rather than adding a second handle. Properties panel gained Box width/height fields. Tests: 448/448 -> 476/476 (23 new, including a licensed pixel-based clipping test). Live-verified at three layers: the vendor-DLL probe itself; a true end-to-end run (real template through the real built EnvelopeRenderer.Cli.exe against the real 392-record sample CSV, output rasterized and visually confirmed to wrap/clip correctly); and a reflection-driven built-form smoke against the real TemplateDesignerForm (real panel fields, real mouse-driven resize drag, real canvas screenshot) — the last of these was initially skipped mid-execution and caught/completed before Sprint Review. Found, not assumed: the project's own Debenu license key (key.txt, repo root) had been overlooked by at least two prior sprints’ searches (which only checked under code/). Full detail: backlog/sprints/sprint-9.md.
2026-10-27 4 - Sprint review product-owner verified the Sprint 9 story against acceptance criteria (verdict: sprint goal met in full). Independently re-ran the full test suite (476/476 confirmed directly via dotnet test) and read the actual DebenuPdfRenderer.AddPage box branch, TemplateLayoutXmlSerializer/TemplateXmlParser persistence, and new test files directly, confirming the claims rather than trusting dev-team's report alone. Agreed the dependent “Support rotated wrapped text...” story (previously 8 pts) needs re-confirmation, not silent reuse, given this sprint's own de-risking finding. Updated backlog/backlog.md's epic table and added a “Sprint 9 Review outcome” section; added a Development verification note to the story in backlog/epics/04_live_preview_and_record_navigation.md.
2026-10-27 5 - Sprint retrospective scrum-master ran the retrospective (backlog/sprints/sprint-9-retrospective.md). Ninth sprint, clean delivery, no drops (one item showed genuine follow-through in substance despite its literal trigger not arising; two correctly carry forward unchanged, one now a third sprint running). Named one honest near-miss: the built-form GUI smoke was initially dropped from the story's own task list mid-execution, caught and completed before review — logged as a new action item. Logged a Proposed (not yet applied) process-improvement entry in logs/process_improvement_log.md: the project's own Debenu license key was overlooked by at least two prior sprints’ searches, a recurring (2+ occurrence) verification-depth gap meeting AGENTS.md's kit-level bar — recommended fix is a documentation nudge in CLI_CONTRACT.md/AGENTS.md, awaiting a human product owner decision on wording/placement. All anti-patterns checked; none found.
2026-10-27 1 - Backlog refinement product-owner ran Sprint 10 backlog refinement after the user confirmed the post-Sprint-9-retrospective pause point with “continue.” Per the Sprint 9 retrospective's own action item, re-confirmed “Support rotated wrapped text and a live wrap/clip indicator for text elements” (previously 8 pts) via real code inspection and a new licensed end-to-end test — found rotation composition was already delivered as a byproduct of Sprint 9's implementation (DebenuPdfRenderer.AddPage's box branch already calls DrawRotatedTextBox; canvas/preview box-mode draws already run inside the existing rotation transform), proven with a real rendered screenshot of a 20°-rotated, wrapped, boxed element. Renamed to “Add a live wrap/clip indicator for text elements,” re-sized down to 3 points. Also found and documented that automated pixel-row-count clip verification is unreliable under rotation, simplifying a new regression test accordingly. Full detail: backlog/backlog.md's Sprint 10 backlog refinement outcome, backlog/epics/04_live_preview_and_record_navigation.md.
2026-10-27 2 - Sprint planning scrum-master facilitated with product-owner/dev-team input. Capacity signal now has nine data points (20, 19, 18, 18, 15, 18, 18, 13, 13). Committed 13 points: the 3-point indicator story plus epic 6's multi-select/align pair (10 pts), finally pulled after being deferred twice (Sprint 8, Sprint 9) for fresher requests that no longer apply. Reasoned explicitly that pairing a small, additive story with one large/novel story (multi-select's new selection model) does not trip the established “two large/novel stories” caution, since only one side carries that risk profile. Recorded in backlog/sprints/sprint-10.md; full reasoning in backlog/backlog.md's Sprint 10 planning outcome note.
2026-10-27 3 - Sprint execution dev-team completed Sprint 10 Batch 1, “Add a live wrap/clip indicator for text elements” (3/13 points). New framework-free WrapClipDetector (Desktop.Core) drives a dashed-orange indicator on the canvas and preview panel. Mid-batch, the human product owner raised two live-build issues, addressed together: (1) no way to delete a placed element or Address Control — added CanvasElementEditor.RemoveSelected()/TemplateCanvasControl.RemoveSelectedElement(), wired to Delete/Backspace and a new toolbar button; (2) the resize handle should control only box width, font size set elsewhere — removed the Sprint 8 uniform-font-scale handle behavior entirely; HasBox now means “Width is set” alone, Height independent and optional (new HasHeightClip), and DebenuPdfRenderer.AddPage gained a “Width alone, auto-height, no clip” render path. Full suite 476/476 -> 488/488. Live-verified: a real licensed end-to-end CLI render (width-only, unrotated and rotated) confirmed auto-height wrap with no clipping; a reflection-driven built-form harness confirmed the real resize handle sets only Width, the real Delete key removes the selection, and a real canvas screenshot shows the wrap indicator. One disclosed caveat: the toolbar Delete button's PerformClick() didn't reliably fire in the synthetic harness — proven correct via a direct method call instead. Full detail: backlog/sprints/sprint-10.md, backlog/epics/02_template_designer_gui_foundation.md, backlog/epics/04_live_preview_and_record_navigation.md.
2026-10-27 3 - Sprint execution (ad hoc, outside formal ceremony) User reported that clicking on and moving a dynamic placeholder had become “not smooth any more.” Root cause found by directly instrumenting TemplateCanvasControl.OnMouseDown with Stopwatch timers rather than guessing: SelectionChanged fired unconditionally on every left-click — including a click on an already-selected element, the normal way to begin dragging it — and TemplateDesignerForm's handler runs the full un-gated RefreshPropertiesPanel() every time, a cost (~40-60ms/click, measured) that only became perceptible once this sprint's added property-panel rows made the refresh heavier. Fixed by capturing the pre-click selection identity and only raising SelectionChanged when it actually changed (RaiseSelectionChangedIfDifferent). Live-verified with the same instrumented reflection harness: an already-selected element's second click dropped from ~50ms to 0.295ms end-to-end in OnMouseDown, while a genuine selection change still correctly pays the warranted refresh cost unchanged. Full suite re-run: Desktop.Core 364/364, CLI 124/124 (fix isolated to the WinForms-only TemplateCanvasControl, which has no automated test project). Documented in backlog/epics/02_template_designer_gui_foundation.md and backlog/sprints/sprint-10.md.
2026-10-27 3 - Sprint execution dev-team completed Sprint 10 Batch 2, “Select multiple elements at once on the canvas” (5/13 points). Additive multi-select layer alongside existing single-selection state (CanvasElementEditor.MultiSelected, TemplateCanvasControl._multiSelectedAddressControls), collapsing to ordinary single-select at 0-1 items so every existing code path is unaffected. Rubber-band selection (rotation-aware AABB intersection) and modifier-click toggle both work across mixed elements/Address Controls; group drag moves the set by one shared delta preserving relative offsets (snapping the delta once, not each item's position independently); every selected item is visibly highlighted; properties panel shows “N items selected,” disabled for per-item editing. 12 new Desktop.Core tests, full suite 364/364 -> 376/376. Live-verified via reflection-driven built-form harness including a real canvas screenshot; one disclosed caveat (ModifierKeys has no public setter, so modifier-click verified via direct private-method call) and one unrelated pre-existing cosmetic gap found and logged, not fixed in-scope (selection-highlight width under-wrap). Full detail: backlog/sprints/sprint-10.md, backlog/epics/06_layout_efficiency_and_operator_tooling.md.
2026-10-27 3 - Sprint execution dev-team completed Sprint 10 Batch 3, “Align and distribute multiple elements” (5/13 points) — sprint's full committed scope (13/13) now Done. New framework-free AlignmentCalculator (Desktop.Core) computes deltas for 6 alignment edges and center-spaced distribution along 2 axes from world-space bounding boxes; TemplateCanvasControl feeds it a mixed elements/Address-Controls bounds list (reusing/extracting Batch 2's rotation-aware AABB code) and applies deltas back as plain position offsets. New 8-button toolbar row enabled only at 2+ selected items, refreshed in lock-step with existing selection-state refresh so it can't drift out of sync. 12 new Desktop.Core tests, full suite 376/376 -> 388/388. Live-verified via reflection-driven harness: exact expected alignment/distribution results, correct button enable/disable at 0/1/2+ selected, and a fresh full-form screenshot (not reused from Batch 2, per this story's own carry-in note) confirming the new toolbar and highlights render correctly together. Full detail: backlog/sprints/sprint-10.md, backlog/epics/06_layout_efficiency_and_operator_tooling.md.

Powered by TurnKey Linux.