docs(spec): FU-2a idempotent-ingest design + split FU-2b migration to #67

FU-2 split (chair decision 2026-05-30): FU-2a = pure-code (GAP-03 ON CONFLICT
upsert, GAP-06 write-time type-aware normalization, GAP-13 materialized
searchable flag); FU-2b (#67) = data-migration for GAP-07/08 (identifier
reconciliation + dedup) deferred as separate chair-involved task.

DB check 2026-05-30: ~52/56 internal_committee rows hold full citation in
case_number, >=1 duplicate (8047-23). Architecture verified vs 3+ sources
(PostgreSQL ON CONFLICT, DDD write-boundary normalization, materialized
validity flag). No identifier migration in FU-2a.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 19:56:07 +00:00
parent 44ae739031
commit a8b780765d
2 changed files with 177 additions and 23 deletions

View File

@@ -2056,9 +2056,9 @@
},
{
"id": "60",
"title": "[FU-2] ingest idempotent + מזהים קנוניים",
"description": "מפתח-upsert דטרמיניסטי + נרמול case_number בכתיבה + תיאום מספרים מעורבים.",
"details": "מכסה GAP-03,06,07,08,13. מספק INV-ING2/G3/G1/ID1/ID2/DM2/DM1. severity: Critical. סוג: קוד + מיגרציית-נתונים (דורש אישור-עלות). תלוי ב-FU-1.",
"title": "[FU-2a] ingest idempotent + נרמול-בכתיבה + searchable (pure-code)",
"description": "upsert ON CONFLICT על מפתח קנוני + נרמול case_number בכתיבה (type-aware) + דגל searchable מפורש. אפס מיגרציית-נתונים.",
"details": "מכסה GAP-03,06,13. מספק INV-ING2/G3/G1/ID1/DM1. severity: Critical. סוג: pure-code (schema-additive). תלוי ב-FU-1 (#59). FU-2b (#67) מטפל ב-GAP-07/08 בנפרד.",
"testStrategy": "",
"status": "pending",
"dependencies": [
@@ -2086,26 +2086,6 @@
"testStrategy": "",
"parentId": "60"
},
{
"id": 3,
"title": "[GAP-07] תיאום מספרי-תיק מעורבים (with-month canonical)",
"description": "מיגרציה חד-פעמית; הצורה עם-חודש קנונית (החלטת-יו\"ר).",
"dependencies": [],
"details": "INV-ID1",
"status": "pending",
"testStrategy": "",
"parentId": "60"
},
{
"id": 4,
"title": "[GAP-08] הסרת ציטוט-מלא כ-case_number",
"description": "רשומות עם ציטוט מלא כמזהה (legacy).",
"dependencies": [],
"details": "INV-DM2/ID2",
"status": "pending",
"testStrategy": "",
"parentId": "60"
},
{
"id": 5,
"title": "[GAP-13] שדה searchable מפורש",
@@ -2358,6 +2338,40 @@
}
],
"updatedAt": "2026-05-30T17:37:34.741136+00:00"
},
{
"id": "67",
"title": "[FU-2b] תיאום מזהים קנוניים + ניקוי ציטוט-כמזהה (data-migration, chair)",
"description": "מיגרציה חד-פעמית של ~52+ רשומות case_law עם ציטוט-מלא ב-case_number → מספר-בסיס מנורמל; dedup (למשל 8047-23 כפול); הכרעת צורה קנונית per-record.",
"details": "מכסה GAP-07,08. מספק INV-ID1/ID2/DM2. severity: High. סוג: DATA-MIGRATION + chair-decision (מספר רשמי per-record, with-month canonical). דורש: גיבוי, dry-run, סקירת-יו\"ר, reversibility. תלוי ב-FU-2a (#60, לצורך פונקציית הנרמול). מקור: בדיקת DB 2026-05-30 — internal_committee ~52/56 ציטוט-מלא, ≥1 dup (8047-23), 1 בלתי-פתיר (ערר אדלר/cited_only).",
"testStrategy": "",
"status": "pending",
"dependencies": [
"60"
],
"priority": "high",
"subtasks": [
{
"id": 1,
"title": "[GAP-07] תיאום מספרי-תיק מעורבים (with-month canonical)",
"description": "מיגרציה חד-פעמית; הצורה עם-חודש קנונית (החלטת-יו\"ר).",
"dependencies": [],
"details": "INV-ID1",
"status": "pending",
"testStrategy": "",
"parentId": "67"
},
{
"id": 2,
"title": "[GAP-08] הסרת ציטוט-מלא כ-case_number",
"description": "רשומות עם ציטוט מלא כמזהה (legacy).",
"dependencies": [],
"details": "INV-DM2/ID2",
"status": "pending",
"testStrategy": "",
"parentId": "67"
}
]
}
],
"metadata": {