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 |
|
uncle6me-web
|
42cb1d7aa9
|
console-ui:把「線上跑的是不是當代的」變成機械判準,並接進部署鏈
leo 2026-08-08:「已經發生過一次這個錯誤,把舊版界面上到 prod,
你要確定不可再犯。」
實測(repo 對線上,純文字資產比對):
repo portal/index.html 343,969 bytes
線上 mira.uncle6.me 82,911 bytes(Songti 12 處,舊金色 serif 品牌)
線上 pages.dev 82,911 bytes(同上)
而 e730b3f 那版 verify-live 對這兩站**三項檢查全過**——因為它驗的是
組態(apiBase、profile 的 views/home),不是世代。
⇒ 一個網址可以組態完全正確、卻對外展示一套早就被淘汰的介面,
而所有機械檢查都說它是綠的。這就是要消滅的狀態。
本次落地:
一、世代指紋(targets.mjs)
逐一取線上/產物的資產(index / portal / console / favicon.svg),
遮掉本來就該隨部署目標不同的那兩行(VIEWS/HOME),其餘按位元組比對。
刻意不用關鍵字清單——清單要人維護,而舊世代能無聲上線正是因為沒人記得維護它。
誠實 trade-off 寫在檔內:repo 改了沒部署就會判紅,那是正確的(那時線上確實不當代)。
二、宣告值真的寫進產物(收掉 e730b3f 標的 WIP)
deploy.mjs 改為由 targets.mjs 產出 .staging/<目標> 再推:
config.js 由宣告值即時產生、console 的 VIEWS/HOME 依 profile 覆寫,
**覆寫沒命中就中止部署**;推之前回頭讀磁碟上那份驗一次(不看腳本印了什麼)。
public/config.js 刪除——它是產物不是原始碼。
三、修好一道從 08-03 起就在誤判的閘
t160 的世代閘比對 portal 全文含「登記新庫」即拒部,而 66f1b59(08-03)
加了一則**說明「已經把它拿掉了」的 HTML 註解** ⇒ 該閘自那天起每次誤判,
npm run deploy:personal 連續五天推不出去。改成剝掉註解後只看可見內容,
並降級為輔助(主判準是指紋)。這正是「手工關鍵字閘會腐爛」的實例。
四、讓它在該跑的時候真的被跑到(不再生出沒人記得執行的腳本)
· deploy.mjs 推完自動回頭驗線上,不過就算本次部署失敗
· .deploy-state.json 只在線上實測通過後才寫,且不進版控
(新 checkout 沒紀錄=狀態未知=該被提醒,而不是繼承別人的綠燈)
· Stop hook 每回合離線比對「手上這一代 vs 最後一次驗過的部署」,
在要說「做完了」的那一刻出聲(實測 0.096s,不連網)
五、uncle6 邊界寫進工具本身(leo 08-08:「要看範例只在 youlin 網站,不要去碰 uncle6」)
deploy.targets.json 的 enterprise 標 frozen:deploy 拒絕部署、verify 連抓都不抓。
目標本身保留不刪——刪掉就變成下一個 AI 眼中「從來沒有過這個站」的失憶。
同源清掉兩處還活著的舊記錄:README 的線上 demo 連結、public/index.html 的註解。
驗收證據見 commit 後的實測輸出(舊世代樣本取自 git 歷史 ad367e4,本機起站餵判準,
未碰任何線上資源)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-08 20:36:18 +08:00 |
|
Leo
|
20c7610371
|
refactor: 移除已廢棄的自管加密金鑰機制(credential 全面託管 CF Workers Secrets)
leo 2026-07-20 明令:「已經改用 cf 自己的 secrets,不要再說它了」
「我希望以後再也看不到這個詞再出現」
背景:credential 早已遷移至 CF Workers per-script Secrets + D1 目錄,
舊的自管金鑰(client 端 AES-GCM + KV 密文 + crypto_decrypt)是遷移期遺留。
本次連根移除,含一併作廢的死 SaaS 碼。
移除:
- 舊 KV 密文解密路徑(credential-injector.ts 整檔、dual-read fallback)
前置驗證:leo21c / youlin 兩帳號 CREDENTIALS_KV 實測 *:cred:* 皆 0 筆
- migrate-to-workers-secrets 搬家端點(回填已完成,無可回填)
- /register 路由與 generateApiKey(HMAC 產 ak_ key 是 SaaS 遺物;
self-hosted 走 namespace 明碼 D21,已無人使用)
- platform_crypto component(三帳號實測 404 已退役,無 workflow 引用)
保留(附理由):
- crypto_decrypt 保留為永遠回失敗的 stub——現役三個 auth .wasm 仍宣告該
import,缺項會讓 WASM instantiate 直接失敗。待零件重編後可真正刪除。
順帶修復(原不在範圍,但會實際壞事):
- /auth/callback 有 `if (!key) redirect(server_error)` 閘,未設該 secret 的
實例會登入直接失敗 → 已移除
- OAuth 兩處把 provider token 寫進舊加密 KV(租戶鍵與實際 api_key 在 rotate
後必然分歧,已失效)→ 改導向 Workers Secrets,包 try/catch 不影響登入
- acr init Standard 模式呼叫已刪除的 /register → 改引導 OAuth 取 key
- .claude/rules 與 system-dev/docs 是同一規範的兩份鏡像,先前只改 rules
導致鏡像仍在教舊做法 → 已同步(此類雙檔同步應納入檢查)
新用戶安裝從此零 secret 前置。
測試 187/188(唯一 fail 為 pre-existing,stash 驗證與本次無關);
cypher-executor 與 cli typecheck 全綠。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-21 01:32:48 +08:00 |
|
uncle6me-web
|
9cc29f5dfb
|
docs(wiki): Mira Console 完整版收尾——mistakes #24 三層跳脫驗證法+DELETE 假綠缺口、status 更新 (Arcrun#3 console 系)
|
2026-07-04 17:51:25 +08:00 |
|
Claude
|
c830150da1
|
docs(wiki): 記錄 acr update 部署源綁 GitHub codeload 的框架級發現(mistakes #23)
雲端工人跑 Arcrun#3 控制台頁時發現:acr update 部署物永遠從 GitHub codeload
tarball 抓,跟本地/Gitea checkout 脫鉤——D20 鎖死 GitHub 的雲端工人若照字面
指示部署會蓋掉自己的改動卻回報成功(假綠)。本次改手工複刻注入邏輯部署
單一 worker 繞過此坑,記錄供下次沿用;多 worker 場景正解留 leo 裁。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-02 09:10:00 +00:00 |
|
uncle6me-web
|
31d4a9c47b
|
feat(sprint): T-loop1d 今晚任務——雲端做 Arcrun#3 控制台頁(第二次壓測,跨多repo)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-02 16:46:52 +08:00 |
|
uncle6me-web
|
f21906ca6a
|
chore(wiki): 本 session capture(薄殼防複發/歷史債卡 + mistakes #19-21 + status)
兩次 /wiki-capture 累積的知識落盤:
- cards/decisions/ 新卡:薄殼防複發-能力對照表加smoke、薄殼規則晚於實作-MCP漂移是歷史債
(+ 00-INDEX 編入,決策桶現 15 張)
- mistakes #19 死端點假綠(grep route/smoke 驗端點存在)
- mistakes #20 gitignored 檔無 git 史(時間靠檔內註記)
- mistakes #21 wrangler.toml services=[...] inline 在 [vars] 後被吸成 vars.services(issue #12)
- decisions-summary:薄殼防複發機制、workflow description 由操盤 CC 據實生成
- status:本 session #8/#11/#12 進度 + merge 結果
純記憶/文檔,無 code。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-28 01:43:26 +08:00 |
|
uncle6me-web
|
558e80b4da
|
chore(wiki): wiki-init 補骨架 + system-dev-template 安裝/更新腳本
wiki 已初始化過(push 檔活躍維護),本次補從沒建的 pull 層 + arcrun 化範本:
- cards/decisions/ 14 張決策原子卡(含 gloss/實體/typed-edge 三元組):
從 decisions-summary 全量改寫 13 + 新增「薄殼規則晚於實作-MCP漂移是歷史債」1
- TAXONOMY 從 PKM 範本換成 arcrun 軸(子系統 零件架構/cypher/credential/recipe/kbdb/
薄殼/部署/平台原則 + 形態 架構決策/踩坑/機制說明/禁令/案例經驗)
- principles 填 13 條跨全局原則(從 rules/ + mindset 蒸餾)
- INDEX 真實視圖(子系統角度 + 決策角度,指向 cards)
- system-dev/scripts/ + scripts/ install/update 安裝腳本(template 接入)
純基建/文檔,無業務 code(功能 code 見前一 commit)。
raw source(docs/)0 異動、wiki 卡際連結無斷鏈。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-27 17:53:37 +08:00 |
|