Skip to content

T-YGJ1-schema-migration-sweeps-concurrent-tasks

Status: closed/superseded · Impact: medium · Complexity: small

Auto-generated from a /sdlc:task-work post-mortem. Review and promote to open/ready before picking up.

A schema bump (e.g. task v3→v4) bulk-stamps the entities that exist at the moment the migration runs. Tasks authored on a feature branch and merged concurrently with the bump miss the sweep — they land on main still at the old schema_version, and the drift only surfaces later when /sdlc:task-work picks one up and audit_entities fails the gate, forcing a mid-task bump. Closing this gap means a bump’s follow-through accounts for the in-flight corpus, not just the snapshot at migration time. Surfaced by T-1KPE-add-backlog-capture, which was authored at schema_version: '3', missed the v4 bulk-stamp, and required a mid-task bump to clear the resulting audit_entities drift.

LocationRole today
plugin/skills/entities-migrate/migrate_entities.tsApplies mechanical schema-drift fixes (including stamping schema_version) across docs/planning/<plural>/ at the moment it runs — a one-shot snapshot of the corpus.
plugin/skills/entities-migrate/SKILL.mdSpins up a worktree, runs the audit, stamps missing schema_version, opens a PR. Sees only entities present when invoked; tasks merged after (but authored at the old version) are not re-swept.
plugin/skills/entities-audit/SKILL.mdReports schema_version drift but is the late detector — it fires at task-pickup time inside the quality gate, after the stale task has merged.
docs/planning/tasks/Carries the active task corpus; a task merged on its own branch concurrently with a bump arrives stamped at the pre-bump version and becomes silent drift.

From T-1KPE-add-backlog-capture’s post-mortem: “The task was authored at schema_version: '3' and missed the v4 bulk-stamp, forcing a mid-task bump to clear an audit_entities drift — the v4 migration should sweep tasks created/merged concurrently with the bump.”

A schema bump’s migration leaves no stale-version task behind even when tasks merge concurrently. Concretely: the bump procedure (the schema-bump task template and/or /sdlc:entities-migrate) gains a follow-through that re-sweeps the corpus after the concurrently-open branches have merged — either by re-running the stamp after the bump’s own PR lands, or by an idempotent re-sweep the orchestrator triggers once the in-flight PRs that predate the bump have all merged. The re-sweep is mechanical (stamp-only) and idempotent, so running it twice is a no-op.

  1. Decide the trigger mechanism. These are candidate mechanisms, not a foregone manual sweep — pick during implementation: (a) the schema-bump task template gains an explicit final step “after concurrent in-flight PRs merge, re-run /sdlc:entities-migrate to stamp stragglers” (cheapest, explicit, but operator-driven); (b) make ongoing schema verification a step in the /sdlc:orchestrate loop — each tick the orchestrator runs the audit (and, when drift is purely a stamp-version straggler, an idempotent re-stamp) so concurrently-merged tasks are caught on the next tick without an operator remembering to re-sweep; (c) run the sweep/verification as a GitHub Action / CI check — a workflow (on push to main, and/or scheduled) runs the audit and either fails the check on drift or opens a stamp PR, so the corpus is verified continuously rather than only at bump time or task pickup; (d) audit_entities / /sdlc:setup runs the stamp opportunistically. Options (b) and (c) make verification continuous (no reliance on remembering to re-sweep) at the cost of standing infrastructure; (a) is the cheapest one-shot. Whichever is chosen, document the re-sweep as idempotent so it’s safe to repeat.
  2. Confirm migrate_entities.ts’s stamp pass is idempotent on already-current entities (re-running stamps nothing new) so a re-sweep is a clean no-op when there are no stragglers — this is the precondition that makes any of (a)-(d) safe to run repeatedly.
  3. Implement the chosen trigger (template step, orchestrate-loop step, CI workflow, or opportunistic stamp) and add a fixture: a corpus where one task is one version behind after a bump, re-swept to current; plus an already-current corpus that stays unchanged.

Root cause note. The recurring stale-version drift is a symptom of modeling entity state as files (frontmatter the migration must physically rewrite across the corpus). The deeper fix — an append-only event log so state is derived rather than bulk-rewritten — is tracked separately by the append-only event-log backlog item (filed in PR #151). This task closes the coverage gap for the file-based model we have today; it does not block on that larger change.

The first two rows hold regardless of which trigger mechanism is chosen; the remaining rows depend on the Approach-1 decision (one of them, not all).

LocationKindChange
plugin/skills/entities-migrate/migrate_entities.tsmodifyEnsure / assert the stamp pass is idempotent so a re-sweep is a no-op when clean.
plugin/skills/entities-migrate/tests/modifyFixture: a one-version-behind straggler is stamped to current on re-sweep; an already-current corpus is unchanged.
plugin/skills/entities-migrate/SKILL.mdmodify(trigger (a)) Document the post-bump re-sweep for concurrently-merged stragglers; note idempotency.
plugin/skills/orchestrate/SKILL.mdmodify(trigger (b)) Add an audit/re-stamp step to the orchestrate tick so concurrently-merged stragglers are caught the next tick.
.github/workflows/new(trigger (c)) A workflow that runs audit_entities on push to main (and/or scheduled), failing on drift or opening a stamp PR.
  • AC-1: A task that merges to main at the pre-bump schema_version after a bump has run is brought to the current version by the documented re-sweep, without a /sdlc:task-work pickup being required to surface the drift.
  • AC-2: Re-running the stamp pass against an already-current corpus produces no diff (idempotent no-op).
  • AC-3: The schema-bump procedure (template and/or /sdlc:entities-migrate SKILL) documents the concurrent-merge re-sweep so a future bump’s author follows it.
  • Blocking concurrent merges during a bump (a merge-queue / freeze policy) — heavier coordination than this stamp-sweep follow-through.
  • Changing what a bump migrates beyond schema_version stamping — this task is about coverage of the existing stamp, not new migration rules.
  • none

Spawned by /sdlc:task-work post-mortem of T-1KPE-add-backlog-capture on 2026-05-27.

Section titled “Related (distinct) observed case — 2026-06-02”

A sibling concurrency hazard surfaced during the .claude/->TS migration dogfood: two concurrent /sdlc:task-work PRs, squash-merged out of dispatch order, produced a phantom merge conflict on the task file. Because task-state commits (verify / start / record-PR) land on main directly, the lagging PR carried the same task-file edits via a divergent commit ancestry that GitHub’s 3-way merge could not auto-reconcile; git rebase --onto origin/main cleared it (the duplicate commits were dropped by patch-equivalence, leaving only the real work commits). This is a distinct root cause from this task’s schema-stamp gap but the same family (concurrent task PRs + main-side coordination). A fix likely lives in extending T-61OI-check-ancestry-flags-stale-base (auto-detect the stale base) and/or auto-rebasing a lagging task PR before merge.

Bullet: The task was authored at schema_version: ‘3’ and missed the v4 bulk-stamp, forcing a mid-task bump to clear an audit_entities drift — the v4 migration should sweep tasks created/merged concurrently with the bump. Keywords searched: schema_version, audit_entities, concurrently, bulk-stamp, migration, authored, mid-task, forcing Excluded: 2026-05-27-add-backlog-capture Top candidates (score / status / headline):

  • 39 / closed/done / 2026-05-19-consolidate-task-status-enum — Consolidate task status enum and migrate existing instances
  • 36 / closed/done / 2026-05-19-implement-entities-migrate — Implement /sdlc:entities-migrate to apply mechanical schema-drift fixes
  • 30 / planning/needs-definition / 2026-05-23-archive-closed-tasks-in-subdirectory — Move closed tasks to docs/planning/tasks/archive/; default scans to active-only
  • 22 / closed/done / 2026-05-22-restructure-task-touchpoints-as-a-table-with-symbol-dir-glob — Restructure task touchpoints as a table with symbol/dir/glob citation grammar
  • 20 / planning/draft / 2026-05-25-add-sdlc-lease-migrate-and-control-plane-bootstrap — Add sdlc lease migrate one-shot cutover (with control-plane bootstrap) Decision: SPAWNED

← Back to Tasks