Planning-bug record (logged by motir re-plan [MOTIR-1615](motir:cmr7r0ryt000604k00njnms0d), 2026-07-05). Lesson: notes.html #149 (verified by content on origin/main, 2026-08-04 — the card originally cited no entry number).
MOTIR-1615 was planned as upward-only status rollup (children → parent) — it even documented what it does NOT do — without considering the symmetric downward direction (a done parent completing its children). Automatic status derivation between a parent and its children is inherently bidirectional; scoping only one direction is a completeness-axis gap (a real-product status-sync feature keeps parent and children consistent BOTH ways). Surfaced by the user's re-plan directive: "when the parent is marked done by CI, all children should be marked done too."
Story re-scoped to bidirectional status derivation; added the downward-cascade service MOTIR-1647; the ADR MOTIR-1616, design MOTIR-1617, toggle field MOTIR-1618, Inngest job MOTIR-1621, settings UI MOTIR-1622, and both test subtasks MOTIR-1623 / MOTIR-1624 were swept to cover both directions.
As written 2026-07-06: workItemsService.applyStatusTransition (lib/services/workItemsService.ts:1489) is strictly canTransition-gated (IllegalTransitionError under restricted) with NO force/bypass, and the default workflow has no todo→done/blocked→done edge ⇒ the downward cascade cannot ride the legal transition graph and must ADD a privileged system-set path.
Re-executed at close-out against the card's own creation commit (92c3fe2d, the origin/main tip at 2026-07-06T01:18Z): async applyStatusTransition( was at :1489, and grep -c "system?: boolean" over that file returned 0. The claim was exact when made. Both halves have drifted since — see below.
Recorded in docs/decisions/status-derivation.md (Accepted 2026-08-03; filed under docs/decisions/, not the card's docs/adr/ — rung 2, all 22 sibling ADRs live there):
Project booleans, autoRollupParentStatus + autoCompleteChildrenOnParentDone, both default ON (recommendation adopted). One combined toggle rejected because it cannot express upward-only, the commonest preference.opts.system (recommendation adopted in direction, corrected in premise) — the bypass is REUSED, not added. See the correction below.origin/main)Shipped: 010ad0e8 feat(work-items): bidirectional parent↔child status derivation (MOTIR-1615) (#1816) (one Story→main PR) + 91d6f18e design(projects): … status-automation switches (MOTIR-1617) (#1815). Story and all nine linked cards are done.
applyStatusTransition is now at lib/services/workItemsService.ts:1629 (was :1489; the ADR quoted :1609 at its own HEAD 3d7a9831) — ordinary line rot, re-locate by content.opts.system?: boolean landed 2026-07-08 — two days after this card — via 212df810 feat(import): persist engine + import API routes (MOTIR-941) (#1566), whose setImportedStatus (:1578) is its first caller. grep -c "system?: boolean" now returns 1. The ADR §4 caught this at run time: "The card proposed extending applyStatusTransition with opts.system; it already exists."todo→done transition rows. lib/services/childStatusCascadeService.ts:133 passes { system: true } into the shared authority and adds no new bypass; its comment at :28 says so.prisma/schema.prisma:713 / :722, both @default(true). MOTIR-1625's edge shipped at lib/workflows/defaultWorkflow.ts:88 (['in_progress', 'done']) and is present on the live tenant's workflow.Drift class worth naming: a negative rung-2 claim can be correctly executed and true when written, then falsified by an unrelated sibling merge days later. Kept as a record note, not promoted and not written as a new notes.html entry — one occurrence, zero damage (the ADR self-corrected it downstream), and the standing defense is the one already in the corpus: re-execute every negative claim at close-out and paste the count, which is exactly what caught it here. notes.html #149 is left untouched: notes entries are historical records, and its lesson ("re-verify the reverse direction's mechanism against shipped reality") is strengthened by this, not contradicted.
No code action beyond the re-planned subtasks. Closed out on the ADR recording all three decisions.