insight_selection line
insight_selection 記錄某個聊天室對本文件 system tag 的逐室加入。它的自然身分是 (本文件的 system tag, chatroom) 這一組。Tag 永遠不由作者撰寫——它就是 header.system——因此這是唯一完全沒有 spec 的具狀態 kind。
JSONL Line
{"kind":"insight_selection","chatroom":"$room:Front Desk/Reception"}欄位契約
| 欄位 | 必填 | 精確契約 |
|---|---|---|
kind | 是 | 固定 "insight_selection" |
chatroom | 是 | 1–160 字元,符合 `^([a-z0-9][a-z0-9_.-]35 |
state | 否 | "present" 或 "absent",預設 "present" |
沒有 ref、沒有 spec、也沒有 renamed_from。chatroom 可以是原始 chatroom UUID,或一個 $room: 身分 token;此處只接受 $room: 家族,填 $user:、$dept: 或 $smc: 會被欄位 pattern 在 parse 階段拒絕。
兩道 scope 檢查
兩道檢查都是 validate 階段錯誤,因此會讓整份文件無法 apply:
insight_selection is only valid for department-scope documents
insight_selection requires a non-empty system (header.system)department scope 這道檢查位於伺服器 differ,它具備獨立行解析器沒有的 scope 脈絡。工作台能單靠 header.system 證明第二道,但永遠證明不了第一道——chatroom 或 company scope 的文件必須以伺服器 plan 檢查。
Ref 與身分規則
Qualified ref 是 insight.{解析後的 chatroom uuid},在 token 解析之後建立——所以指向同一個聊天室的原始 ID 文件與 $room: 文件會落在同一列 state 並收斂。State 列帶有 resource_type: "insight_selection"、resource_id: "insight_selection:{tag_id}:{chatroom_id}",以及 null 的 table_id,因為 insight selection 不是資料表子資源。
兩行解析到同一個聊天室屬於與順序相關的衝突,會被拒絕:
duplicate insight_selection line for chatroom '33333333-3333-4333-8333-333333333333'這包含「一行填原始 ID、一行填 $room: token 但指向同一室」的情況。工作台只能比對authored 值,因此它抓得到字面完全相同的情形;解析後才碰撞的情形需要伺服器 plan。
生命週期與規劃
| 宣告 | System tag | Live selection | Action |
|---|---|---|---|
present | 尚不存在 | — | create,附帶 warning |
present | 存在 | 不存在 | create |
present | 存在 | 存在 | noop |
absent | 尚不存在 | — | noop,附帶 warning |
absent | 存在 | 不存在 | noop,附帶 warning |
absent | 存在 | 存在 | delete |
兩則 warning 是:
insight system tag does not exist yet; it is created on apply — selection legality cannot be fully verified until then
insight selection not present; nothing to remove第一則是首次 apply 到全新 scope 的正常樣貌:plan 在 tag 存在之前無法完整驗證選擇,所以它如實說明,而不是假裝可以。
Apply 行為
Present 行會確保 selection 列存在,並在 system tag 尚不存在時,透過 tag 自動同步使用的同一條路徑建立它。Apply 接著驗證該聊天室存在、未被刪除,且屬於該部門所在的公司。Absent 行會刪除 selection 列與其 state 列。
insight_selection 'insight.<uuid>': chatroom does not exist or is deleted
insight_selection 'insight.<uuid>': chatroom belongs to a different company
insight_selection: <token resolution error>
insight_selection: chatroom token '$room:Reception' now resolves to a different chatroom than it did at plan time; run plan again最後一則正是讓「釘住 plan」對 token 文件有意義的那道重新檢查。
Export
Export 為每個 live selection 輸出一行,依 chatroom ID 排序,且只在「department scope 且 system 非空」的 export 中出現。chatroom 在能無歧義解析時寫成 $room: token,否則寫原始 UUID。state 會完全省略——匯入時預設為 present——所以來回一趟會收斂為 noop。
若資料庫中沒有 insight-selection 資料表(尚未套用 migration 的 scope),匯出器會略過整個區塊而不是失敗;若內省本身出錯,則假設該表存在。
驗證錯誤
[{"type": "missing", "loc": ["insight_selection", "chatroom"], "msg": "Field required", "url": "https://errors.pydantic.dev/2.12/v/missing"}]
[{"type": "string_pattern_mismatch", "loc": ["insight_selection", "chatroom"], "msg": "String should match pattern '^([a-z0-9][a-z0-9_.-]{0,35}|\\$room:[^\\r\\n]{1,150})$'", "ctx": {"pattern": "^([a-z0-9][a-z0-9_.-]{0,35}|\\$room:[^\\r\\n]{1,150})$"}, "url": "https://errors.pydantic.dev/2.12/v/string_pattern_mismatch"}]
insight_selection requires a non-empty system (header.system)
duplicate insight_selection line for chatroom '<uuid>'動手試試
在 IaC 工作台加入一個 system 非空的 header 與上面的範例行。刪掉 header 觀察 system 檢查觸發,還原後把 token 改成 $user:someone,確認 pattern 會在 parse 階段拒絕它。這個加入實際開啟了什麼,請見洞察系統。