Skip to content

Polish unplanned-work WPF flow: parent Feature, open-task button, trimmed debrief, az-job spinner#165

Open
jdschleicher wants to merge 2 commits into
mainfrom
claude/new-issue-workflow-improvements-q4pg28
Open

Polish unplanned-work WPF flow: parent Feature, open-task button, trimmed debrief, az-job spinner#165
jdschleicher wants to merge 2 commits into
mainfrom
claude/new-issue-workflow-improvements-q4pg28

Conversation

@jdschleicher

@jdschleicher jdschleicher commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Navigation

Section Status
Summary
Issue Closes #164
Changes ✅ 4 files
Test Plan ✅ 7 items
Skill Reports
🐚 Bash Engineer Review ✅ APPROVE — View
💠 PowerShell Engineer Review ✅ APPROVE — View
🛡️ Security Audit ✅ PASS — View
🧼 Clean-Code Engineer Review ✅ APPROVE — View
📄 Docs Check ✅ CURRENT — View
✅ Criteria Check ✅ PASS — View
📐 AzDO Diagrams Check ✅ CURRENT — View

How it works

az-Start-UnplannedWork runs the session, then at stop spins up a non-modal WPF progress window that narrates the at-stop az boards chain. On the first daily-story creation it now prompts for a parent Feature and links the story under it; later firefights reuse the cached story and skip the prompt. The debrief reuses the shared timer form, re-labelled and given an "Open in Azure DevOps" button.

flowchart TD
    Start([az-Start-UnplannedWork]):::pub
    Prog["New-WpfProgressWindow<br/>spinner + status line<br/>no-op stub off Windows"]:::pub
    Daily[Get-UnplannedWorkDailyStory]
    Cached{cached or existing<br/>story today?}
    NewStory[New-UnplannedWorkStory]
    Parent["Read-UnplannedParentFeature<br/>pick parent Feature"]:::pub
    Orphan["Resolve-AzDevOpsOrphanParent<br/>orphan-safe fallback"]:::priv
    Link[Invoke-AzDevOpsParentLink]:::priv
    Task[create + link firefight Task]
    Debrief[Invoke-UnplannedDebrief]
    Form["Show-WpfTimerDebrief<br/>drops captured-items list<br/>Open in Azure DevOps button"]:::pub
    Open["az-Open-WorkItemById<br/>via -OpenAction / -OpenLabel"]:::io

    Start --> Prog
    Start --> Daily
    Daily --> Cached
    Cached -- yes --> Task
    Cached -- no, first today --> NewStory
    NewStory --> Parent
    Parent --> Orphan
    Parent -.link.-> Link
    NewStory --> Task
    Task --> Debrief
    Debrief -- flush items, close window --> Form
    Form -- click --> Open
    Prog -. per-step status .-> Debrief

    classDef pub fill:#1f3a5f,stroke:#4ea3ff,color:#fff
    classDef priv fill:#3a3a3a,stroke:#999,color:#fff
    classDef io fill:#5a4a1a,stroke:#e0c060,color:#fff
Loading

Summary

Four refinements to az-Start-UnplannedWork (PowerShell/Windows-only), all gated to the unplanned call site so the shared Pomodoro timer debrief form is unchanged:

  1. Parent-Feature prompt — the daily "Unplanned Work — " catch-all story is no longer created orphaned. On the first creation each day, New-UnplannedWorkStory prompts for a parent Feature and links it; cached/existing stories skip the prompt; a skipped/failed pick falls back to parentless without aborting the session.
  2. Trimmed debrief formInvoke-UnplannedDebriefWpf no longer passes -Items, so the redundant read-only "Captured items" list is gone (items already flush to the Task description).
  3. Open-task button — the form now passes -OpenAction, surfacing an "Open in Azure DevOps" button that opens the just-created Task (reachable even after a failed post).
  4. Loading spinner — a new non-modal New-WpfProgressWindow wraps the at-stop az boards chain (find/create story → create Task → save items) with a per-step status line, so the user isn't staring at a frozen terminal. No-op stub off Windows, where the existing Write-Host lines remain the feedback.

Issue

Closes #164

Changes

  • powcuts_by_cli/azdevops_unplanned.ps1 — new Read-UnplannedParentFeature; New-UnplannedWorkStory parent pick + Invoke-AzDevOpsParentLink; -Progress threaded through Get-UnplannedWorkDailyStory / Invoke-UnplannedDebrief / the orchestrator; Invoke-UnplannedDebriefWpf drops -Items, adds -OpenAction/-OpenLabel.
  • powcuts_by_cli/pow_common.ps1 — new New-WpfProgressWindow (+ private no-op New-WpfProgressController).
  • powcuts_by_cli/pow_timer.ps1Show-WpfTimerDebrief gains a defaulted -OpenLabel knob (timer keeps &#39;Open work item&#39;; unplanned passes &#39;Open in Azure DevOps&#39;).
  • docs/azure-devops-diagrams.md — section-11 flowchart, dependency map, and prose updated.

Test Plan (Windows PowerShell — WPF, can't run in CI)

  • All changed .ps1 files parse cleanly ([System.Management.Automation.Language.Parser]::ParseFile(...))
  • First firefight of the day prompts for a parent Feature; the daily story is linked under it in Azure DevOps
  • A skipped/failed Feature pick creates the story parentless without aborting
  • A second firefight the same day reuses the cached story with no Feature prompt
  • The unplanned debrief form shows no "Captured items" list and an "Open in Azure DevOps" button that opens the new Task
  • A spinner window with updating status text shows while the at-stop az boards jobs run
  • Pomodoro timer debrief (Start-TimerSession) is unchanged — no list change, no extra button, no spinner regression

🤖 Generated with Claude Code


Generated by Claude Code

…164)

Four refinements to az-Start-UnplannedWork, all gated to the unplanned
call site so the shared Pomodoro timer debrief form is unchanged:

- New-UnplannedWorkStory now prompts for a parent Feature on the first
  daily-story creation (orphan-safe; cached/existing stories skip it) and
  links it via Invoke-AzDevOpsParentLink. Extracted Read-UnplannedParentFeature.
- Invoke-UnplannedDebriefWpf drops -Items so the read-only captured-items
  review list is omitted (items already flush to the Task description), and
  passes -OpenAction so an "Open in Azure DevOps" button opens the new Task.
- Show-WpfTimerDebrief gains a defaulted -OpenLabel knob so the open
  button caption is configurable without touching the timer's wording.
- New-WpfProgressWindow (pow_common.ps1): a non-modal spinner+status window
  wrapping the at-stop az-boards chain so the user sees which step is running;
  a no-op stub off Windows where the per-step Write-Host lines remain.

Diagram doc updated for the new parent-link, progress window, and open button.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NKnjPmNLKwW7KiZgkoaNHa

Copy link
Copy Markdown
Owner Author

🐚 Senior Bash Engineer

APPROVE — no bash files in this diff

This branch changed only PowerShell files (powcuts_by_cli/azdevops_unplanned.ps1, pow_common.ps1, pow_timer.ps1) and docs/azure-devops-diagrams.md. No bashcuts_by_cli/* or .bcut_home changes, so there is nothing for the bash review to assess.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🛡️ Senior Security Engineer

Verdict: PASS — no security findings.

Reviewed the PowerShell changes on this branch (azdevops_unplanned.ps1, pow_common.ps1, pow_timer.ps1) against the focus areas:

  • Command/arg injection into az / WIQL — None. The new daily-story → parent-Feature flow routes through Invoke-AzDevOpsParentLink -Id <int> -ParentId <int>; both params are strongly typed [int], and the underlying Add-AzDevOpsWorkItemRelation receives ints, not interpolated strings. No new WIQL is constructed in this diff (title-bearing WIQL is pre-existing and unchanged).
  • Untrusted input → openers / Start-Process — Safe. az-Open-WorkItemById takes [int] $Id; the new openAction closure passes the [int] $TaskId. The URL is <configured-org-base>/_workitems/edit/<int>, then Start-Process $url — no user-controlled string reaches the process launch. $Title/$InitialStatus/$OpenLabel flow only into WPF control properties (data, never code).
  • Add-Type / reflection / WPF windowNew-WpfProgressWindow calls Add-Type -AssemblyName PresentationFramework, WindowsBase, PresentationCore (named framework assemblies only — no -MemberDefinition/-TypeDefinition, no dynamic compilation, no reflection from untrusted input). Controller members are fixed scriptblocks; no eval-like construct.
  • New network calls / secrets — None introduced.

Nothing exploitable is introduced by this diff.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🧼 Senior Clean-Code Engineer

Summary

Three PowerShell files changed: a new New-WpfProgressWindow + private New-WpfProgressController pair in pow_common.ps1, a -Progress controller threaded through the az-Start-UnplannedWork create chain in azdevops_unplanned.ps1, and a one-line -OpenLabel knob added to Show-WpfTimerDebrief in pow_timer.ps1. The new window correctly reuses the existing New-WpfBrushSet + New-WpfSpinnerControl seams and shared color constants — the spinner/brush scaffolding is not duplicated. Well-factored overall.

Findings

Severity Location Issue
LOW azdevops_unplanned.ps1:173, :826 The if ($null -eq $Progress) { $Progress = New-WpfProgressWindow -Disabled } optional-param default appears in New-UnplannedWorkStory and Invoke-UnplannedDebrief. This is a 3-line null-coalescing default, not a repeated decision tree — the extract-repeated-branches rule targets platform/branch logic. Extracting a Resolve-WpfProgress helper here would add indirection without paying for itself (Check 7). Acceptable as-is; left as a note, not a request.
LOW pow_common.ps1:485–495 New-WpfProgressWindow returns the no-op New-WpfProgressController stub at three exit points (-Disabled/non-Windows, Add-Type catch, and implicitly via the disabled path). The $stub = New-WpfProgressController; return $stub two-line form is repeated verbatim twice. Minor; consistent with the project's "name-then-return" rule, so leaving it is fine.

Duplication Map

Pattern Callsites Proposed helper
WPF spinner glyph + status TextBlock row New-WpfProgressWindow (pow_common), Show-WpfTimerDebrief (pow_timer:1321–1342) No extraction recommended. Both already call the shared New-WpfSpinnerControl; only the surrounding container differs (Border row vs. collapsible status panel) and the literals differ (FontSize 20/300 vs 18/280, margin 10 vs 8). Pulling a shared "status row" helper would over-couple two windows with different lifetimes. Matches the established inline-layout WPF style.
$Progress null default New-UnplannedWorkStory:173, Invoke-UnplannedDebrief:826 Not worth a helper (see LOW above).

Function Sizes

Function Lines (body) Verdict
New-WpfProgressWindow ~95 OK — long but it's linear WPF construction (window → border → row → spinner → status → controller), the established shape for this repo's WPF builders (New-WpfCircleResources, Show-WpfTimerDebrief). No hidden second responsibility.
New-WpfProgressController 11 OK
New-UnplannedWorkStory ~50 OK — suspend/resume + create + link reads as one orchestration.
Read-UnplannedParentFeature ~20 OK — clean single-purpose extraction.

Magic Numbers

The new window inlines FontSize 13/20, MaxWidth 300, Padding '20,16', BorderThickness 2, CornerRadius 10, and Thickness(0,0,10,0). Acceptable inline — the surrounding WPF helpers (Show-WpfTimerDebrief, the timer status panel at pow_timer:1329–1340 with its own FontSize 18 / MaxWidth 280 / Thickness 0,0,8,0) inline layout literals everywhere; these are single-use cosmetic values, not reused thresholds. Naming them would break consistency with the established style, not improve it. No flag.

Breathing Room

Two blank lines between all new top-level functions ✓. Internal logical groups (param block → guard → brush set → window → border → row → controller) are separated by single blank lines ✓. No gratuitous triple blanks. Clean.

Premature Abstraction

New-WpfProgressController has effectively one logical caller (New-WpfProgressWindow, from three exit points) — but it's a genuine null-object pattern that lets every call site drive real and stub controllers identically without branching on platform, which is the whole point. Justified, not speculative.

Verdict

APPROVE — well-factored. New WPF helpers reuse the existing brush/spinner seams rather than copy them; the two flagged items are LOW notes (an idiomatic null-default and inline layout literals that match the surrounding style), neither blocking. No HIGH duplicated-branch or parallel-pair-scaffolding violations.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

💠 Senior PowerShell Engineer

Summary

Three .ps1 files changed: pow_common.ps1 (new New-WpfProgressWindow + private no-op New-WpfProgressController), azdevops_unplanned.ps1 (Read-UnplannedParentFeature, parent-Feature pick/link, -Progress controller threading, trimmed debrief), pow_timer.ps1 (defaulted -OpenLabel knob). The design is clean: the platform branch is hidden behind a stub controller so call sites never test Test-WpfIsWindows, Stop is idempotent via a captured [ref], and the timer call site is genuinely untouched. One inconsistent scriptblock-member invocation idiom is the only thing worth a second look; everything else is solid.

Findings

Severity Location Issue
[MEDIUM] azdevops_unplanned.ps1:176,179,844,1218 Inconsistent scriptblock-member invocation. & $Progress.Suspend() / & $Progress.Resume() / & $Progress.Stop() mix two invocation styles: the () already invokes the scriptblock note-property (returns its value), then & invokes that result. It works today only because Suspend/Resume/Stop return nothing ($win.Hide()/Close()/Timer.Stop() are void), so & $null is a harmless no-op. It is inconsistent with the correct & $Progress.SetStatus 'text' form two lines away, and it's a latent footgun: if any member's body ever ends in a value-returning expression, & <thatValue> will try to execute it as a command and can throw. Pick one form and use it everywhere — either $Progress.Suspend() (drop the &) or & $Progress.Suspend (drop the parens). The parameterized members must stay & $Progress.SetStatus 'text'.
[LOW] pow_common.ps1:430 (New-WpfProgressController), :446 (New-WpfProgressWindow), azdevops_unplanned.ps1:134 (Read-UnplannedParentFeature) Approved verbs throughout — New, Read, Show, Get, Invoke all on the Get-Verb list. No drift. Noted only to record the verb audit passed.
[LOW] azdevops_unplanned.ps1:813 (Invoke-UnplannedDebrief) $itemList = @($Items) is the legitimate @() use (normalizing an unknown [object[]] param to a safe-to-.Count/foreach array), not the banned re-wrap of a typed List the function built. No action needed — calling it out so the @()-footgun check is on record as clear.

Detailed Notes (no change required)

  • Output-stream cleanliness — PASS. New-WpfProgressWindow returns exactly one object ($controller / the $stub). $win.Show(), $spinner.Timer.Start(), and $win.Close() are all void-returning WPF/Dispatcher calls, so nothing leaks to the pipeline; every .Children.Add(...) (returns an int index) is correctly piped to Out-Null. No stray objects escape.
  • GetNewClosure() / [ref] idempotency — PASS. $forceRender and the four controller members each GetNewClosure() after all captured locals ($win, $statusText, $spinner, $forceRender, $stopped) are defined, so each closure snapshots the right state. Stop guarding on a captured $stopped = [ref] $false and returning early gives the required "close early + finally closes again" idempotency the call site in az-Start-UnplannedWork's try/finally relies on. This mirrors the established $frameIndex = [ref] 0 spinner idiom.
  • "Never return a function call directly" — PASS. Both new functions capture into a named local ($stub, $controller, $result) and return $thatVariable. Read-UnplannedParentFeature returns $featureId (named). Compliant.
  • Multi-line conditional / switch rules — PASS. All new if/else branches are multi-line with their own indented bodies (the $null -eq $Progress guards, the -Disabled -or -not (Test-WpfIsWindows) branch, the Stop early-return). No inline if (...) { x } else { y }. No switch introduced.
  • Named magic values — PASS. $spinnerRightMargin, $script:WpfColorProgressUnplanned, MaxWidth = 300/FontSize = 13 are either named or self-evidently layout literals. The "0 = parentless" sentinel is documented in the function comment.
  • Breathing room / DRY — PASS. Two blank lines between top-level functions; the platform/WPF-load fallback is factored into the shared New-WpfProgressController stub rather than duplicated. Good extraction.
  • -Progress defaulting — PASS. Every consumer (New-UnplannedWorkStory, Invoke-UnplannedDebrief) guards if ($null -eq $Progress) { $Progress = New-WpfProgressWindow -Disabled }, so the functions are safe to call standalone without the orchestrator threading a controller in.
  • Parse check — SKIPPED: pwsh is not on PATH in this environment, so syntax was reviewed visually only. Please confirm the PR's first test-plan item (ParseFile on all three files) locally before merge.

Dot-Sourcing Wire-Up

WIRED — no new files added; New-WpfProgressWindow / New-WpfProgressController live in the already-sourced pow_common.ps1.

Approved Verbs

PASS — New-WpfProgressWindow, New-WpfProgressController, Read-UnplannedParentFeature all use approved verbs (New, Read); Show-/Get-/Invoke- touched functions unchanged in their verb.

Verdict

APPROVE — no critical/high issues. The MEDIUM & $Progress.Suspend() invocation inconsistency is not currently a bug (the void-returning members make & $null a no-op) but is a latent footgun and a readability inconsistency with the adjacent & $Progress.SetStatus 'text' lines; worth normalizing to a single invocation style in a follow-up touch. Confirm the ParseFile test-plan item locally since pwsh wasn't available here.


Generated by Claude Code

Drop the redundant () from no-arg controller members so & invokes the
scriptblock directly (& $Progress.Suspend), matching the parameterized
& $Progress.SetStatus 'text' form. The old & $Progress.Suspend() worked
only because the members are void-returning; this removes the latent
footgun flagged in PowerShell review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NKnjPmNLKwW7KiZgkoaNHa

Copy link
Copy Markdown
Owner Author

📄 Docs Check

Verdict: CURRENT — no README edits warranted.

This branch is a PowerShell-only refinement to the existing az-Start-UnplannedWork flow (parent-Feature prompt on first daily-story creation, an "Open in Azure DevOps" button on the debrief form, a loading-spinner progress window, and removal of the WPF form's captured-items review list). No new files, no new CLI sections, no public-command renames.

Structural checks:

  • Setup files — PASS. .bcut_home and powcuts_home.ps1 both present.
  • Bash sourcing — PASS. All 9 files in bashcuts_by_cli/ sourced from .bcut_home; no dead refs.
  • PowerShell sourcing — PASS. All 22 files in powcuts_by_cli/ dot-sourced from powcuts_home.ps1 (incl. azdevops_unplanned.ps1); no orphans, no dead refs.
  • Public commandsaz-Start-UnplannedWork and New-UnplannedWorkDebrief both still defined; the diff only added a private helper (Read-UnplannedParentFeature) and -Progress params.

README staleness:

  • The Unplanned-work section's Flow step ("captured items flush to the Task description, then you're prompted for debrief notes") remains accurate — it never claimed a review list in the WPF form, so dropping it leaves nothing stale.
  • The new parent-Feature prompt / Open button / progress spinner are enhancements the README doesn't enumerate at this granularity; their absence isn't a contradiction, so no edit is required.

No auto-fixes applied.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ Criteria Check — #164: Polish the unplanned-work WPF flow

Mapped every acceptance criterion to the branch diff (git diff main...HEAD) on claude/new-issue-workflow-improvements-q4pg28.

Syntax Checks

  • Bash: no bashcuts_by_cli/ or .bcut_home files changed (PowerShell-only issue, as designed) — nothing to parse.
  • ⚠️ PowerShell parse: pwsh is not on PATH in the audit environment — deferred to user verification on Windows.

Acceptance Criteria

# Criterion Status Evidence
1 First-of-day prompts for a parent Feature; daily story linked under it ✅ Met New Read-UnplannedParentFeature (azdevops_unplanned.ps1:134) reuses Read-AzDevOpsFeaturePick + Resolve-AzDevOpsOrphanParent; New-UnplannedWorkStory calls it then Invoke-AzDevOpsParentLink -Id $newId -ParentId $featureId (:206). Reached only via the Find → 0 → New create path, i.e. first creation of the day.
2 Skipped/failed Feature pick → parentless, no abort ✅ Met Read-UnplannedParentFeature returns 0 when hierarchy is null or pick is skipped; link block is guarded by if ($featureId -gt 0). A failed Invoke-AzDevOpsParentLink only emits a yellow warning and continues (azdevops_unplanned.ps1:207-211).
3 Second firefight same day reuses cached story, no Feature prompt ✅ Met Get-UnplannedWorkDailyStory checks Get-UnplannedCachedStoryId / WIQL Find-UnplannedWorkStoryId first; only the cache-miss branch hits New-UnplannedWorkStory. The Feature pick lives inside New-UnplannedWorkStory, so cached/found stories never prompt.
4 Debrief form no longer shows the "Captured items (N)" list ✅ Met Invoke-UnplannedDebriefWpf dropped the -Items $itemList argument to Show-WpfTimerDebrief (diff removes that line). The form's items review list is gated by $itemsLabel/$itemsList.Visibility which only flips Visible when -Items is non-empty.
5 Log Item button still captures + flushes to Task description ✅ Met The stopwatch capture loop and Save-UnplannedItemsToTask are untouched; Invoke-UnplannedDebrief still calls Save-UnplannedItemsToTask -TaskId $TaskId -Title $Title -Items $itemList (azdevops_unplanned.ps1:842, now under & $Progress.SetStatus 'Saving captured items...').
6 Debrief form shows an "Open in Azure DevOps" button opening the new Task ✅ Met Invoke-UnplannedDebriefWpf adds $openAction = { az-Open-WorkItemById $TaskId }.GetNewClosure() and passes -OpenAction $openAction -OpenLabel 'Open in Azure DevOps'. Show-WpfTimerDebrief gained -OpenLabel param (pow_timer.ps1:1055), wires Content = $OpenLabel (:1150), and the button's click handler runs $OpenAction (:1406).
7 Standalone WPF progress window with live status during pre-debrief jobs ✅ Met New New-WpfProgressWindow + New-WpfProgressController (no-op stub) in pow_common.ps1:427/444. az-Start-UnplannedWork creates it (New-WpfProgressWindow -Title 'Unplanned Work' -InitialStatus 'Finding today''s story...'), threads -Progress through Get-UnplannedWorkDailyStoryNew-UnplannedWorkStoryInvoke-UnplannedDebrief, and drives SetStatus/Suspend/Resume/Stop per step. Closed in a finally (idempotent Stop).
8 Pomodoro timer debrief unchanged ✅ Met The timer call site (pow_timer.ps1:1797-1802) passes neither -Items, -OpenLabel, nor -Progress; -OpenLabel defaults to 'Open work item' and -Items defaults empty, so no captured-items list, no relabeled/spurious button, no progress window. Progress plumbing is gated entirely to the unplanned call site.
9 Changed .ps1 parse cleanly; verified in a fresh PowerShell terminal on Windows ⚠️ Manual pwsh not on PATH here — deferred to user verification on Windows. All referenced helpers exist and resolve: New-WpfBrushSet -ProgressColor, $script:WpfColorProgressUnplanned, az-Open-WorkItemById, az-New-AzDevOpsFeature -NoChildStoriesPrompt -NoOpen, Read-AzDevOpsHierarchyCache, Resolve-AzDevOpsIterationArea, Invoke-AzDevOpsParentLink.
10 docs/azure-devops-diagrams.md reviewed/updated if surface changes ✅ Met Prose + both mermaid graphs updated: new Read-UnplannedParentFeature and New-WpfProgressWindow nodes, NewUWStory --> UWParentFeat --> PFeat, NewUWStory --> InvLink, StartUW --> UWProgress edges, and the debrief-form node now reads "Open in Azure DevOps" with the items-review list removed.

Summary

Status Count
✅ Met 8
⚠️ Manual (deferred to Windows) 2
❌ Gap 0

Manual Verification Checklist (fresh PowerShell terminal on Windows)

  • Parse-clean: [System.Management.Automation.Language.Parser]::ParseFile(...) for azdevops_unplanned.ps1, pow_common.ps1, pow_timer.ps1 — zero errors.
  • First az-Start-UnplannedWork of the day → Feature pick appears, daily story shows the parent link in Azure DevOps.
  • Skip the Feature pick → story still created parentless, session proceeds.
  • Second firefight same day → no Feature prompt, same daily story reused.
  • Debrief form shows no "Captured items" list but the "Open in Azure DevOps" button opens the new Task.
  • Progress window with updating status text is visible while the at-stop az jobs run.
  • Run a Pomodoro timer debrief → form is identical to before (no items list change, button reads "Open work item", no progress window).

Verdict

PASS — all 8 code-evidenced criteria are met with concrete diff references; the 2 remaining (PowerShell parse-clean + runtime behavior on Windows) require hands-on Windows verification and are deferred to the user (pwsh is not available in the audit environment). No gaps found.

🤖 Generated with Claude Code


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

📐 AzDO Diagrams Check

Verdict: CURRENTdocs/azure-devops-diagrams.md is in lockstep with the Azure DevOps source changes on this branch.

Trigger

TRIGGERED — changed Azure DevOps source files:

  • powcuts_by_cli/azdevops_unplanned.ps1
  • powcuts_by_cli/pow_common.ps1
  • powcuts_by_cli/pow_timer.ps1

Diagram Doc Touched

TOUCHED — docs/azure-devops-diagrams.md was updated in this branch (section 11 flowchart + prose, section 12 dependency map).

Function / behavior coverage

Source change Diagram reflection Status
Read-UnplannedParentFeature (new, azdevops_unplanned.ps1) Node UWParentFeat in §12 with edge NewUWStory --> UWParentFeat --> PFeat; named in §11 NewStory node + prose
New-WpfProgressWindow (new, pow_common.ps1) Node UWProgress in §12 with edge StartUW --> UWProgress; named in §11 prose
Invoke-AzDevOpsParentLink newly called from New-UnplannedWorkStory Edge NewUWStory --> InvLink added; in §11 NewStory node + prose
-OpenLabel / -OpenAction ("Open in Azure DevOps"), -Items dropped §11 WpfForm node + prose updated; review list removal documented
-Progress threading through az-Start-UnplannedWorkGet-UnplannedWorkDailyStoryNew-UnplannedWorkStory / Invoke-UnplannedDebrief Covered by §11 progress-window prose + UWProgress node
New-WpfProgressController (one-line no-op null-object stub) Intentionally omitted — trivial private helper, consistent with other omitted trivial helpers ✅ (judged omit)

Edge targets verified to exist as real nodes: PFeat[Read-AzDevOpsFeaturePick] (L930), InvLink[Invoke-AzDevOpsParentLink] (L936).

az subcommand drift

No new az boards|devops|repos|pipelines subcommands introduced by this diff — it reuses existing wrappers (Invoke-AzDevOpsParentLink, Set-AzDevOpsWorkItemField, Add-AzDevOpsDiscussionComment). No diagram subcommand drift.

Edits applied

None. The diagram was already updated correctly as part of this branch; no gaps found.


🤖 Automated /azdevops-diagrams-check


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Polish the unplanned-work WPF flow: parent-Feature prompt, open-task button, trimmed debrief, and az-job spinner

2 participants