feat(tasks): give task rows a canonical record identifier
Every work-record type carried a stable identifier except tasks, whose rows held only id, workplan_id, title, status and priority — nothing connecting a row to CUST-WP-0067-T01 in the file it came from. Matching was therefore by title, so a renamed heading looked like one task vanishing and another appearing, and the forge-derived reset had to refuse to touch tasks at all. Adds tasks.record_id (nullable: no migration can invent an identity for an existing row) and a backfill that reads the pairing from the repository files, where a task declares both its canonical id and its projection UUID. 5516 pairs across 121 repositories with zero conflicts; 4456 of 6073 cache task rows identified. Diff and reset now key on record_id where present, falling back to a title-prefixed key so an unidentified row stays visibly unidentified. Unknown stays unknown: a row the files do not claim keeps no identity and the reset keeps refusing to act on it, and an existing identity is never overwritten — a mismatch is recorded as a conflict rather than resolved. Refs STATE-WP-0083-T06 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
This commit is contained in:
parent
43ffe883c3
commit
8b207a991a
6 changed files with 325 additions and 6 deletions
|
|
@ -36,6 +36,12 @@ class Task(Base, TimestampMixin):
|
|||
nullable=False,
|
||||
index=True,
|
||||
)
|
||||
# Canonical work-record identifier, e.g. "CUST-WP-0067-T01" (ADR-007).
|
||||
# Nullable because rows created before STATE-WP-0083-T06 have none; only the
|
||||
# repository files know the mapping. Without it a task can be matched only by
|
||||
# title, so renaming a heading looks like one task vanishing and another
|
||||
# appearing.
|
||||
record_id: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
|
||||
title: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
status: Mapped[TaskStatus] = mapped_column(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue