clean-house sweep: anchor drift, app/-prefix paths, D-59 sunset
Fixes 3 substring-truncated cross-reference anchors so they match the full heading slug: - D-3 link in architecture.md - D-40 link in process.md (heading gained the [SUPERSEDED] tag) - Q-15 link in questions-process.md Strips the legacy `app/` prefix from path references in 5 files — the dirs were flattened to repo root in the Flutter rebuild (D-56). Three "was `app/...`" historical references in D-5 and D-56 are deliberately preserved as record of the dissolution. Adds an inline (tracked in T-88) note to D-59 so the "must track dugite-native releases for security updates" intent is wired to a backlog item — RULE-SUNSET-WITHOUT-TICKET would otherwise keep flagging it on every sweep. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+153
-112
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"exported_at": "2026-05-06T13:45:07Z",
|
||||
"exported_at": "2026-05-06T14:40:38Z",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "D-1",
|
||||
@@ -9,7 +9,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-3",
|
||||
@@ -19,7 +19,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-4",
|
||||
@@ -29,7 +29,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-5",
|
||||
@@ -39,7 +39,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-6",
|
||||
@@ -49,7 +49,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-7",
|
||||
@@ -59,7 +59,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-8",
|
||||
@@ -69,7 +69,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-9",
|
||||
@@ -79,7 +79,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-10",
|
||||
@@ -89,7 +89,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-11",
|
||||
@@ -99,7 +99,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-12",
|
||||
@@ -109,7 +109,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-13",
|
||||
@@ -119,7 +119,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-14",
|
||||
@@ -129,7 +129,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-15",
|
||||
@@ -139,7 +139,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-16",
|
||||
@@ -149,7 +149,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-17",
|
||||
@@ -159,7 +159,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-18",
|
||||
@@ -169,7 +169,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-19",
|
||||
@@ -179,7 +179,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-20",
|
||||
@@ -189,7 +189,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/accessibility.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-21",
|
||||
@@ -199,7 +199,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/accessibility.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-22",
|
||||
@@ -209,7 +209,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/accessibility.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-23",
|
||||
@@ -219,7 +219,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-24",
|
||||
@@ -229,7 +229,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-25",
|
||||
@@ -239,7 +239,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-26",
|
||||
@@ -249,7 +249,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-27",
|
||||
@@ -259,7 +259,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-28",
|
||||
@@ -269,7 +269,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-29",
|
||||
@@ -279,7 +279,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-30",
|
||||
@@ -289,7 +289,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-31",
|
||||
@@ -299,7 +299,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-32",
|
||||
@@ -309,7 +309,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-33",
|
||||
@@ -319,7 +319,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-34",
|
||||
@@ -329,7 +329,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-35",
|
||||
@@ -339,7 +339,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-36",
|
||||
@@ -349,7 +349,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-37",
|
||||
@@ -359,7 +359,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-38",
|
||||
@@ -369,7 +369,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-39",
|
||||
@@ -379,7 +379,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-40",
|
||||
@@ -389,7 +389,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-41",
|
||||
@@ -399,7 +399,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-42",
|
||||
@@ -409,7 +409,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-43",
|
||||
@@ -419,7 +419,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-44",
|
||||
@@ -429,7 +429,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-45",
|
||||
@@ -439,7 +439,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-46",
|
||||
@@ -449,7 +449,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-47",
|
||||
@@ -459,7 +459,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-48",
|
||||
@@ -469,7 +469,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-49",
|
||||
@@ -479,7 +479,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-50",
|
||||
@@ -489,7 +489,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-51",
|
||||
@@ -499,7 +499,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-52",
|
||||
@@ -509,7 +509,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-53",
|
||||
@@ -519,7 +519,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-54",
|
||||
@@ -529,7 +529,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-55",
|
||||
@@ -539,7 +539,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-23",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-56",
|
||||
@@ -549,7 +549,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-23",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-57",
|
||||
@@ -559,7 +559,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-23",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-58",
|
||||
@@ -569,7 +569,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-23",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-59",
|
||||
@@ -579,7 +579,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-25",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-60",
|
||||
@@ -589,7 +589,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-26",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-61",
|
||||
@@ -599,7 +599,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-26",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-62",
|
||||
@@ -609,7 +609,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-26",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-63",
|
||||
@@ -619,7 +619,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-26",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "D-64",
|
||||
@@ -629,7 +629,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-05-03",
|
||||
"file_path": "decisions/architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "D-65",
|
||||
@@ -639,7 +639,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-26",
|
||||
"file_path": "decisions/tooling.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-1",
|
||||
@@ -648,7 +648,7 @@
|
||||
"title": "Authorisation granularity on the IPC socket",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "Q-2",
|
||||
@@ -657,7 +657,7 @@
|
||||
"title": "Back-pressure on event streams",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-3",
|
||||
@@ -666,7 +666,7 @@
|
||||
"title": "Event persistence + audit/undo",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-4",
|
||||
@@ -675,7 +675,7 @@
|
||||
"title": "`.canvas` schema compatibility with Obsidian",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-5",
|
||||
@@ -684,7 +684,7 @@
|
||||
"title": "IPC wire-format stability + `schema_version:`",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-6",
|
||||
@@ -693,7 +693,7 @@
|
||||
"title": "Window chrome — native frame vs frameless custom",
|
||||
"status": "resolved",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-7",
|
||||
@@ -702,7 +702,7 @@
|
||||
"title": "macOS app bundle signing / notarisation",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-8",
|
||||
@@ -711,7 +711,7 @@
|
||||
"title": "Extension API shape — widgets, subcommands, both?",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-9",
|
||||
@@ -720,7 +720,7 @@
|
||||
"title": "Lua runtime vendoring",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-10",
|
||||
@@ -729,7 +729,7 @@
|
||||
"title": "Extension manifest `schema_version:`",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-extensions.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-11",
|
||||
@@ -738,7 +738,7 @@
|
||||
"title": "Coverage gates — hard thresholds vs soft reporting",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-12",
|
||||
@@ -747,7 +747,7 @@
|
||||
"title": "Screen-reader automation (axe-core via Playwright)",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-testing.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-13",
|
||||
@@ -756,7 +756,7 @@
|
||||
"title": "Web production-mode a11y",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-accessibility.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "Q-14",
|
||||
@@ -765,7 +765,7 @@
|
||||
"title": "i18n plurals / gender / date-format tooling",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-accessibility.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:05"
|
||||
},
|
||||
{
|
||||
"id": "Q-15",
|
||||
@@ -774,7 +774,7 @@
|
||||
"title": "Editor tab — full LSP vs tree-sitter-only highlight",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-16",
|
||||
@@ -783,7 +783,7 @@
|
||||
"title": "`tree-sitter-dart` grammar maintenance",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-17",
|
||||
@@ -792,7 +792,7 @@
|
||||
"title": "Icon set growth",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-18",
|
||||
@@ -801,7 +801,7 @@
|
||||
"title": "Theme hot-reload in release builds",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-19",
|
||||
@@ -810,7 +810,7 @@
|
||||
"title": "(withdrawn)",
|
||||
"status": "resolved",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-20",
|
||||
@@ -819,7 +819,7 @@
|
||||
"title": "Kernel DB service — namespaced SQL access?",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-process.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-21",
|
||||
@@ -828,7 +828,7 @@
|
||||
"title": "Pql absorbs planning vs keeps separate",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-22",
|
||||
@@ -837,7 +837,7 @@
|
||||
"title": "Ticket persistence strategy",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-23",
|
||||
@@ -846,7 +846,7 @@
|
||||
"title": "SSH-remote development — run clide against a remote workspace",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-25",
|
||||
@@ -855,7 +855,7 @@
|
||||
"title": "Body text face — mono everywhere vs Josefin Sans UI + mono code",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-26",
|
||||
@@ -864,7 +864,7 @@
|
||||
"title": "Small screen layout (\u003c 1000px)",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-27",
|
||||
@@ -873,7 +873,7 @@
|
||||
"title": "Two-editor split",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-28",
|
||||
@@ -882,7 +882,7 @@
|
||||
"title": "Terminal strip scope — shell only or logs/errors/tests",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-29",
|
||||
@@ -891,7 +891,7 @@
|
||||
"title": "Branch picker location",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-30",
|
||||
@@ -900,7 +900,7 @@
|
||||
"title": "Focus behavior when editor is dirty and viewer is peeked",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "Q-31",
|
||||
@@ -909,7 +909,7 @@
|
||||
"title": "XWayland fallback for frameless — proper Wayland protocol needed",
|
||||
"status": "open",
|
||||
"file_path": "decisions/questions-architecture.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-2",
|
||||
@@ -919,7 +919,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-20",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-3",
|
||||
@@ -929,7 +929,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-4",
|
||||
@@ -939,7 +939,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-5",
|
||||
@@ -949,7 +949,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-6",
|
||||
@@ -959,7 +959,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-7",
|
||||
@@ -969,7 +969,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-8",
|
||||
@@ -979,7 +979,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-9",
|
||||
@@ -989,7 +989,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-10",
|
||||
@@ -999,7 +999,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-11",
|
||||
@@ -1009,7 +1009,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-21",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
},
|
||||
{
|
||||
"id": "R-12",
|
||||
@@ -1019,7 +1019,7 @@
|
||||
"status": "active",
|
||||
"date": "2026-04-22",
|
||||
"file_path": "decisions/rejected.md",
|
||||
"synced_at": "2026-05-05 13:11:46"
|
||||
"synced_at": "2026-05-06 14:37:06"
|
||||
}
|
||||
],
|
||||
"decision_refs": [
|
||||
@@ -1051,7 +1051,7 @@
|
||||
"source_id": "D-16",
|
||||
"target_id": "D-19",
|
||||
"ref_type": "references",
|
||||
"note": "**Decision:** Bundled extensions (every `app/lib/builtin/\u003cname\u003e`) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the `ptyc`-peer Lua runtime (s..."
|
||||
"note": "**Decision:** Bundled extensions (every `lib/builtin/\u003cname\u003e`) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the `ptyc`-peer Lua runtime (see [..."
|
||||
},
|
||||
{
|
||||
"source_id": "D-18",
|
||||
@@ -1105,13 +1105,13 @@
|
||||
"source_id": "D-39",
|
||||
"target_id": "D-40",
|
||||
"ref_type": "references",
|
||||
"note": "**Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-planning-vs-keep..."
|
||||
"note": "**Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-superseded-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-plann..."
|
||||
},
|
||||
{
|
||||
"source_id": "D-39",
|
||||
"target_id": "Q-21",
|
||||
"ref_type": "references",
|
||||
"note": "**Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-planning-vs-keep..."
|
||||
"note": "**Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-superseded-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-plann..."
|
||||
},
|
||||
{
|
||||
"source_id": "D-39",
|
||||
@@ -1597,7 +1597,7 @@
|
||||
"source_id": "Q-16",
|
||||
"target_id": "Q-15",
|
||||
"ref_type": "references",
|
||||
"note": "**Context:** If tree-sitter is the Tier-2 answer ([Q-15](#q-15-editor-tab-full-lsp-vs-tree-sitter-only)), grammar sourcing matters."
|
||||
"note": "**Context:** If tree-sitter is the Tier-2 answer ([Q-15](#q-15-editor-tab-full-lsp-vs-tree-sitter-only-highlight)), grammar sourcing matters."
|
||||
},
|
||||
{
|
||||
"source_id": "Q-17",
|
||||
@@ -2705,10 +2705,31 @@
|
||||
"id": "T-86",
|
||||
"type": "task",
|
||||
"title": "codify UI spacing constants (gaps, paddings, control sizes)",
|
||||
"status": "in_progress",
|
||||
"status": "done",
|
||||
"priority": "medium",
|
||||
"created_at": "2026-05-06 13:28:58",
|
||||
"updated_at": "2026-05-06 13:38:44"
|
||||
"updated_at": "2026-05-06 13:45:12"
|
||||
},
|
||||
{
|
||||
"id": "T-87",
|
||||
"type": "bug",
|
||||
"title": "kill secondary Claude tmux sessions on tab close and on app shutdown",
|
||||
"description": "D-41 lifecycle contract: \"closing a secondary kills that tmux session\" and \"secondary numbering (-1, -2, ...) resets between clide runs since ephemeral state is lost\" — the second clause only holds if non-primary tmux sessions are reaped on app shutdown.\n\nNeither happens today.\n\n**Gap 1 — tab close is UI-only.** `ClaudeSessionHostState` (lib/builtin/claude/src/claude_session_host.dart:18) builds tabs via MultitabController; closing a secondary just removes the entry. No `tmux kill-session` shellout anywhere in lib/builtin/claude/ or lib/src/pty/ (verified by grep for `kill-session` / `killSession` / `tmux kill`).\n\n**Gap 2 — app shutdown leaks secondaries.** Nothing reaps `clide-claude-\u003crepohash\u003e-N` sessions when the app exits. Repro: spawn two secondaries, quit clide, `tmux -L clide list-sessions` still shows them. Confirmed live: 4 sessions on the clide socket (primary + -1, -2, -3) survived prior runs.\n\n**Acceptance:**\n- Closing a secondary tab in the Claude pane runs `tmux -L clide kill-session -t \u003cname\u003e` for that secondary's session name (use existing `secondarySessionName(repoRoot, n)`).\n- App shutdown enumerates `clide-claude-\u003crepohash\u003e-*` sessions on the clide socket and kills the non-primary ones. Primary is left detached (D-41 explicit).\n- `_nextSecondary` index policy: keep the in-process counter for the running app; cold-start always begins at 1 because secondary sessions are gone.\n- Add a test that exercises the close path and asserts the kill-session command was invoked (mock the tmux runner).\n\n**Out of scope:** primary lifecycle (unchanged — survives shutdown by design), general-purpose terminal panes (no tmux wrapping per D-41), Windows behaviour.",
|
||||
"status": "in_progress",
|
||||
"priority": "high",
|
||||
"decision_ref": "D-41",
|
||||
"created_at": "2026-05-06 13:46:07",
|
||||
"updated_at": "2026-05-06 13:46:29"
|
||||
},
|
||||
{
|
||||
"id": "T-88",
|
||||
"type": "task",
|
||||
"title": "track dugite-native upstream releases for security updates",
|
||||
"status": "backlog",
|
||||
"priority": "low",
|
||||
"decision_ref": "D-59",
|
||||
"created_at": "2026-05-06 14:34:35",
|
||||
"updated_at": "2026-05-06 14:34:35"
|
||||
}
|
||||
],
|
||||
"ticket_deps": null,
|
||||
@@ -4111,6 +4132,26 @@
|
||||
"old_value": "backlog",
|
||||
"new_value": "in_progress",
|
||||
"changed_at": "2026-05-06 13:38:44"
|
||||
},
|
||||
{
|
||||
"ticket_id": "T-86",
|
||||
"field": "status",
|
||||
"old_value": "in_progress",
|
||||
"new_value": "done",
|
||||
"changed_at": "2026-05-06 13:45:12"
|
||||
},
|
||||
{
|
||||
"ticket_id": "T-87",
|
||||
"field": "description",
|
||||
"new_value": "D-41 lifecycle contract: \"closing a secondary kills that tmux session\" and \"secondary numbering (-1, -2, ...) resets between clide runs since ephemeral state is lost\" — the second clause only holds if non-primary tmux sessions are reaped on app shutdown.\n\nNeither happens today.\n\n**Gap 1 — tab close is UI-only.** `ClaudeSessionHostState` (lib/builtin/claude/src/claude_session_host.dart:18) builds tabs via MultitabController; closing a secondary just removes the entry. No `tmux kill-session` shellout anywhere in lib/builtin/claude/ or lib/src/pty/ (verified by grep for `kill-session` / `killSession` / `tmux kill`).\n\n**Gap 2 — app shutdown leaks secondaries.** Nothing reaps `clide-claude-\u003crepohash\u003e-N` sessions when the app exits. Repro: spawn two secondaries, quit clide, `tmux -L clide list-sessions` still shows them. Confirmed live: 4 sessions on the clide socket (primary + -1, -2, -3) survived prior runs.\n\n**Acceptance:**\n- Closing a secondary tab in the Claude pane runs `tmux -L clide kill-session -t \u003cname\u003e` for that secondary's session name (use existing `secondarySessionName(repoRoot, n)`).\n- App shutdown enumerates `clide-claude-\u003crepohash\u003e-*` sessions on the clide socket and kills the non-primary ones. Primary is left detached (D-41 explicit).\n- `_nextSecondary` index policy: keep the in-process counter for the running app; cold-start always begins at 1 because secondary sessions are gone.\n- Add a test that exercises the close path and asserts the kill-session command was invoked (mock the tmux runner).\n\n**Out of scope:** primary lifecycle (unchanged — survives shutdown by design), general-purpose terminal panes (no tmux wrapping per D-41), Windows behaviour.",
|
||||
"changed_at": "2026-05-06 13:46:26"
|
||||
},
|
||||
{
|
||||
"ticket_id": "T-87",
|
||||
"field": "status",
|
||||
"old_value": "backlog",
|
||||
"new_value": "in_progress",
|
||||
"changed_at": "2026-05-06 13:46:29"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ A11y + i18n are Tier-0 contracts, not Tier-6 polish.
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Every widget primitive wraps its interaction surface in a `Semantics` node at the point of creation. A11y coverage is a test-time gate (`ci/test_a11y.sh`), not a post-hoc polish pass. `ensureSemantics()` fires at app boot; Flutter's semantics tree is always populated.
|
||||
- **Rationale:** Retrofitting a11y onto a grown UI is what every project that skips this promises to do later and then doesn't. Making it a Tier-0 contract costs one `Semantics` line per primitive and a semantic-coverage test; postponing costs a rewrite.
|
||||
- **Cost:** Widget authors maintain correct labels; tests reject new primitives without semantics. Enforced by `app/test/a11y/` coverage tests.
|
||||
- **Cost:** Widget authors maintain correct labels; tests reject new primitives without semantics. Enforced by `test/a11y/` coverage tests.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
### D-21: i18n is a Tier-0 contract (fframe pattern + locale-fallback chain)
|
||||
|
||||
@@ -13,7 +13,7 @@ Core, rendering, IPC, kernel, panel manager.
|
||||
|
||||
### D-8: Feature-first folder layout
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Under `app/lib/`, organise by feature (`kernel/`, `extension/`, `widgets/`, `builtin/<name>/`) rather than by layer (`models/`, `views/`, `controllers/`). Private implementation lives under each feature's `src/`; the feature's public surface is a barrel file at the feature root (e.g. `app/lib/kernel/kernel.dart`).
|
||||
- **Decision:** Under `lib/`, organise by feature (`kernel/`, `extension/`, `widgets/`, `builtin/<name>/`) rather than by layer (`models/`, `views/`, `controllers/`). Private implementation lives under each feature's `src/`; the feature's public surface is a barrel file at the feature root (e.g. `lib/kernel/kernel.dart`).
|
||||
- **Rationale:** Features grow and get deleted as units; layer-first layouts fragment a feature across three directories and make deletions risky. Matches extensions-as-features (every extension already has its own folder).
|
||||
- **Cost:** Imports cross features only via the barrel — enforce by review, no automated check yet.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
@@ -89,7 +89,7 @@ Core, rendering, IPC, kernel, panel manager.
|
||||
|
||||
### D-4: Ignore file strategy
|
||||
- **Date:** 2026-04-20 (was ADR 0004; ported from the claudian lineage)
|
||||
- **Decision:** One mechanism everywhere: the `ignore_files:` list in `.pql/config.yaml`. Ordered list of gitignore-shaped files; later entries win on per-pattern conflicts. pql defaults to `ignore_files: [.gitignore]`. Per [D-3](#d-3-pql-as-supporter-tool), clide writes the list on load — `[.gitignore, .clideignore]` if `.clideignore` exists, else `[.gitignore]`. `.clideignore` carries **only** the clide-specific deviations from `.gitignore` (supports `!pattern` negations); never duplicate gitignore's contents. Walker magic: none except `.git/` — every other tool-owned dir (`.pql/`, `.clide/`) is added to `.gitignore` at install time; exclusion flows through the normal `ignore_files:` chain.
|
||||
- **Decision:** One mechanism everywhere: the `ignore_files:` list in `.pql/config.yaml`. Ordered list of gitignore-shaped files; later entries win on per-pattern conflicts. pql defaults to `ignore_files: [.gitignore]`. Per [D-3](#d-3-pql-as-supporter-tool-clide-wraps-never-duplicates), clide writes the list on load — `[.gitignore, .clideignore]` if `.clideignore` exists, else `[.gitignore]`. `.clideignore` carries **only** the clide-specific deviations from `.gitignore` (supports `!pattern` negations); never duplicate gitignore's contents. Walker magic: none except `.git/` — every other tool-owned dir (`.pql/`, `.clide/`) is added to `.gitignore` at install time; exclusion flows through the normal `ignore_files:` chain.
|
||||
- **Context:** Every file-enumerating surface in clide (pql query panels, canvas drivers, graph view, file watchers, pane lists, file tree) needs to skip the obvious junk — `vendor/`, `node_modules/`, `dist/`, build artifacts — or results drown in noise. Clide's working assumption is that the git repo *is* the workspace — no separate "vault" concept.
|
||||
- **Rationale:** Users get one config knob, in a file they might already know (pql users) or never need to touch (clide-only users). `.clideignore` is short by design — it's deltas, not a full list. Sidecar consumers read the same key and apply identical precedence, so Claude and the user always see the same filtered surface.
|
||||
- **Cost:** Removing clide from a repo leaves pql working with vanilla defaults (clide's last-written `ignore_files:` stays until pql or the user rewrites it; worth reconsidering during uninstall design).
|
||||
|
||||
@@ -13,7 +13,7 @@ Extension contract, Lua runtime, grain, contribution points.
|
||||
|
||||
### D-16: Built-ins in Dart, third-party in sandboxed Lua
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Bundled extensions (every `app/lib/builtin/<name>`) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the `ptyc`-peer Lua runtime (see [D-19](#d-19-lua-runtime-as-ptyc-peer-supporter-tool)). The contribution contract is language-agnostic — same contribution shapes, same manifest schema.
|
||||
- **Decision:** Bundled extensions (every `lib/builtin/<name>`) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the `ptyc`-peer Lua runtime (see [D-19](#d-19-lua-runtime-as-ptyc-peer-supporter-tool)). The contribution contract is language-agnostic — same contribution shapes, same manifest schema.
|
||||
- **Rationale:** Dart built-ins get full SDK power (custom painters, isolates, FFI); third-party Lua gets a narrow capability API, no arbitrary syscalls, no deps on pub.dev. VS Code's Node-runs-with-full-power model is a supply-chain nightmare we're explicitly rejecting.
|
||||
- **Cost:** Two implementation paths for the same contract; we pay in API design to keep them equivalent at the seams.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
@@ -41,7 +41,7 @@ Extension contract, Lua runtime, grain, contribution points.
|
||||
|
||||
### D-46: Core frame builtins vs shipped extensions boundary
|
||||
- **Date:** 2026-04-22
|
||||
- **Decision:** The `app/lib/builtin/` directory is reserved for core frame infrastructure — components the shell cannot function without. Everything that renders *content* (editor surfaces, tool panels, integrations) is a shipped extension: still Dart, still bundled in the binary, but architecturally an extension that registers through the contribution contract and could in principle be disabled by the user.
|
||||
- **Decision:** The `lib/builtin/` directory is reserved for core frame infrastructure — components the shell cannot function without. Everything that renders *content* (editor surfaces, tool panels, integrations) is a shipped extension: still Dart, still bundled in the binary, but architecturally an extension that registers through the contribution contract and could in principle be disabled by the user.
|
||||
|
||||
**Core frame builtins** (cannot be disabled; the frame breaks without them):
|
||||
`default-layout`, `welcome`, `ipc-status`, `theme-picker`, `terminal`, `files`, `grammars-core`, `settings-ui`, `extensions-ui`, `keybindings-ui`.
|
||||
@@ -53,7 +53,7 @@ Extension contract, Lua runtime, grain, contribution points.
|
||||
`editor`, `claude`, `claude-control`, `markdown`, `diff`, `git-ui`, `pql`, `canvas`, `graph`, `decisions`, `tickets`, `todos`, `problems`.
|
||||
|
||||
- **Rationale:** The previous session bled several content extensions (jira, todos, decisions, tickets, canvas, graph) into `builtin/` as stubs, treating "shipped with the app" as "part of the frame." This conflates two concerns: the frame's structural integrity and the bundled feature set. A user who disables the canvas extension should get a working IDE with no canvas panel; a user who disables the layout extension gets a broken window. The boundary is: can the frame render and function without it? If yes, it's a shipped extension, not a frame builtin.
|
||||
- **Cost:** Shipped extensions need a separate registration path (e.g. `app/lib/extensions/` or equivalent) distinct from `app/lib/builtin/`. The extension contract must support "bundled Dart extension" as a first-class category alongside "builtin" and "third-party Lua." Migration is incremental — move one at a time, each behind a working build.
|
||||
- **Cost:** Shipped extensions need a separate registration path (e.g. `lib/extensions/` or equivalent) distinct from `lib/builtin/`. The extension contract must support "bundled Dart extension" as a first-class category alongside "builtin" and "third-party Lua." Migration is incremental — move one at a time, each behind a working build.
|
||||
- **Supersedes:** Removes `builtin.jira` (already deleted; should never have been a builtin — Jira integration is a third-party extension, not a shipped one).
|
||||
- **Raised by:** 2026-04-22 session review.
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Q&D record system itself, kanban, commit conventions, changelog.
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Planning subcommands (`decisions`, `ticket`, `plan`) land in pql's repo long-term. Clide consumes them via shell-out, matching [D-3](architecture.md)'s wrap-don't-duplicate rule for pql. Clide does not grow Dart subcommands for planning.
|
||||
- **Rationale:** A terminal user or a user in VS Code / JetBrains still needs Q&D access. Binding planning tooling to clide-the-Flutter-app would cut them off from their own work — see [R-9](rejected.md#r-9-port-planning-tooling-into-clide). pql is already the CLI, already universal, already wrapped by clide.
|
||||
- **Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-planning-vs-keeps-separate).
|
||||
- **Cost:** Planning features don't ship until pql catches up. Mitigated by [D-40](#d-40-superseded-python-stopgap-under-toolsscriptsplan). Gated by [Q-21](questions-process.md#q-21-pql-absorbs-planning-vs-keeps-separate).
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
### D-40: [SUPERSEDED] Python stopgap under `tools/scripts/plan`
|
||||
|
||||
@@ -16,7 +16,7 @@ Tooling-domain questions currently live here too. Split into
|
||||
### Q-16: `tree-sitter-dart` grammar maintenance
|
||||
- **Status:** Open
|
||||
- **Question:** `UserNobody14/tree-sitter-dart` is archived. `nielsenko/tree-sitter-dart` is the maintained fork. Do we pin `nielsenko/`, mirror it in-repo, or lean on the Dart analyzer's own semantic output and skip tree-sitter for Dart?
|
||||
- **Context:** If tree-sitter is the Tier-2 answer ([Q-15](#q-15-editor-tab-full-lsp-vs-tree-sitter-only)), grammar sourcing matters.
|
||||
- **Context:** If tree-sitter is the Tier-2 answer ([Q-15](#q-15-editor-tab-full-lsp-vs-tree-sitter-only-highlight)), grammar sourcing matters.
|
||||
- **Source:** 2026-04-21 planning.
|
||||
|
||||
### Q-17: Icon set growth
|
||||
|
||||
@@ -41,7 +41,7 @@ Test pyramid, drivers, client-side constraint.
|
||||
|
||||
### D-28: Test organisation — mirror `lib/` in `test/`
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Every test file lives at the same relative path as its subject. `app/lib/kernel/src/i18n/catalog_loader.dart` pairs with `app/test/kernel/i18n/catalog_loader_test.dart`. No separate `unit/` vs `widget/` directories; test type is detected by what the test imports.
|
||||
- **Decision:** Every test file lives at the same relative path as its subject. `lib/kernel/src/i18n/catalog_loader.dart` pairs with `test/kernel/i18n/catalog_loader_test.dart`. No separate `unit/` vs `widget/` directories; test type is detected by what the test imports.
|
||||
- **Rationale:** Matching paths makes "jump to test" predictable in any editor. Type-by-imports matches how `flutter test` already works.
|
||||
- **Cost:** Large feature folders mirror into large test folders. Acceptable.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
@@ -20,7 +20,7 @@ Toolchain, supply chain, CI, ignore strategy.
|
||||
|
||||
### D-42: Dependencies documented in `licenses.yaml`
|
||||
- **Date:** 2026-04-22
|
||||
- **Decision:** `app/assets/licenses.yaml` has three sections: `self:` (clide's MIT license, rendered first in the About screen so the user knows what they're running), `dependencies:` (third-party artefacts that **ship in the binary** — fonts, runtime Dart packages, native supporter tools, bundled data), and `dev_dependencies:` (build-time-only tooling — test runners, mocks, lints, golden harness — tracked for audit but **not rendered** in the About screen because they don't reach the user). Each entry has name, kind, version, homepage, license identifier, and a one-line purpose; runtime entries also carry a `license_file:` pointer to the bundled license text so the About screen can display it verbatim. Adding any dependency is a two-step commit: add the artefact **and** the corresponding `licenses.yaml` entry in the same changeset, under the correct section.
|
||||
- **Decision:** `assets/licenses.yaml` has three sections: `self:` (clide's MIT license, rendered first in the About screen so the user knows what they're running), `dependencies:` (third-party artefacts that **ship in the binary** — fonts, runtime Dart packages, native supporter tools, bundled data), and `dev_dependencies:` (build-time-only tooling — test runners, mocks, lints, golden harness — tracked for audit but **not rendered** in the About screen because they don't reach the user). Each entry has name, kind, version, homepage, license identifier, and a one-line purpose; runtime entries also carry a `license_file:` pointer to the bundled license text so the About screen can display it verbatim. Adding any dependency is a two-step commit: add the artefact **and** the corresponding `licenses.yaml` entry in the same changeset, under the correct section.
|
||||
- **Rationale:** Complements [D-31](#d-31-prefer-zero-deps-exact-pin). Prefer-zero-deps is a *budget*; `licenses.yaml` is the *visible consequence*. An extra row in the About screen is a review-time signal that the shipped-binary surface grew. Splitting dev deps out keeps the user-facing list small and honest — a test framework is not something the user needs to see in About — while still documenting every supply-chain input for audit completeness. The runtime entries discharge the redistribution obligations bundled licenses impose (OFL, MIT, BSD all require preserving the license text alongside the binary) without ad-hoc NOTICE files.
|
||||
- **Cost:** One extra edit per dep. Zero tolerance for drift — an un-listed dep is a contributor-visible bug. Until the About screen lands at Tier 6, `licenses.yaml` is accurate but not rendered; the discipline applies from now regardless so Tier 6 inherits a clean list.
|
||||
- **Raised by:** 2026-04-22 planning (user-directed best practice).
|
||||
@@ -47,7 +47,7 @@ Toolchain, supply chain, CI, ignore strategy.
|
||||
- **Decision:** Ship a self-contained Git binary from [dugite-native](https://github.com/desktop/dugite-native) (the same distribution GitHub Desktop bundles). Downloaded at build time via `make dugite-fetch`, stored under `native/dugite/`, gitignored. The `Toolchain` class resolves to the bundled binary first, falling back to system git on PATH.
|
||||
- **Rationale:** The macOS app sandbox blocks execution of Homebrew-installed git (symlinks resolve to Cellar paths that SBPL cannot match without freezing rendering). `/usr/bin/git` is an xcrun shim that refuses to run inside a sandbox. Bundling dugite-native makes clide self-contained — no dependency on Homebrew, Xcode CLT, or system git. The approach is proven: GitHub Desktop, Tower, and other git GUI apps all bundle their own git for the same reason.
|
||||
- **Alternatives rejected:** (R) libgit2 via FFI — missing porcelain commands (pull/push/rebase), no hooks, would require rewriting GitClient. (R) Build git from source — dugite-native already does this with better infra. (R) SBPL exceptions for Homebrew — `(subpath "/opt/homebrew")` for process-exec freezes Flutter rendering on macOS 26.
|
||||
- **Cost:** ~57 MB download (~199 MB unpacked, stripped at build time). Must track dugite-native releases for security updates. GPL-2.0 (git binary) applies to the bundled artefact, not to clide's MIT code.
|
||||
- **Cost:** ~57 MB download (~199 MB unpacked, stripped at build time). Must track dugite-native releases for security updates (tracked in T-88). GPL-2.0 (git binary) applies to the bundled artefact, not to clide's MIT code.
|
||||
- **Cross-reference:** [D-31](#d-31-prefer-zero-deps-exact-pin), [D-42](#d-42-dependencies-documented-in-licensesyaml).
|
||||
- **Raised by:** 2026-04-25 macOS sandbox investigation.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user