Skip to content

[Work model] Align proposal conflict projection with ordered lifecycle and active-state effects #3012

Description

@Chris0Jeky

Carried out of #2926 so the residual keeps a tracker when that issue closes. Source-traced from the two follow-up comments on #2926 (originally from the #2951 review, comments 3983336933 and 3983545705). No runtime reproduction yet.

ProposalOperationContractValidator now projects a proposal's ordered column occupancy for the restore-lifecycle WIP contract (PR for #2926): card create, card move and both lifecycle actions fold into a per-column active-count delta, and a restore is measured against that. The warning surface was deliberately left out of that slice and still disagrees with the gate:

  1. ProposalConflictDetector.GetProjectedColumnChangesAsync projects only create and move operations, not lifecycle effects. A WIP-1 column holding one archived card, with a proposal containing restore-lifecycle(A) plus a create/move of B, can still render capacity as 1/1 (Ok tone) even though the contract now refuses the proposal at approve. The warning is wrong in the safe direction here - the gate refuses first - but Review shows a positive capacity signal for a proposal that cannot apply.
  2. When an outgoing move's target card is archived, the active-only column baseline excludes it while GetProjectedColumnChangesAsync still subtracts its source delta, so a move-out plus an incoming create/move can show false capacity alongside the stale-card warning. ProposalOperationContractValidator rejects archived non-lifecycle edits, so this is a preview-truth defect, not a demonstrated committed WIP bypass.

Acceptance

  • GetProjectedColumnChangesAsync applies ordered lifecycle effects (archive frees a slot, restore takes one) and active-state-aware move deltas, so the conflict/capacity rows agree with the contract gate.
  • Regression: a mixed lifecycle + create/move proposal renders a wip-limit warning rather than a positive capacity row.
  • Regression: a move-out whose card is archived does not produce a false capacity signal.
  • Control: a proposal that genuinely fits keeps its Ok capacity row.

Files backend/src/Taskdeck.Application/Services/ProposalConflictDetector.cs, backend/tests/Taskdeck.Application.Tests/Services/ProposalConflictDetectorTests.cs.

Proving check dotnet test backend/tests/Taskdeck.Application.Tests/Taskdeck.Application.Tests.csproj -c Release -m:1 --filter "FullyQualifiedName~ProposalConflictDetector"

Warning-surface truth only; no new WIP redesign is requested and the approve/execute gate is not in scope.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority IIThe active direction's next tranche: wedge capabilities, significant defects, near-term hardening.backendPrimary implementation impact in .NET API/domain/application/infrastructure.bugSomething isn't working

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions