Created
Jun 22, 18:22
Started
Jun 22, 18:22
Completed
Jun 22, 18:58
DevOps handoff
Type
Feature
Shape
backend
Worktree Slug
archive-completed-tasks
Repositories
mcritchie-studio
Release Train
—
Branch
feat/archive-completed-tasks
Acceptance Criteria
Expected Test Plan
Checks Run
Agent Context
Close the DevOps loop: shipped -> archived. New 'bin/release archive' command + relabel the SHIPPED kickoff. RULE (operator-confirmed): archive every task with stage=shipped that is NOT a member of Release.last_shipped; NEVER touch active (designed/building/submitted/reviewed/assembled) or blocked tasks. (1) MODEL/CONDUCTOR (testable): add Release::Conductor.archive_completed! that computes keep_slugs = Release.last_shipped&.tasks&.pluck(:slug) || [], then archives Task.where(stage: 'shipped').where.not(slug: keep_slugs) via task.archive! (exists, task.rb:268, stage->archived). Also add a PURE preview method (e.g. archivable_completed_slugs) returning the slugs that WOULD be archived, so --dry-run previews without mutating. Return {archived:[slugs], kept:[slugs], count:N}. Idempotent (re-run archives nothing new). (2) bin/release archive subcommand following existing bin/release conventions (PROD default per PR4, --local, --yes, confirm() before the bulk archive unless --yes/--dry-run, conductor() for the board write like prepare/ship, wire ARGV via the Release::Cli module added in R3): real run -> conductor('Release::Conductor.archive_completed!') then 'bin/agent-worktree cleanup --reclaim --yes' (reclaims merged/shipped worktrees INCLUDING squash-merged legacy ones) then summary 'Archived N tasks; reclaimed M worktrees; SHIPPED -> K'; --dry-run -> read-only preview of archivable slugs + 'agent-worktree cleanup --reclaim' dry-run, nothing executed. (3) UI: app/helpers/application_helper.rb devops_kickoffs change 'shipped' => 'Archive completed tasks' (was 'Cleanup worktrees'); update any helper test asserting the old label. (4) LAST RELEASE LINKS SURVIVE ARCHIVING — lock with a test: rel.tasks fetches members by release_slug regardless of stage, and member chips use task_path(slug); verify _last_release/_release_summary render the member chip + working link even when a member is archived, and the task show page renders an archived task (200). TESTS [unit]: archive_completed! archives shipped-not-in-last-release, KEEPS last-release members, KEEPS active+blocked, handles no-last-release + old release_slug-less shipped tasks, idempotent. [integration]: bin/release archive end-to-end archives the right set (dry-run previews, real run mutates) + Last Release renders an archived member's chip/link + GET archived task page 200.
Stage Timeline
Who handled each stage, the time it took (measured), and the model / tokens / cost reported (best-effort) — plus who's on it right now. — means the agent didn't report that metric.
Conversation
QA review feedback, agent handoffs, and follow-up notes for this task.
Logic APPROVED + independently verified: archivable == shipped MINUS Release.last_shipped members exactly (cross-checked vs raw SQL), zero non-shipped tasks reachable (can't touch active/blocked), idempotent, no-last-release archives all shipped, dry-run mutates nothing, Last-Release archived-member link test is real. Suite green (81 model/cli/helper + 42 controller, 0 failures). BLOCK is narrow: this PR makes shipped->archived a real transition but leaves 3 docs contradicting it. (1) app/views/tasks/stages.html.erb:63 footer still reads 'Archived is terminal trash - abandoned, never shipping' - now self-contradicts the same page's shipped row you changed (shipped tasks move to archived). User-facing. (2) app/models/task.rb:10 same stale 'abandoned, never shipping' comment. (3) docs/agents/system/devops-cycle-design.md:357 still documents the OLD 'Cleanup worktrees' kickoff + 'The deployment is done.' - update to 'Archive completed tasks' + the bin/release archive shipped->archived loop conclusion (it's the canonical Full spec). Fix all three in this PR (leave docs cleaner than you found it), then re-submit - logic needs no changes.
Sealed-bid sizing
Edit →Alex (PM)
—
Avi (PO)
—
Dev
—
Actual
—
We emailed a one-tap sign-in link to . It expires shortly and can only be used once.
No email? Check spam, or close this and try again.