# Sprint Backlog
**Sprint:** 1 **Dates:** 2026-09-08 - 2026-09-11
**Sprint Goal:** Prove a thin text-only desktop-to-CLI rendering spine so an operator can select files, launch a job, watch progress, and receive a PDF generated through Debenu from a known XML template.
## Committed Items
| Story | Size | Status | Tasks |
|---|---|---|---|
| Define the CLI render contract | 3 points | Done | - [x] Define the MVP CLI arguments, stdout/stderr rules, and exit-code contract in repo docs.
- [x] Scaffold the CLI entrypoint and argument parsing for template, CSV, and output paths.
- [x] Validate missing or invalid required arguments for local and UNC path inputs.
- [x] Return documented success and failure exit codes with simple smoke examples. |
| Render text-only PDFs through Debenu Quick PDF | 8 points | Done | - [x] Wire Debenu Quick PDF Library `10.13` into the CLI runtime path.
- [x] Parse the supported text-only XML template elements needed for page and text placement.
- [x] Load CSV rows and merge static plus dynamic text into the render model.
- [x] Generate PDF `1.4+` RGB output and write it to the requested output path.
- [x] Verify the render path with a representative sample template and CSV dataset. |
| Emit machine-readable progress during render | 3 points | Done | - [x] Define a simple line-oriented progress event format that the desktop app can parse.
- [x] Emit startup, active-render, completion, and failure progress events without corrupting error output.
- [x] Throttle active progress output to at least once per second and document examples. |
| Launch a text-only render from the desktop app | 3 points | Done | - [x] Scaffold the desktop shell with template, CSV, and output pickers plus a launch action.
- [x] Validate required operator inputs before the render starts.
- [x] Start the CLI process with the selected paths and surface clear launch failures. |
| Show render progress and completion summary | 3 points | Done | - [x] Parse the CLI progress stream in the desktop app without freezing the UI.
- [x] Display active status updates whenever progress events arrive.
- [x] Show success totals and failure outcomes, including elapsed time and warning count (no warning concept exists in the product yet — see Day 1 log; not fabricated). |
## Notes
- Capacity signal: first sprint with no historical velocity, so the team uses a conservative one-week forecast of about `32` task-hours for committed feature work and keeps roughly `10%` of the week for refinement and ceremony.
- Planning rationale: the team pulls a thin integration spine from the highest-priority ready stories and intentionally defers broader template-authoring and CSV-mapping stories to avoid overcommitting in the first one-week sprint.
- Impediments: template asset path strategy (absolute vs relative) remains open; UNC timeout/retry behavior remains open.
- Risk handling this sprint: keep Sprint 1 to known local-file and known-template scenarios unless the product owner resolves the open path and UNC questions mid-sprint.
- Deferred ready stories: `Configure canvas dimensions in operator-friendly units`, `Place and move text elements on the canvas`, `Save and reopen text-only XML templates`, `Load CSV headers and sample rows into the desktop app`, and `Create a dynamic text token from a CSV column`.
- Carried over from previous sprint: none.
## Daily Scrum Log
| Day | Date | Completed | Planned | Blocked/At risk |
|---|---|---|---|---|
| 1 | 2026-09-08 | N/A (sprint start) | Swarm on "Define the CLI render contract" (all other stories depend on its arg/exit-code shape) | Template path and UNC timeout impediments still open (see `logs/impediment_log.md`); not blocking today, will block Story 2 if still open when it starts |
| 1 (end of day) | 2026-09-08 | "Define the CLI render contract" — all 4 tasks done, story meets DoD, marked Done. `EnvelopeRenderer.Cli` scaffolded with contract doc, arg parsing/validation, exit codes 0/1/2/3/4/64, 15 passing xUnit tests, manual smoke examples recorded in `code/CLI_CONTRACT.md`. | Pull Batch 2, "Render text-only PDFs through Debenu Quick PDF" | Template path and UNC timeout impediments still open — now directly relevant since Batch 2 is the story they were flagged against; logged one low-impact, self-resolving debt item (exit code `64` placeholder) in `logs/technical_debt_log.md` |
| 1 (continued) | 2026-09-08 | "Render text-only PDFs through Debenu Quick PDF" — all 5 tasks done, story meets DoD, marked Done. Hit and resolved a real blocker mid-task: the vendored Debenu DLL fails every save (error 999) without a license key; found and verified a working key. Discovered via the vendor reference guide that `SetPageSize` has no US envelope sizes, so the template format uses exact `pageWidth`/`pageHeight` points via `SetPageDimensions` instead — also caught and fixed a real bug this surfaced (a fresh Debenu document already has page 1, so the original code would have produced a spurious blank leading page on every render). Verified end-to-end against the real 392-row sample CSV: exact `%PDF-1.4`, 392/392 pages, correct #10 envelope dimensions. Exit-code `64` placeholder removed (debt paid down); exit `1` now covers all template/CSV/render failures. | Pull Batch 3, "Emit machine-readable progress during render" | Template path and UNC timeout impediments still open, unchanged by this batch. Debenu license key requirement now documented in `code/CLI_CONTRACT.md`; logged as a resolved impediment in `logs/impediment_log.md`. |
| 1 (continued) | 2026-09-08 | "Emit machine-readable progress during render" — all 3 tasks done, story meets DoD, marked Done. Added a plain-text, line-oriented `PROGRESS elapsedMs= completed= [reason=]` event format on stdout (`startup`/`render`/`complete`/`failure`), documented with rationale in `code/CLI_CONTRACT.md`. `render` events throttle to at least once per second via `ConsoleProgressReporter`; `RenderEngine` reports per-record unconditionally and lets the reporter decide what actually gets written. `failure` events supplement (never replace) the existing stderr `ERROR: ` line and unchanged exit codes — verified live against the real 392-row sample CSV (startup → two throttled render lines → failure, with stderr/exit code untouched). 47/47 tests passing (15 new). Did not re-run the 100k-record/300 DPI benchmark for this story specifically (judged negligible regression risk: one delegate call added per record) — flagged as an open release-quality check, not a blocker for this story. | Pull Batch 4, "Launch a text-only render from the desktop app" | Template path and UNC timeout impediments still open, unchanged by this batch. Release-quality 100k-record benchmark not re-verified since Batch 2 — worth checking before Sprint 1 review if a batch touches the render hot path again. |
| 1 (continued) | 2026-09-08 | "Launch a text-only render from the desktop app" — all 3 tasks done, story meets DoD, marked Done. User confirmed the open "UI framework still to be confirmed" item as **WinForms** (recorded in `project_config.md`). Added `EnvelopeRenderer.Desktop` (WinForms shell: three file pickers + Render button) plus `EnvelopeRenderer.Desktop.Core` (UI-independent, testable validation/argument-building/process-launch logic) and `EnvelopeRenderer.Desktop.Tests` (27 new xUnit tests). Launch runs via `Task.Run` so the UI thread is never blocked; launch failures (e.g. CLI executable not found) surface via inline status text and a message box, distinct from render failures which remain out of scope for this story. Actually built and ran the GUI end-to-end (blank-field validation, real launch, forced launch-failure via `ENVELOPERENDERER_CLI_PATH`) and confirmed correct behavior in all three cases. 74/74 tests passing (27 new + 47 unchanged). Logged one in-scope-boundary debt item in `logs/technical_debt_log.md`: the Render button re-enables once the CLI process starts, not once it finishes, so nothing yet guards against a double-launch — explicitly deferred to Batch 5, which will track process lifetime/exit code anyway. | Pull Batch 5, "Show render progress and completion summary" | Template path and UNC timeout impediments still open, unchanged by this batch. Release-quality 100k-record benchmark still not re-verified since Batch 2. Double-launch guard intentionally deferred to Batch 5 (see technical debt log). |
| 1 (continued) | 2026-09-08 | "Show render progress and completion summary" — all 3 tasks done, story meets DoD, marked Done. **This was the last batch of Sprint 1.** Desktop app now streams and parses the CLI's `PROGRESS ...` stdout events live (background async reads, `Progress` marshaling back to the UI thread — never freezes the UI), shows active status while rendering, and shows a completion summary (elapsed time, records rendered, success/failure reason) on process exit. Closed the double-launch debt from Batch 4: Render button now only re-enables after the process actually exits, not when it starts — marked Resolved in `logs/technical_debt_log.md`. Investigated the "warning count" task explicitly: no warning concept exists anywhere in the CLI/render pipeline today (the only related idea, missing-image placeholders, belongs to an unbuilt future image-handling epic) — reported as a real gap rather than fabricating a counter; the summary reports only real fields. Verified end-to-end against the real 392-row sample CSV with both a real success run (valid `DEBENU_LICENSE_KEY`, real 1.28 MB PDF produced) and a real forced-failure run (no key) — both showed correct live status and correct final summaries. 106/106 tests passing (32 new). | Sprint 1 committed backlog is now fully Done — hand off to Sprint Review (`product-owner` leads, `process/04_sprint_review.md`). | Template path and UNC timeout impediments still open (see `logs/impediment_log.md`) — carry into Sprint 2 planning. Two items to surface at Sprint Review: (1) the 100k-record/300 DPI benchmark has not been re-run since Batch 2, (2) no "warning" concept exists in the product yet, so the "warning count" acceptance task is satisfied by its absence rather than a real counter — product owner may want to scope that properly in a future story once image/overflow handling exists. |
## Execution Order
Sequenced by dependency, not by story-list order (which happens to match here since the sprint goal *is* the walking skeleton). Swarm each batch as a unit before pulling the next — don't spread across batches with a small team. Batch 4 is the one exception called out below.
| Batch | Story | Why it's gated here |
|---|---|---|
| 1 | Define the CLI render contract | Nothing else can safely start — arg names, exit codes, and stdout/stderr rules are the interface every other story codes against. |
| 2 | Render text-only PDFs through Debenu Quick PDF | Needs Batch 1's entrypoint/arg parsing to exist to wire the render path into. Highest points (8) and highest technical risk (Debenu interop, XML parsing, CSV merge) — largest single swarm target. |
| 3 | Emit machine-readable progress during render | Needs Batch 2's render loop in place to emit real startup/active/completion/failure events against, not stubs. |
| 4 | Launch a text-only render from the desktop app | Only hard dependency is Batch 1's contract (needs real arg names/paths to launch against). Scaffolding the shell and input pickers can start as soon as Batch 1 is done, in parallel with Batches 2-3 **if** the team has more than one contributor to swarm with; otherwise take it sequentially after Batch 3 to avoid splitting focus. |
| 5 | Show render progress and completion summary | Needs both Batch 3 (event format to parse) and Batch 4 (a running process to parse events from) — last in the chain regardless of team size. |
**Today's pull:** Batch 5, "Show render progress and completion summary," per the daily scrum above — the last batch in the sprint's execution order.