Files
Arcrun/system-dev/docs
uncle6me-web b223a69884 fix(portal): 藏書地圖看得到自己的知識——租戶字串改從「寫入端」來,不再拿環境變數預設值(Arcrun#108)
leo 2026-08-12 實撞:藏書地圖回 0 個庫,同一分鐘 KBDB 裡有 1854 條三元組,
`arcrun_whoami` 顯示 admin/全部知識庫、`kbdb_search` 也查得到——只有地圖那格是空的。

病根(不是資料掉了,是讀寫兩端各拿一個來源):
  寫入端 owner_id = `~/.arcrun/config.yaml` 的 `api_key`(CLI push/小幫手上傳/MCP,
    leo = `bfezv28v`)
  讀取端過濾 = `portalTenant(env) = env.CONSOLE_TENANT || "leo"`
    ——repo toml 帶的**官方 prod 值**,而 `acr` 從來不注入 CONSOLE_TENANT
  ⇒ 那個 `"leo"` 不是理論邊角,是每台 self-hosted 實例的實際行為,1854 條全被濾掉。

與 #105(`env.MCP_OWNER_NAMESPACE || "leo"`)同一句話,換一個檔案。

租戶字串該從哪裡來(本票的核心判斷):
  **從「寫入這批知識的那一方」來,不是從一份手抄的環境變數預設值來。**
  不是「掛到每個帳號上」——portal 帳號共用同一台實例的知識庫(design D-2),
  帳號之間的差別是 libraries 權限不是 owner_id;複製一份到帳號上只是多一個會過期的副本。
  #105 真正的教訓是:過濾用的租戶字串要有單一權威來源、解析不到要誠實失敗、且要能機械驗證。

修法:
1. 唯一產地 `cypher-executor/src/lib/tenant.ts`
   - `knowledgeOwner(env)` → branded `TenantId`:`ARCRUN_NAMESPACE` → `CONSOLE_TENANT` →
     丟 `TenantUnresolvedError`。**沒有字面預設值**——`|| 'leo'` 正是把「這台機器沒設定」
     偽裝成「你沒有資料」的元凶。
   - `accountTenant(env)` → 普通 `string`(帳號子 namespace `{tenant}::portal` 與 cypher
     自己寫的設定用它)。**回 string 是刻意的**:型別上就不可能流進知識資料面。
   - 資料面過濾一律經 `ownerQuery()` / `ownerField()`,只吃 `TenantId`。
2. 值的正解由 CLI 從真相源導出:`acr update` 把 config 的 `api_key` 注入成 `ARCRUN_NAMESPACE`,
   但**先驗再寫**(`GET /kbdb/map?owner_id=<api_key>` 查得到庫才寫;查不到/問不到就一個字
   都不動)。無條件覆蓋會把「知識本來就在 CONSOLE_TENANT 底下」的一鍵安裝實例指向空的那一格
   ——那是 #97/#106 那類「更新一次把人家的東西弄不見」,比原本的 bug 更糟。
   未注入時回退 CONSOLE_TENANT ⇒ 對官方 prod 與未更新的實例,這次改動是惰性的。
3. 空地圖分四態(沿 #100「讀不到就說讀不到」):no_library_grant/filtered_out/
   scope_mismatch/confirmed_empty。scope_mismatch 以前不存在,所以設定錯誤被畫成
   「你沒有資料」。回應仍不含租戶字串(design §3.3 紅線)。
4. 同族一起修(同一道閘一次抓到):console-dashboard 4 處、console-auth 1 處
   ——console 首頁的規模數字與藏書地圖對 leo 也一直是空的。

留下的閘(規則存在但沒機制驗證=會再犯第三次):
  · 型別閘:TenantId 只能由 tenant.ts 產出 → 拿隨手一個 string 去過濾,tsc 當場不給過。
  · 出貨閘:scripts/build-worker-artifacts.mjs 編 tier2 成品前先掃,違規 → 編不出成品。
  · 閘自己可測:規則是純函式(tenant-source-rules.mjs),tests/tenant-gate.test.ts
    逐條驗「5 種壞例子會擋」+「11 種合法寫法零誤攔」;掃描範圍只有 src/,擋不到自己。
  規範寫入 .claude/rules/02-forbidden.md 第六類、system-dev/wiki/mistakes.md #26。

沒動:庫權限過濾(一字未改,回歸測試釘住)、帳號資料落點、任何金鑰、租戶字串仍不下發前端。

驗證:
  cypher   vitest 441 綠 / 14 紅,14 紅與 base commit e05518a 逐字相同(既有)
           tsc 5 個既有錯誤,零新增
  cli      node:test 60/60 綠(含本次新增 12 條);tsc 零錯誤
  閘       壞例子實跑 exit 1;build 實跑「建置中止」;乾淨時實跑通過
  端到端   ◐ 未驗:需部署到 leo21c,那道閘要 leo 親手解(見 PR ③)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 00:15:58 +08:00
..

Arcrun 文件分類索引

LLM Wiki 結構:長期記憶系統,防止決策遺忘和重複錯誤。 參考:Andrej Karpathy — A Closer Look at How LLMs Remember


分類規則

目錄 用途 例子
1-vision/ 「為什麼」:設計哲學、核心價值、前瞻方向 arcrun 優勢、Haiku 就能搞定、薄殼原則
2-architecture/ 「是什麼」:系統設計、技術棧、組件關係 MVP 架構、零件模型、KV 存儲方案
2-architecture/decisions/ 架構關鍵決策和 trade-off Service binding 為什麼廢、R2 只用 Phase 5、同 zone 1042 解法
3-specs/ 需求和 SDD:設計文件、任務清單 (從 .agents/specs/ 搬來)
4-guides/ 操作手冊:如何做、工作流程 部署流程、CLI 用法、壓測方法
5-records/ 日誌和證據:事件、測試、決策履歷 Incident、壓測報告、問題追蹤
5-records/incidents/ 生產問題復盤:故障原因、改進方案 2026-05-13 同 zone 1042、2026-06-06 MCP route bug
5-records/test-reports/ 壓測結果、驗收報告 2026-06-07 公庫上線測試、2026-06-08 Haiku 乾淨重測
6-user/ 對外文件:README、教程、FAQ self-hosted 安裝、開發者指南

.claude/wiki/ — LLM 本機記憶

檔案 用途 更新頻率
INDEX.md wiki 目錄和導引 每次新增
mistakes.md CC(我)常犯的錯 + 避坑方法 每次踩坑後
status.md 當前進度、已知問題、下一步 每次 session 結束
decisions-summary.md 架構決策快速參考(不是全文,是摘要 + 連結) 每次大決策後
modules/[name].md 關鍵模組說明:職責、入口、常見誤解 不定期補充

檔案遷移計畫

當前位置 新位置 優先級
根目錄 .md(除 README/CLAUDE → docs/ 分類
.agents/specs/ → docs/3-specs/
.claude/rules/ → docs/2-architecture/ + wiki
docs/incidents/ → docs/5-records/incidents/
壓測報告 → docs/5-records/test-reports/

下一步

所有檔案整理進此結構後,wiki 將作為 CC 和任何 LLM 的長期記憶入口。