Commit Graph

6 Commits

Author SHA1 Message Date
Leo 8ab6f8a66b fix(cypher): interpolateString single-ref array/object pass-through (P0 #11)
mira_feed_watcher 第一輪 cron tick 跑 264ms 完成但 0 raw 處理 — 挖到 root cause:

interpolateString 看到模板就 string.replace,非 string 值(如 kbdb_get 回的
blocks 陣列)一律 JSON.stringify。所以 `items: "{{list_raws.blocks}}"` 把
陣列轉成字串給 filter 零件,filter 收到字串 != array → items 被忽略 →
FOREACH 跑 0 次 → watcher 看似成功實則空跑。

修:interpolateString 加 single-ref pass-through —— 若整個值是純單一 `{{x}}`
引用,回 raw value(保留 array / object 型別)。多 ref / 混合文字仍 stringify。

對應 SDD: arcrun.md 三-A P0 #11。

下一輪 cron tick 應該真正處理 raws,加 wiki-processed tag。
2026-05-14 14:54:26 +08:00
Leo 9560485937 feat(cypher): add scheduled() handler — arcrun-native cron 排程基建
對應 arcrun.md 三-A P1 #3。

緣由:cron 零件存在但只做 expression validation,沒有真正的排程跑。leo 指出
「邊用 arcrun 邊修,不要 workaround」— 撤回前一輪的 /mira/wiki-from-raw
mira-specific route(違反 mira CLAUDE.md §1.5 一律 arcrun-native),改補
真正的 cron infra。

加入:
- src/lib/cron-match.ts — 5 欄位 cron matcher(* / N / */N / a-b / a,b 組合)
- src/scheduled.ts — handler:掃 KV cron-idx: prefix,比對 controller.scheduledTime
  → executeWebhookGraph 背景跑
- routes/webhooks-named.ts — acr push 時偵測首節點 cron → 存 cron_expr 到 record
  + 額外寫 cron-idx:{api_key}:{name} 輕量索引;DELETE 一併清理
- src/index.ts — export default 改 { fetch, scheduled }
- wrangler.toml — [triggers] crons = ["* * * * *"](每分鐘 tick)
- wrangler.toml — workers_dev = true 供 self-fetch self-trigger 用
- tests/arcrun-test/cron_heartbeat.yaml — 健康監控 workflow(每分鐘 fire + set 節點)

撤回:
- 刪 src/routes/mira.ts(mira-specific workaround)
- types.ts 拿掉 MIRA_CONFIG
- index.ts 拿掉 miraRouter wire
- landing/app/mira/feed/page.tsx 拿掉 triggerWikiSynthesis 呼叫

下一輪:mira_feed_watcher.yaml(mira side),可能要先補 kbdb_get filter +
CALLS_SUBFLOW wire(arcrun.md 列為跟進)。
2026-05-14 14:04:57 +08:00
Leo 660b32eafd feat(mira): 河道 → wiki 自動化(fire-and-forget 觸發 wiki_synthesis)
對應 polaris/mira/.agents/specs/mira-app/tasks.md 7B.3h(簡化版)。

原計畫用 arcrun cron 零件 → cypher-executor scheduled() handler,但發現
cron 零件只是 validator,cypher-executor 還沒實作 scheduled()。為了不擋
「河道書寫 → 自動產 wiki」這條 UX,先做 fire-and-forget 版本:

- 新 cypher-executor route POST /mira/wiki-from-raw
  - body: { raw_block_id }
  - server 端從 MIRA_CONFIG secret 補 partner key / mira_token / 三個 block IDs
  - waitUntil 背景跑 executeWebhookGraph,立刻回 202
- landing 河道 post composer 成功寫 raw 後 fire-and-forget triggerWikiSynthesis()
  跟既有 triggerAiReply() 同範式
- types.ts 加 MIRA_CONFIG?: string

部署後需手動:
  echo '{"service_api_key":"ak_...","data_api_key":"ak_...","schema_block_id":"...","skill_block_id":"...","entities_block_id":"...","mira_token":"..."}' \
    | wrangler secret put MIRA_CONFIG

UX:河道貼一則 → AI reply 30s 內 → wiki 60-90s 內出現在 /mira/wiki。

arcrun.md 記 P1 #3:cypher-executor 加 scheduled() handler,那是真正的
cron 路線,封測前不擋。
2026-05-14 13:50:13 +08:00
Leo d6d2cecfb5 fix(cypher): resumeFromPaused 漏 node-id namespace 導致下游模板找不到 paused 結果
mira 7B.3f PATCH 測試踩到:classify 跟 compose 都是 claude_api(兩次 paused/resumed),
upsert_index_entry config 寫 `{{compose_index_entry.data.text}}`,但 PATCH 跑出的
block content 是字面 `{{compose_index_entry.data.text}}` —— 模板沒被替換。

根因:resumeFromPaused 把 callback_result spread 到 top-level,但漏了
`[paused_node_id]: callback_result` 的 namespace 包裝。同步路徑的 propagateCtx
有做這件事,resume 路徑沒做,行為不一致。

修:mergedContext 加 [paused_node_id]: callback_result 一行,跟 propagateCtx 對齊。

arcrun.md 同步補三-B「新零件 checklist」+ 三-C「workers_dev=true 全 component
自動化」收尾紀錄。
2026-05-14 12:06:59 +08:00
Leo 4e746986b4 feat(arcrun): add kbdb_upsert_block component for idempotent block writes
對應 mira 7B.3f:per-entity index-entry 維護需要「找有則 PATCH 沒找到 POST」,
arcrun workflow 沒 IF/branch 能力(已知限制 #1 + 新 P1 #1),用 kbdb_upsert_block
零件把分支邏輯封進零件內:GET /blocks?page_name=X → user_id filter → 找到 PATCH 沒找到 POST。
page_name 當 idempotency key,未來其他「找有則改沒則建」場景共用。

SDD:polaris/mira/.agents/specs/mira-app/design.md §3.5.12.4.1
     matrix/arcrun/.agents/specs/arcrun/arcrun.md 三-A P1 #1 + 三-B 新零件加入紀錄
2026-05-14 10:18:21 +08:00
Leo 13b01328c1 docs: add SDD specs + user requirements + tests
- .agents/specs/: spec-driven-dev docs for arcrun MVP, auth-recipe,
  credential-primitives-wasm (active refactor), landing-page,
  sdk-and-website, u6u-core-mvp, u6u-platform-evolution.
- .agents/steerings/tech.md: detailed tech stack rationale.
- docs/user_requirements/: long-form requirements incl. credential
  primitives, pages spec, py strategy analysis.
- tests/: end-to-end harness scaffolding.

These are the durable context backing CLAUDE.md's SDD protocol.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:48:24 +08:00