Agents Builders

Archive completed tasks

Archived
archive-completed-tasks

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

QA URL

Production URL

devops task-board

Acceptance Criteria

  • Archive shipped tasks not in the last release
  • bin/release archive reclaims worktrees and prints summary
  • Last Release still links to archived task members
  • Dry-run previews archive and reclaim without executing

Expected Test Plan

  • unit
  • integration

Checks Run

  • [unit] archive_completed!/archivable_completed_slugs: archives shipped-not-in-last-release, keeps last-release members + active/blocked, no-release archives all, pre-conductor release_slug-less archived, idempotent
  • [integration] bin/release archive --dry-run previews plan+reclaim and mutates nothing; real run archives→reclaims→summarizes; reclaimed_count parses tool output
  • [integration] /deployments Last Release renders a working task_path chip for an archived member; archived task show page returns HTTP 200; shipped kickoff relabeled to Archive completed tasks

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.

  1. Shipped Archived
    Model
    Duration
    Tokens
    Cost
    Completed Jun 23, 17:13 · 4 days ago

Conversation

QA review feedback, agent handoffs, and follow-up notes for this task.

QA Feedback 5 days ago

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