Skip to content

[Feature] Ticket-first gate for database migrations + /migration skill + migration AgDR template #59

@atlas-apex

Description

@atlas-apex

User Story

As a backend engineer or data engineer working on a managed project, I want ApexStack to refuse edits to database migration files unless I have an open ticket with the right label and a linked migration AgDR, so that high-blast-radius schema and data changes get the same ticket-first discipline as code changes.

Motivation

Migrations are high-blast-radius: data loss, downtime, locks on production tables, cross-service consumer coordination. They deserve dedicated ticket scrutiny and a separate decision record.

Today ApexStack has require-active-ticket.sh which enforces "some" ticket exists before edits. But for migrations, "some" isn't enough — a migration should link to a ticket that captures the rollback plan, downtime estimate, and affected tables. The existing gate treats a migration PR like any other bug-fix PR.

Incidents this would have caught (all real, across the session of 2026-04-14):

Acceptance Criteria

Hook — require-migration-ticket.sh

  • Fires PreToolUse on Write/Edit to paths configured as migration paths
  • Default path patterns (overridable per project via .claude/project-config.json key migration_paths):
    • `backend/scripts/migrate-*.ts`
    • `backend/scripts/migrate-*.js`
    • `backend/scripts/migrations/**`
    • `*.sql` under any `migrations/` directory
    • `backend/template.yaml` changes that ADD or MODIFY `AWS::DynamoDB::Table` resources (detected by sam validate diff — complex, may defer to manual ticket check in v1)
    • `infrastructure/**` changes that ADD or MODIFY `aws_dynamodb_table`, `aws_rds_cluster`, `aws_rds_instance` (Terraform)
    • Prisma schema file, TypeORM migration directories, Alembic migrations (future projects)
  • Before allowing the edit, verify:
    • An OPEN GitHub issue exists in the tracker repo
    • The issue has the label `migration` (or `database` — configurable per-project)
    • The issue body includes a reference to an AgDR at `docs/agdr/AgDR-\d+-.migration.\.md`
  • If any check fails, block with a helpful message pointing to the /migration skill
  • Exempt paths: anything under `.claude/`, `docs/`, `.md`, `.example` (template files)

/migration skill

  • Creates a structured migration ticket with the right shape in one guided flow
  • Prompts for:
    • Migration type (schema / data / sql / orm)
    • Affected tables/entities (list)
    • Rollback plan (required — free text, must be non-empty)
    • Estimated downtime (none / seconds / minutes / hours + reasoning)
    • Cross-service consumers that need coordination (list or "none")
    • Data volume estimate (rough row/item count)
  • Creates the issue with title `[Migration] : `, labels `migration` + priority
  • Also creates the AgDR file at `docs/agdr/AgDR-NNNN-migration-.md` from the migration-specific template (see next AC)
  • Returns the ticket URL + AgDR path

Migration AgDR template — templates/agdr-migration.md

  • Extends the base AgDR template with migration-specific fields:
    • Affected tables/entities
    • Rollback plan (explicit section, not buried under Consequences)
    • Downtime estimate + reasoning
    • Cross-service consumers
    • Data volume
    • Testing plan (staging first? smoke script? canary?)
    • Observability: what metrics/logs will confirm success?
  • Lives at `templates/agdr-migration.md`, referenced by the `/migration` skill

Docs

  • Update `.claude/rules/workflow-gates.md` with a new gate row: "Migration → any edit to migration paths requires labeled migration ticket + linked AgDR"
  • Update `CLAUDE.md` to mention the `/migration` skill in the skill list
  • Add a short section to `workflows/sdlc.md` describing the migration sub-workflow (ticket → AgDR → dev smoke → staging verify → prod apply with rollback ready)

Design Notes

No UI changes. Output is:

  • Hook blocking messages (terminal text, actionable)
  • /migration skill: conversational prompts, confirmation preview, structured issue body
  • AgDR template: markdown with sections labeled clearly

Out of Scope

  • Auto-generating migration content (the engineer still writes the migration)
  • Automated rollback execution (captured in the plan, not executed by ApexStack)
  • Cross-project migration coordination (multi-repo orchestration — too complex for v1)
  • Integration with specific migration tools (Prisma, Alembic, Flyway) — tool-specific path patterns are configurable, but ApexStack doesn't wrap the tool

Rollout

  • Phase 1: hook + `/migration` skill + AgDR template (one PR)
  • Phase 2: auto-detect DynamoDB table changes in SAM / Terraform via sam validate / terraform plan introspection (deferred — complex, path-pattern heuristic is 80% of the value)

Effort Estimate

TBD — likely 1-2 days for Phase 1 across hook, skill, template, docs.

Priority

P1 — the pattern that prompted this (silent 500 from answer transaction collision) is the exact class of bug that a dedicated migration-class review path catches. Not urgent (no active migration in flight), but should be in place before the next managed project lands a migration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — material gap or user-impactingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions