universal-dev-standards 6.11.0 → 6.13.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/ai/standards/developer-memory.ai.yaml +24 -2
- package/bundled/ai/standards/open-work-tracking.ai.yaml +216 -0
- package/bundled/ai/standards/turn-completion-integrity.ai.yaml +34 -2
- package/bundled/core/developer-memory.md +58 -2
- package/bundled/core/open-work-tracking.md +333 -0
- package/bundled/core/turn-completion-integrity.md +36 -2
- package/bundled/hooks/check-turn-completion-codex.mjs +116 -0
- package/bundled/hooks/check-turn-completion-gemini.mjs +81 -0
- package/bundled/hooks/check-turn-completion.mjs +24 -149
- package/bundled/hooks/turn-completion/engine.mjs +206 -0
- package/bundled/hooks/turn-completion/locales/en.mjs +29 -1
- package/bundled/hooks/turn-completion/locales/zh-TW.mjs +29 -1
- package/bundled/locales/zh-CN/CHANGELOG.md +23 -3
- package/bundled/locales/zh-CN/CLAUDE.md +1 -1
- package/bundled/locales/zh-CN/README.md +2 -2
- package/bundled/locales/zh-CN/SECURITY.md +2 -1
- package/bundled/locales/zh-CN/core/turn-completion-integrity.md +36 -6
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +2 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +24 -5
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +4 -3
- package/bundled/locales/zh-TW/CHANGELOG.md +23 -3
- package/bundled/locales/zh-TW/CLAUDE.md +1 -1
- package/bundled/locales/zh-TW/README.md +2 -2
- package/bundled/locales/zh-TW/SECURITY.md +2 -1
- package/bundled/locales/zh-TW/core/open-work-tracking.md +255 -0
- package/bundled/locales/zh-TW/core/turn-completion-integrity.md +36 -6
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +2 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +24 -5
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +4 -3
- package/package.json +1 -1
- package/src/commands/init.js +26 -0
- package/src/installers/hooks-installer.js +104 -0
- package/standards-registry.json +19 -7
|
@@ -13,8 +13,8 @@ standard:
|
|
|
13
13
|
- "Respect noise control levels and cooldown periods"
|
|
14
14
|
|
|
15
15
|
meta:
|
|
16
|
-
version: "1.
|
|
17
|
-
updated: "2026-
|
|
16
|
+
version: "1.2.0"
|
|
17
|
+
updated: "2026-09-25"
|
|
18
18
|
source: core/developer-memory.md
|
|
19
19
|
description: Structured system for capturing, retrieving, and surfacing developer experience insights across conversations and projects
|
|
20
20
|
|
|
@@ -128,6 +128,20 @@ standard:
|
|
|
128
128
|
trigger: "confidence < 0.2 OR 180+ days unsurfaced with confidence < 0.5"
|
|
129
129
|
- type: staleness
|
|
130
130
|
trigger: "versioned type with outdated version_bound"
|
|
131
|
+
- type: code-reference
|
|
132
|
+
trigger: "recalled memory cites a file path or symbol (function/class) that no longer exists at that location, or has moved"
|
|
133
|
+
timing: "runs before proactive-surfacing (check before a memory is shown, not after)"
|
|
134
|
+
scope: "file paths and symbol names (functions/classes) only; file:line is out of scope (line numbers drift on unrelated edits — different staleness semantics; see DEC-115 OQ-1)"
|
|
135
|
+
modes:
|
|
136
|
+
degraded:
|
|
137
|
+
when: "no graph engine configured (any tool, no setup — the default)"
|
|
138
|
+
how: "the assistant verifies the referenced path/symbol itself (Glob/Grep/Read) before using the memory — same mechanism as the memory-as-hint-not-conclusion rule"
|
|
139
|
+
source: "knowledge-graph-memory 1.0.0 §2.1 Degraded Mode"
|
|
140
|
+
engine:
|
|
141
|
+
when: "a graph engine is indexed (e.g. EngramGraph)"
|
|
142
|
+
how: "engine query (e.g. `egr refs check`) reports each citation's state: present / moved (with new location) / missing / unresolvable"
|
|
143
|
+
source: "knowledge-graph-memory 1.0.0 §2.2 Service Mode"
|
|
144
|
+
unresolvable_rule: "unresolvable (e.g. a cross-repo reference outside the indexed scope) MUST NOT be treated as present or missing — surface it as its own state"
|
|
131
145
|
- type: revision
|
|
132
146
|
trigger: "2+ needs-revision feedback"
|
|
133
147
|
|
|
@@ -135,6 +149,11 @@ standard:
|
|
|
135
149
|
- id: proactive-surfacing
|
|
136
150
|
trigger: conversation start or matching code pattern/error/decision detected
|
|
137
151
|
instruction: >
|
|
152
|
+
Before surfacing, run the code-reference staleness check
|
|
153
|
+
(review.checks type: code-reference) on each candidate memory's
|
|
154
|
+
cited file path / symbol. Do not surface a memory whose citation
|
|
155
|
+
resolves to missing without flagging it as stale; unresolvable is
|
|
156
|
+
not the same as present or missing.
|
|
138
157
|
Surface top 3 relevant memories when relevance > 0.7.
|
|
139
158
|
Max 5 per trigger. Cooldown 7 days per entry.
|
|
140
159
|
If > 5 matches, summarize into grouped insight.
|
|
@@ -225,3 +244,6 @@ standard:
|
|
|
225
244
|
Category: {category} | Tags: {tags}
|
|
226
245
|
Insight: {insight}
|
|
227
246
|
Context: {context}
|
|
247
|
+
|
|
248
|
+
related_standards:
|
|
249
|
+
- knowledge-graph-memory
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Open Work Tracking Standard - AI Optimized
|
|
2
|
+
# Source: core/open-work-tracking.md
|
|
3
|
+
|
|
4
|
+
standard:
|
|
5
|
+
id: open-work-tracking
|
|
6
|
+
name: Open Work Tracking Standard
|
|
7
|
+
description: 開放工作追蹤標準——承載開放工作的地方必須低摩擦收件、記錄解除條件、生成可推導欄位、印出分母、且在回合結束時被檢視而不阻斷
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
version: "1.0.0"
|
|
11
|
+
updated: "2026-09-23"
|
|
12
|
+
source: core/open-work-tracking.md
|
|
13
|
+
description: >
|
|
14
|
+
三種不同的「工作不見了」的方式(沒地方記新想法、等待中沒有解除條件、
|
|
15
|
+
沒有時鐘的計畫無聲腐爛)常被塞進同一份清單,而合併本身就是失敗的一部分。
|
|
16
|
+
本標準是 deferred-item-exit 的下游一半:DEX 管「延後項目有沒有離開文件」,
|
|
17
|
+
本標準管「離開之後抵達的那個承載庫,自己會不會腐壞」。
|
|
18
|
+
|
|
19
|
+
iron_law: >
|
|
20
|
+
一個承載開放工作的地方,必須:不要求分類就能收下新項目、為每一個等待中項目記下解除條件、
|
|
21
|
+
對可推導的欄位改用生成、回報還剩什麼時同時揭露看不到什麼、
|
|
22
|
+
在控制權從 agent 交回人的那一刻被檢視——而且那個檢視不能讓回合失敗。
|
|
23
|
+
|
|
24
|
+
# ── 寫法約束:先讀這一段,它拘束下面每一條 ────────────────────────────────
|
|
25
|
+
# 與 deferred-item-exit 受的是同一條約束(DEC-049),套用在下游一層:
|
|
26
|
+
# 本標準只陳述關係,不規定承載庫用什麼工具/格式/系統實作。
|
|
27
|
+
writing_constraint:
|
|
28
|
+
basis: DEC-049
|
|
29
|
+
upstream: deferred-item-exit
|
|
30
|
+
admissible_what:
|
|
31
|
+
- "收件點欄位數必須具備的性質"
|
|
32
|
+
- "等待項目與解除條件之間必須存在的關係"
|
|
33
|
+
- "「這是最新的」這句宣稱必須從什麼可被證明"
|
|
34
|
+
- "一個回報數字與它看不到的部分之間的關係"
|
|
35
|
+
- "控制權交回人的那一點存在一個確認點,且它永不阻斷"
|
|
36
|
+
inadmissible_how:
|
|
37
|
+
- "收件點是哪個 app、檔案或工單系統"
|
|
38
|
+
- "輪詢解除條件的排程器或機器人"
|
|
39
|
+
- "具體用哪個雜湊函式、diff 工具或 CI 供應商"
|
|
40
|
+
- "儀表板版面或報告範本"
|
|
41
|
+
- "用什麼 hook 系統、shell 或 cron 實作確認點"
|
|
42
|
+
consequence: >
|
|
43
|
+
本標準不附帶任何閘門。它只說一個承載開放工作的地方必須具備什麼性質;
|
|
44
|
+
有沒有東西在檢查是採用專案的決定,而 OWT-014/OWT-015 是用來讓那個決定
|
|
45
|
+
沒辦法被默默做掉的。
|
|
46
|
+
|
|
47
|
+
guidelines:
|
|
48
|
+
- "收件點必填欄位不得超過兩個——分類/優先級/負責人一律是 triage 時的動作,不得成為輸入門檻"
|
|
49
|
+
- "每個等待中項目都要記下**在等什麼**與**什麼事件視為解除**,解除條件應盡量機器看得到"
|
|
50
|
+
- "凡能從版控/規格標記/CI 結果推導出來的欄位,一律生成,不得手寫"
|
|
51
|
+
- "**生成區段的「最新」宣稱要能從內容本身證明**(例如來源雜湊),不能只靠一個人可以敷衍的日期"
|
|
52
|
+
- "**「內容可證明最新」與「日期宣稱最新、內容未驗證」是兩個不同狀態,不得合併成同一個通過**"
|
|
53
|
+
- "任何「還有 N 項」的數字,必須同時印出看得見多少、看不見多少——看不見的部分不得被讀成零"
|
|
54
|
+
- "確認點要出現在**控制權從 agent 交回人的那一刻**,不能只掛在 shell 啟動、CI 或文件被編輯時"
|
|
55
|
+
- "🔴 確認點**永遠不阻斷**——「還有工作沒做完」幾乎永遠為真,永遠為真的閘門會被關掉"
|
|
56
|
+
- "確認點與阻斷式檢查掛同一事件時,確認點的輸出要排在阻斷判決之前"
|
|
57
|
+
- "判定項目是等待中/未分類/已丟棄,走訪承載庫自己的結構欄位,不要只靠掃描散文措辭"
|
|
58
|
+
- "措辭清單可以補充結構欄位,但涵蓋率必須明示未知,乾淨結果不得回報成「沒有漏掉」"
|
|
59
|
+
- "超過門檻仍未分類的項目要在摘要裡被點名,不得被合併進一個總數"
|
|
60
|
+
- "項目從承載庫消失(drop)必須帶一句理由,不得只是消失"
|
|
61
|
+
|
|
62
|
+
# ── R5 vs turn-completion-integrity:掛同一事件,行為刻意相反 ──────────────
|
|
63
|
+
vs_turn_completion_integrity:
|
|
64
|
+
shared_event: "回合結束、控制權交回人類"
|
|
65
|
+
turn_completion_integrity:
|
|
66
|
+
watches: "agent 自己最後一則訊息裡,被說出口又被放棄的第一人稱承諾"
|
|
67
|
+
default_state: "罕見——只在明確做出承諾又被丟下時觸發"
|
|
68
|
+
on_violation: "擋住回合結束,直到承諾被解決或說明卡在誰身上"
|
|
69
|
+
this_standard:
|
|
70
|
+
watches: "承載庫裡的項目,看有沒有沒解除條件的、沒出口的、或過門檻還沒分類的"
|
|
71
|
+
default_state: "常見——「還有工作沒做完」幾乎永遠為真"
|
|
72
|
+
on_violation: "永不阻斷,只能回報(OWT-008)"
|
|
73
|
+
why_opposite: >
|
|
74
|
+
TCI 自己的規則(TCI R4)已經寫出這裡不能做成閘門的理由:
|
|
75
|
+
一個在每個回合都為真的閘門會被關掉,關掉之後它什麼都不保護。
|
|
76
|
+
開放工作非空幾乎永遠為真,所以本標準的確認點被設計成永不保留控制權。
|
|
77
|
+
ordering_when_co_located: "本標準先回報(OWT-009),即使該回合隨後被 TCI 擋下,回報仍然可見"
|
|
78
|
+
|
|
79
|
+
# ── 錨點:走訪結構,不走訪措辭(與 DEX-007/DEX-008 同形狀)───────────────
|
|
80
|
+
anchors:
|
|
81
|
+
principle: "判定等待中/未分類/已丟棄,讀承載庫自己描述該狀態的結構欄位——狀態欄、型別化標記、小節標題——而非散文措辭"
|
|
82
|
+
wording_heuristic:
|
|
83
|
+
allowed: true
|
|
84
|
+
but: "涵蓋率必須明示未知;一份含「等待」「未分類」的措辭清單,對用別的寫法表達的項目什麼也不保證"
|
|
85
|
+
general_form: class-level-fix
|
|
86
|
+
|
|
87
|
+
# ── 戳 vs 內容:與 DEX-005/DEX-006 同形狀,換了一個 artefact ──────────────
|
|
88
|
+
stamp_vs_content:
|
|
89
|
+
failure: >
|
|
90
|
+
生成區段的時間戳很新,被誤讀成內容是新的。戳比內容舊的情況容易抓(比對修改紀錄);
|
|
91
|
+
戳比內容新而內容本身已過期——隱形,因為「戳是新的」正是一次正確對帳看起來的樣子。
|
|
92
|
+
fix: "「最新」的宣稱要能從內容本身被證明(例如來源雜湊),不能只靠一個人可編輯的日期"
|
|
93
|
+
two_states_required:
|
|
94
|
+
- state: content_proven_current
|
|
95
|
+
meaning: "從內容本身可證明是最新的(例如雜湊比對一致)"
|
|
96
|
+
- state: date_claims_current_unverified
|
|
97
|
+
meaning: "日期看起來新,內容有沒有真的對過帳未知"
|
|
98
|
+
why_not_one_state: "把兩態合併成單一通過,正是這條規則要防的缺陷;一個被回報成通過的未知,比一個被回報成未知的未知更糟"
|
|
99
|
+
|
|
100
|
+
evidence_admissibility:
|
|
101
|
+
rule: "被提出作為本標準證據的檢查,必須已經被觀察到對一個刻意違反該要求的樣本回報失敗"
|
|
102
|
+
why: "一支從未失敗過的檢查,與一支不可能失敗的檢查,輸出一模一樣"
|
|
103
|
+
procedure_lives_in: class-level-fix
|
|
104
|
+
exit_code_caveat_lives_in: verification-evidence
|
|
105
|
+
|
|
106
|
+
anti_patterns:
|
|
107
|
+
- pattern: "收件表單有三個以上必填欄位"
|
|
108
|
+
why: "可量測地不再被使用;摩擦由正在打斷自己工作的人承擔"
|
|
109
|
+
- pattern: "「之後再看」而沒有解除條件"
|
|
110
|
+
why: "與被忘記無法分辨;沒有東西會讓它回來"
|
|
111
|
+
- pattern: "手動輸入、重複 git 或 CI 已知資訊的狀態"
|
|
112
|
+
why: "兩個擁有者,其中一個永遠不會被更新"
|
|
113
|
+
- pattern: "沒有內容證明的「最後對過帳」日期"
|
|
114
|
+
why: "內容真的被核對過,跟日期只是被打上去,看起來一模一樣"
|
|
115
|
+
- pattern: "「還有 47 項」而不寫分母"
|
|
116
|
+
why: "預設被讀成完整;看不見的大多數被誤讀成「都做完了」"
|
|
117
|
+
- pattern: "確認點掛在 shell 啟動而不是回合結束"
|
|
118
|
+
why: "只要沒人剛好開新 shell,它就持續漂移"
|
|
119
|
+
- pattern: "確認點擋住回合結束、理由是「還有工作沒做完」"
|
|
120
|
+
why: "每個回合都會觸發;永遠為真的閘門會被關掉,關掉之後什麼都不保護"
|
|
121
|
+
- pattern: "分類狀態只靠散文措辭判讀"
|
|
122
|
+
why: "正確到某個項目用清單沒預料到的方式寫出來為止"
|
|
123
|
+
- pattern: "項目從承載庫無聲消失"
|
|
124
|
+
why: "與一個弄丟它的 bug 無從分辨"
|
|
125
|
+
|
|
126
|
+
rules:
|
|
127
|
+
- id: OWT-001
|
|
128
|
+
rule: "新項目的收件點必填欄位不得超過兩個;分類/優先級/負責人一律是 triage 時的動作,不得成為輸入門檻"
|
|
129
|
+
severity: error
|
|
130
|
+
- id: OWT-002
|
|
131
|
+
rule: "標為等待中的項目,必須同時記下在等什麼與什麼事件視為解除"
|
|
132
|
+
severity: error
|
|
133
|
+
- id: OWT-003
|
|
134
|
+
rule: "能從版控/規格標記/CI 結果完整推導的欄位,一律生成,不得手寫"
|
|
135
|
+
severity: error
|
|
136
|
+
- id: OWT-004
|
|
137
|
+
rule: "生成區段的「最新」宣稱必須能從它所本的內容證明(例如來源雜湊),不能只靠一個人可編輯的日期"
|
|
138
|
+
severity: error
|
|
139
|
+
- id: OWT-005
|
|
140
|
+
rule: "「內容可證明最新」與「日期宣稱最新、內容未驗證」須回報為兩個相異狀態;合併為單一通過即不滿足 OWT-004"
|
|
141
|
+
severity: error
|
|
142
|
+
- id: OWT-006
|
|
143
|
+
rule: "任何「還有 N 項」的數字,須同時印出看得見多少來源、看不見多少來源;看不見的部分不得被讀成零"
|
|
144
|
+
severity: error
|
|
145
|
+
- id: OWT-007
|
|
146
|
+
rule: "開放工作摘要出現在控制權從 agent 交回人的那一刻,不能只掛在 session 開始、CI、或追蹤文件被編輯時"
|
|
147
|
+
severity: error
|
|
148
|
+
- id: OWT-008
|
|
149
|
+
rule: "開放工作摘要自己的結束路徑,不論輸入為何(含「還有很多項」)都不得改變回合的結果"
|
|
150
|
+
severity: error
|
|
151
|
+
- id: OWT-009
|
|
152
|
+
rule: "摘要與一道阻斷式檢查掛同一個回合結束事件時,摘要的輸出須排在阻斷判決之前"
|
|
153
|
+
severity: warning
|
|
154
|
+
- id: OWT-010
|
|
155
|
+
rule: "判定項目是等待中/未分類/已丟棄,須來自承載庫自定義的結構欄位,不得只靠掃描散文措辭"
|
|
156
|
+
severity: error
|
|
157
|
+
- id: OWT-011
|
|
158
|
+
rule: "以措辭啟發式補充結構欄位時,須明示其涵蓋率未知,且其乾淨結果不得回報為「沒有漏掉」"
|
|
159
|
+
severity: warning
|
|
160
|
+
- id: OWT-012
|
|
161
|
+
rule: "超過宣告門檻仍未分類的項目,須在開放工作摘要裡被個別點名,不得被合併進總數"
|
|
162
|
+
severity: error
|
|
163
|
+
- id: OWT-013
|
|
164
|
+
rule: "項目從承載庫移除而未變成規格、追蹤項目、或任何其他具名去向時,須帶一句理由;沒有理由的移除與靜默刪除無法分辨"
|
|
165
|
+
severity: error
|
|
166
|
+
- id: OWT-014
|
|
167
|
+
rule: "本標準的每一條要求都必須可表述為 artefact 之間可判定的關係;不能如此表述的要求不得進入本標準"
|
|
168
|
+
severity: error
|
|
169
|
+
- id: OWT-015
|
|
170
|
+
rule: "被提出作為本標準任一要求之證據的檢查,須已被觀察到對一個刻意違反該要求的樣本回報失敗;從未紅過的檢查不是可採信的證據"
|
|
171
|
+
severity: error
|
|
172
|
+
- id: OWT-016
|
|
173
|
+
rule: "本標準各要求所引用的任何窗口或閾值,須載明來歷,或標為未校準"
|
|
174
|
+
severity: warning
|
|
175
|
+
|
|
176
|
+
# ── 本標準在 UDS 側沒有閘門,這件事被記錄而非被暗示 ──────────────────────
|
|
177
|
+
enforcement:
|
|
178
|
+
automated_gate: false
|
|
179
|
+
why_not: >
|
|
180
|
+
依上面的寫法約束,UDS 陳述關係,有沒有東西判定它是採用專案的決定。
|
|
181
|
+
UDS 不出貨承載開放工作的地方本身,只出貨要求它具備什麼性質的標準。
|
|
182
|
+
what_it_does_instead: >
|
|
183
|
+
OWT-014 保證這裡每一條「能」被判定;OWT-015 固定「一次判定要算數需要什麼」;
|
|
184
|
+
OWT-005/OWT-011 固定「一次不完整的判定容許印出什麼」。
|
|
185
|
+
honest_boundary: >
|
|
186
|
+
一個採用本標準而什麼都沒建的專案並未違反它——但它同樣不能宣稱自己的開放工作
|
|
187
|
+
承載庫具備這些性質,因為它沒有任何可採信的證據說明有。
|
|
188
|
+
|
|
189
|
+
# ── 證據強度與校準:誠實標注,不誇大 ─────────────────────────────────────
|
|
190
|
+
evidence_and_calibration:
|
|
191
|
+
origin: "XSPEC-427(2026-09-23),一個採用專案同一天做出並實跑的參考實作"
|
|
192
|
+
age_at_writing: "以小時計,單一使用者,單一 repo"
|
|
193
|
+
what_this_supports: "R1–R6 的形狀——每一條都對應一個當天觀察到的失效或使用者原話描述的模式"
|
|
194
|
+
what_this_does_not_support: "OWT-001 的「兩個欄位」與 OWT-012 的「兩週」這類具體閾值——這些是初始判斷,不是量測"
|
|
195
|
+
recalibration: "由採用專案自行決定與自行訂定時程;本標準不承諾覆核日期,如同它不承諾閘門"
|
|
196
|
+
|
|
197
|
+
related:
|
|
198
|
+
- id: deferred-item-exit
|
|
199
|
+
relation: "上游的同一個形狀:DEX 要求延後項目離開文件、抵達可追蹤出口,刻意不規定出口的載體。本標準接手出口存在之後的事,要求載體自己不要變成下一份東西會不見的文件"
|
|
200
|
+
- id: turn-completion-integrity
|
|
201
|
+
relation: "掛在同一個事件(回合結束)上,且被設計成行為相反——TCI 阻斷、本標準永不阻斷。見 vs_turn_completion_integrity"
|
|
202
|
+
- id: class-level-fix
|
|
203
|
+
relation: "OWT-011 揭露之措辭清單限制的通則形式,也是 OWT-015 所要求非空跑證據程序的來源"
|
|
204
|
+
- id: verification-evidence
|
|
205
|
+
relation: "OWT-015 所依賴的 exit code 與證據有效性推理的來源;也是 OWT-006/OWT-011 部分涵蓋例外該被登記的地方"
|
|
206
|
+
|
|
207
|
+
physical_spec:
|
|
208
|
+
applies_to:
|
|
209
|
+
- "任何承載跨回合/跨 session 開放工作的地方(收件匣、待辦清單、backlog、worklog 等,載體不限)"
|
|
210
|
+
deliverables:
|
|
211
|
+
- "收件點的欄位數(須 ≤ 2)"
|
|
212
|
+
- "每個等待中項目旁的解除條件"
|
|
213
|
+
- "生成區段旁的內容可證明性(而非僅時間戳)"
|
|
214
|
+
- "任何「還有 N 項」數字旁的看見/看不見分母"
|
|
215
|
+
- "掛在回合結束、永不阻斷的開放工作摘要"
|
|
216
|
+
- "超過門檻仍未分類項目的個別點名,與已丟棄項目的一句理由"
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
id: turn-completion-integrity
|
|
5
5
|
meta:
|
|
6
|
-
version: "1.
|
|
7
|
-
updated: "2026-09-
|
|
6
|
+
version: "1.4.0"
|
|
7
|
+
updated: "2026-09-25"
|
|
8
8
|
source: core/turn-completion-integrity.md
|
|
9
9
|
description: An agent must not end a turn having stated a next action it did not take; enforced at turn end, not by instruction
|
|
10
10
|
related:
|
|
@@ -117,6 +117,36 @@ enforcement:
|
|
|
117
117
|
severity: warning
|
|
118
118
|
timeout_ms: 2000
|
|
119
119
|
|
|
120
|
+
# The check is enforced only where an adapter exists AND a hook is wired into
|
|
121
|
+
# that harness's own config. This is separate from `enforcement:` above, which
|
|
122
|
+
# only describes the Claude Code entry the generic installer walks — Codex and
|
|
123
|
+
# Gemini CLI are installed by their own installCodexHooks/installGeminiHooks
|
|
124
|
+
# functions (cli/src/installers/hooks-installer.js), each writing that
|
|
125
|
+
# harness's own config file and output contract.
|
|
126
|
+
supported_harnesses:
|
|
127
|
+
- harness: claude-code
|
|
128
|
+
event: Stop
|
|
129
|
+
config_file: ".claude/settings.json"
|
|
130
|
+
block_shape: '{"decision":"block","reason":...}, exit 0; silence allows'
|
|
131
|
+
script: scripts/hooks/check-turn-completion.mjs
|
|
132
|
+
- harness: codex
|
|
133
|
+
event: Stop
|
|
134
|
+
config_file: ".codex/hooks.json"
|
|
135
|
+
block_shape: '{"decision":"block","reason":...}, exit 0 — plain text or empty stdout documented as invalid for this event'
|
|
136
|
+
script: scripts/hooks/check-turn-completion-codex.mjs
|
|
137
|
+
known_limit: "R9 (human-directed stop exemption) is best-effort — Codex gives the assistant's last message directly but not the human's; a failed transcript read leaves the human side empty rather than skipping detection"
|
|
138
|
+
- harness: gemini-cli
|
|
139
|
+
event: AfterAgent
|
|
140
|
+
config_file: ".gemini/settings.json"
|
|
141
|
+
block_shape: '{"decision":"deny","reason":...}, exit 0 — the documented preferred path over exit code 2'
|
|
142
|
+
script: scripts/hooks/check-turn-completion-gemini.mjs
|
|
143
|
+
- harness: cursor
|
|
144
|
+
status: evaluated-not-supported
|
|
145
|
+
reason: "Whether Cursor's stop hook can actually block a turn was unresolved as of writing; shipping an adapter against an unverified contract repeats the exact failure R3 exists to prevent"
|
|
146
|
+
- harness: any-other
|
|
147
|
+
status: inactive
|
|
148
|
+
reason: "Same silent-by-default failure as an unsupported language (R8). uds init --with-hooks reports which harnesses it wired a hook into."
|
|
149
|
+
|
|
120
150
|
checklist:
|
|
121
151
|
- The check runs at turn end, not as an instruction to the agent
|
|
122
152
|
- Every failure path exits without blocking
|
|
@@ -129,3 +159,5 @@ checklist:
|
|
|
129
159
|
- The check recognises its own block message and does not read it as the human's
|
|
130
160
|
- The check recognises the itemized blocker ending R2 defines, and does not block it
|
|
131
161
|
- The attribution search excludes the check's own headings and scaffolding
|
|
162
|
+
- Each supported harness's block contract is verified against that harness's own docs, not assumed from another harness
|
|
163
|
+
- The installer only writes a harness's hook config for a harness the adopter selected
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> **Language**: English | [繁體中文](../locales/zh-TW/core/developer-memory.md)
|
|
4
4
|
|
|
5
|
-
**Version**: 1.
|
|
6
|
-
**Last Updated**: 2026-
|
|
5
|
+
**Version**: 1.2.0
|
|
6
|
+
**Last Updated**: 2026-09-25
|
|
7
7
|
**Applicability**: All software projects using AI assistants
|
|
8
8
|
**Scope**: universal
|
|
9
9
|
**Owning Spec**: XSPEC-291 (developer-memory has no dedicated feature XSPEC; XSPEC-291 owns it)
|
|
@@ -250,6 +250,26 @@ recorded so each value is auditable rather than arbitrary.
|
|
|
250
250
|
| `validity.type == "versioned"` AND version is outdated | Flag as stale |
|
|
251
251
|
| `validity.type == "temporal"` AND `expires_at` passed | Flag as expired |
|
|
252
252
|
| `validity.type == "evergreen"` | Skip version check |
|
|
253
|
+
| Recalled memory cites a file path or symbol (function/class) that no longer exists at that location, or has moved | Flag as `code-reference` stale — see below |
|
|
254
|
+
|
|
255
|
+
#### Code-Reference Staleness (`code-reference`)
|
|
256
|
+
|
|
257
|
+
Code moves; a memory recorded against an old location does not update itself. This check catches the case where the memory's insight is still true but its citation — a file path, or a function/class name — is not.
|
|
258
|
+
|
|
259
|
+
This reuses the **two operating modes [Knowledge Graph Memory](knowledge-graph-memory.md) §2 already defines**, rather than inventing a third:
|
|
260
|
+
|
|
261
|
+
| Mode | When | How |
|
|
262
|
+
|------|------|-----|
|
|
263
|
+
| Degraded (no graph engine) | Any tool, no extra setup — the default | Before using a memory, the assistant confirms the cited path/symbol still exists itself (`Glob`/`Grep`/`Read`) — the same mechanism already required by §5 Memory Verification Principle |
|
|
264
|
+
| Engine (a graph engine is indexed, e.g. [EngramGraph](https://github.com/AsiaOstrich/EngramGraph)'s `egr refs check`) | When available | The engine reports each citation's state: `present` / `moved` (with its new location) / `missing` / `unresolvable` |
|
|
265
|
+
|
|
266
|
+
> A correct implementation produces the same answer shape in both modes (Knowledge Graph Memory §2.2) — engine mode is faster and more complete, not different in kind.
|
|
267
|
+
|
|
268
|
+
**`unresolvable` MUST NOT be treated as `present` or `missing`.** It means the checker could not determine an answer for that citation (e.g. a cross-repo reference outside the indexed scope, per Knowledge Graph Memory §2.2's cross-domain caveat) — that uncertainty must reach the assistant as its own state, not collapse silently into a false positive (treated as still valid) or a false negative (treated as gone).
|
|
269
|
+
|
|
270
|
+
**Timing**: this check runs as part of `proactive-surfacing` (§4.1) — before a memory is shown, not after. A memory whose citation resolves to `missing` is not silently surfaced as if nothing changed.
|
|
271
|
+
|
|
272
|
+
**Scope (first batch)**: file paths and symbol names (function/class names) only. `file:line` references are explicitly **out of scope** — a line number drifts on every unrelated edit to the file, which is a different kind of staleness from "this file/symbol no longer exists" (see DEC-115 OQ-1; revisited by 2027-01-31).
|
|
253
273
|
|
|
254
274
|
#### Revision Suggestions
|
|
255
275
|
|
|
@@ -280,6 +300,7 @@ recorded so each value is auditable rather than arbitrary.
|
|
|
280
300
|
| Cooldown period | 7 days per entry | Prevent repetitive suggestions |
|
|
281
301
|
| Max per trigger | 3–5 entries | Information overload prevention |
|
|
282
302
|
| Overflow handling | AI summarizes into grouped insight | When > 5 matches found |
|
|
303
|
+
| Code-reference check | Run before surfacing (§3.4 `code-reference` staleness, degraded or engine mode) | Do not surface a memory whose file/symbol citation no longer resolves without flagging it |
|
|
283
304
|
|
|
284
305
|
#### Surfacing Format
|
|
285
306
|
|
|
@@ -541,6 +562,7 @@ by_category:
|
|
|
541
562
|
- [AI Instruction Standards](ai-instruction-standards.md) — Token-efficient format for memory system instructions
|
|
542
563
|
- [AI-Friendly Architecture](ai-friendly-architecture.md) — Project structure enabling memory integration
|
|
543
564
|
- [Documentation Writing Standards](documentation-writing-standards.md) — Writing quality for memory entries
|
|
565
|
+
- [Knowledge Graph Memory](knowledge-graph-memory.md) — Source of the degraded/engine dual-mode reused by `code-reference` staleness (§3.4)
|
|
544
566
|
|
|
545
567
|
---
|
|
546
568
|
|
|
@@ -587,10 +609,44 @@ If user feedback reveals:
|
|
|
587
609
|
|
|
588
610
|
---
|
|
589
611
|
|
|
612
|
+
## 11. Tool Adoption Example: Code-Reference Check (Non-Normative)
|
|
613
|
+
|
|
614
|
+
This section illustrates one way to wire the `code-reference` staleness check (§3.4) into a tool's own automation. It is documentation only — UDS does not ship this hook, and `uds init`/`uds update` do not install it.
|
|
615
|
+
|
|
616
|
+
### Claude Code
|
|
617
|
+
|
|
618
|
+
Claude Code's automatic memory lives outside the repo, at `~/.claude/projects/<project-path>/memory/`. A `SessionStart` hook can run the check against that directory before the session's first memory surfacing, falling back to degraded mode when no graph engine is present:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
#!/usr/bin/env bash
|
|
622
|
+
# Illustrative only — not installed by any UDS command.
|
|
623
|
+
MEMORY_DIR="$HOME/.claude/projects/$(pwd | tr '/' '-')/memory"
|
|
624
|
+
|
|
625
|
+
if command -v egr >/dev/null 2>&1 && [ -f .engram/graph.db ]; then
|
|
626
|
+
# Engine mode (§3.4): egr resolves each cited path/symbol.
|
|
627
|
+
egr refs check "$MEMORY_DIR"
|
|
628
|
+
else
|
|
629
|
+
# Degraded mode (§3.4): no engine configured — nothing to run up
|
|
630
|
+
# front; the assistant verifies each citation itself before use (§5).
|
|
631
|
+
echo "[developer-memory] no graph engine detected; degraded mode applies"
|
|
632
|
+
fi
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Other Tools
|
|
636
|
+
|
|
637
|
+
A tool without a session-start hook still satisfies this standard through either:
|
|
638
|
+
|
|
639
|
+
- a rule in the repo's own instruction file (`CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.clinerules`, `.windsurfrules`, `copilot-instructions.md`, `GEMINI.md`, `.roo/rules/`, etc.) instructing the assistant to verify a memory's cited path/symbol before relying on it; or
|
|
640
|
+
- a pre-commit check that scans the repo's own instruction file(s) for citations that no longer resolve.
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
590
644
|
## Version History
|
|
591
645
|
|
|
592
646
|
| Version | Date | Changes |
|
|
593
647
|
|---------|------|---------|
|
|
648
|
+
| 1.2.0 | 2026-09-25 | Added: `code-reference` staleness check to Review (§3.4) — a memory citing a moved/missing file path or symbol is flagged before surfacing; reuses Knowledge Graph Memory's degraded/engine dual mode instead of inventing a third; `unresolvable` may not be read as present or missing; scope is file paths and symbol names only (`file:line` explicitly out of scope, DEC-115 OQ-1); §11 adds a non-normative Claude Code adoption example (DEC-115-L1) |
|
|
649
|
+
| 1.1.1 | 2026-06-18 | Added: `Owning Spec` header pointing to XSPEC-291 (patch, no behavioral change; XSPEC-291 §11 disposition) |
|
|
594
650
|
| 1.1.0 | 2026-06-18 | Added: rationale column + configurable note to Retirement Suggestions thresholds (XSPEC-292 T8) |
|
|
595
651
|
| 1.0.0 | 2026-02-07 | Initial standard: schema, 4 operations, proactive protocol, noise control, architecture decision (Always-On Protocol) |
|
|
596
652
|
|