Skip to content

fix(board): verify the Status field actually moved to Done after a done-move (#178) - #200

Merged
dngioidev merged 2 commits into
mainfrom
fix/178-verify-done-move
Jul 22, 2026
Merged

fix(board): verify the Status field actually moved to Done after a done-move (#178)#200
dngioidev merged 2 commits into
mainfrom
fix/178-verify-done-move

Conversation

@dngioidev

Copy link
Copy Markdown
Owner

Closes #178

Problem

On iomanage #73 the post-merge ritual reported "board → Done" but the Projects Status field stayed at Backlog while the issue itself was closed. The move --status done mutation silently didn't persist, and success was reported on the item-edit exit code alone. A closed issue stuck at a non-Done status is a reliable tell of a dropped board mutation.

Fix

AC1 — verify-after-move (plugin/scripts/board/move.mjs)
runMove now RE-READS the item after the status mutation (new verifyStatusMoved) and confirms the Status field equals the requested key:

  • concrete mismatch → retry the mutation once, then fail loudly (non-zero exit + clear error naming the stuck status) rather than reporting a move that never took;
  • unreadable re-read (item-list index lag returning a fallback item with no field, feat(board): optional Phase field at create + findItemByIssue lag-fallback #114) → can't be confirmed or disproved, so it warns and proceeds unverified — lag alone never manufactures a false failure;
  • the existing no-op "already there" path is untouched (short-circuits before any mutation/verify).

AC3 — parentless follow-up warning (plugin/scripts/board/create.mjs)
runCreate warns when a non-top-level ticket (anything but epic/program) is left genuinely orphaned — reconciled against the issue's actual parent via getIssueNode (not just this call's --parent flag, so a resumed create of an already-reparented follow-up doesn't false-warn). Warning-only path per the ticket; the hint names the exact board reparent command. Real: follow-ups #185/#192 were filed parentless during the autopilot run.

Acceptance criteria

  • AC1 — the ritual re-reads the item after a done-move and fails loudly if the Status field is not done (esp. when the issue is closed).
  • AC2 — a test simulates a move whose re-read still shows the OLD status and asserts the verification exits non-zero (and retried once); plus an unreadable-lag case.
  • AC3 — follow-up creation emits a clear parentless warning (reconciled against real parent state), with warn / no-warn / already-parented coverage.

Verification (honest)

  • pnpm verify green locally: 42 files, 371 tests passing.
  • Full-branch forge:reviewer and forge:security run via subagents — security clean (zero critical/high); a reviewer Major on the AC3 warning firing off the flag rather than actual parent state was fixed in commit d8fc4e4 (reconcile against getIssueNode, added a resumed-already-parented test).
  • CI note: GitHub Actions minutes are exhausted for this run, so CI jobs fail at startup (0 steps executed) — infra, not this diff. Confirmed once via gh pr checks; not watched.

🤖 Generated with Claude Code

dngioidev and others added 2 commits July 23, 2026 01:54
…n on parentless follow-ups

The post-merge ritual moved an item with `move --status done` and reported
success on the item-edit's exit code alone. On iomanage #73 that mutation
silently didn't persist: the issue was closed but the Projects Status field
stayed at Backlog. A closed issue stuck at a non-Done status is a reliable
tell of a dropped board mutation.

AC1: runMove now RE-READS the item after the status mutation and confirms the
Status field equals the requested key. A concrete mismatch is retried once,
then fails loudly (non-zero exit + clear error) rather than reporting a move
that never took. An unreadable re-read (item-list index lag, #114) can be
neither confirmed nor disproved, so it warns and proceeds unverified instead
of manufacturing a false failure. Extracted as verifyStatusMoved.

AC3: create.mjs warns loudly when a non-top-level ticket (anything but
epic/program) is created without a --parent — the parentless-follow-up smell
(#185, #192 were filed orphan). Warning-only path with the exact reparent
command; returns a `parentless` flag for callers.

AC2: board.test.mjs simulates a move whose re-read still shows the old status
and asserts the verification fails non-zero (and retried once). Plus an
unreadable-lag case, and AC3 warn/no-warn coverage. Existing move + escalate
tests updated to stateful boards so a re-read reflects the mutation.

Closes #178

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…he --parent flag

Reviewer catch: the AC3 warning keyed off whether --parent was passed this
call, so a resumed create of an already-reparented follow-up would false-warn.
Now query the issue's real parent (getIssueNode) before warning — matching how
every other step in runCreate reconciles against actual state. Only the
eligible non-top-level, no-flag case pays the extra read; epics/programs skip
it entirely. Added coverage for the resumed-already-parented case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dngioidev
dngioidev merged commit 3e51a74 into main Jul 22, 2026
0 of 4 checks passed
@dngioidev
dngioidev deleted the fix/178-verify-done-move branch July 22, 2026 19:05
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.

Post-merge ritual must verify the board status field actually moved to Done

1 participant