[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83405":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":15,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":13,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":9,"pushedAt":9,"updatedAt":21,"readmeContent":22,"aiSummary":9,"trendingCount":14,"starSnapshotCount":14,"syncStatus":13,"lastSyncTime":23,"discoverSource":24},83405,"Alaya","amanayayatu-tech\u002FAlaya","amanayayatu-tech","flow everything",null,"TypeScript",115,5,2,0,38,62.13,false,"main",true,[],"2026-06-12 04:01:41","> 迭代前必读：[PRINCIPLES.md](.\u002FPRINCIPLES.md)。违反 Part 1 任何一条，等于破坏 Alaya 的产品根基。\n\n# Alaya\n\nAlaya 是一个本地优先的 AI-native「认知复利飞轮」系统。它把每一轮产品或运营动作沉淀为可审计资产：预测、观察、误差归因、知识、人工闸门和下一轮决策。\n\n项目的核心目标不是让 Agent 无限制自动行动，而是让 AI 在可追责、可回滚、可复盘的约束下，持续把经验变成下一轮更好的判断。\n\n## 一句话理解\n\nAlaya = 本地 SQLite 记忆层 + 5 个 Agent 飞轮 + 人工闸门 + 预测账簿 + 知识库 + 可选真实 LLM \u002F GitHub Sensor。\n\n默认模式使用 deterministic mock LLM，不调用外部模型；配置 OpenAI-compatible provider 后可以切到真实 LLM。\n\n## 当前状态\n\n| 部分 | 状态 | 说明 |\n| --- | --- | --- |\n| Core | 可运行 | TypeScript 纯内核，验证 4 轮认知复利飞轮 |\n| Web App | 可运行 | Express + React + SQLite，本地完整 MVP |\n| LLM | mock \u002F OpenAI-compatible | 默认 mock，可切 OpenAI \u002F MiniMax 等兼容端点；提供 provider canary、失败类型分类和分 Agent latency 聚合 |\n| Scheduler | 可运行 | 自动推进 cycle；第 5 轮起可由自主目标生成器接管，受 blocking gate、预算和反空转风险闸约束 |\n| Prediction Ledger | 可运行 | Claim schema 强制 `operator >=\u002F\u003C=`、scale 正下限、metric weight 下限、完整预测契约和 `worstClaimError` |\n| Sensor | 可运行 | 支持 GitHub Issues、表单反馈和本地 CSV\u002FJSON 业务信号导入；所有信号先过 Meaning Gate，不直接激活知识 |\n| Notifications | 可运行 | Telegram 单向通知与双向审批卡片；支持 Human Gate 推送、`\u002Fstatus`、`\u002Fgates`、长轮询 callback 和 offset 持久化 |\n| Builder | 可运行 | 支持 governed Codex\u002FCodex CLI dry-run 变更包；非 dry-run apply 必须有 shell capability 和匹配 idempotency risk gate，且不自动执行 patch |\n| Knowledge | 可运行 | SQLite FTS5 搜索、任务前知识注入、近义合并、`supersededBy` 保留、冲突检测、复核工作流、时间衰减和详情引用上限保护 |\n| Ops Metrics | 可运行 | 提供 human gate resolution、LLM cost per cycle、measurable claim ratio、knowledge reuse、blocking backlog 和 compounding gain proxy |\n| Health | 可运行 | `\u002Fhealthz`、`\u002Freadyz`、`\u002Fmetrics` 提供运行探针；`\u002Fhealth` 页面与 `\u002Fapi\u002Fflywheel\u002Fhealth` API 展示复利、知识成熟和 human gate 压力 |\n| Governance | 可运行 | `PRINCIPLES.md`、guard 脚本、CI、secret scan、capability gate、autonomous stop risks 和验证脚本约束核心底线 |\n| Long-run Hardening | 可运行 | 显式运行模式、env fail-fast、脱敏、action ledger、health\u002Fready\u002Fmetrics、Docker shadow compose 和备份\u002F恢复脚本 |\n\n## 目录\n\n- [快速开始](#快速开始)\n- [项目结构](#项目结构)\n- [系统架构](#系统架构)\n- [核心概念](#核心概念)\n- [自主进化与长期验证](#自主进化与长期验证)\n- [Web 功能地图](#web-功能地图)\n- [Telegram 移动端通知与审批](#telegram-移动端通知与审批)\n- [常用命令](#常用命令)\n- [运行模式与安全模型](#运行模式与安全模型)\n- [数据库迁移、备份与恢复](#数据库迁移备份与恢复)\n- [Docker Shadow 部署与 smoke 验证](#docker-shadow-部署与-smoke-验证)\n- [可观测性与审计账本](#可观测性与审计账本)\n- [真实 LLM 与 Secret](#真实-llm-与-secret)\n- [CI 与 24h 验证](#ci-与-24h-验证)\n- [本地数据](#本地数据)\n- [API 概览](#api-概览)\n- [验证记录](#验证记录)\n- [路线图](#路线图)\n- [文档索引](#文档索引)\n\n## 快速开始\n\n要求：\n\n- Node.js 20+\n- npm\n\n安装依赖：\n\n```bash\nnpm run install:all\n```\n\n启动 Web 应用：\n\n```bash\nnpm run dev\n```\n\n默认地址：\n\n```text\nhttp:\u002F\u002Flocalhost:5000\n```\n\n如果 5000 端口被占用：\n\n```bash\nPORT=5001 npm run dev\n```\n\n首次启动会在 `alaya-app\u002F` 下创建本地 SQLite 数据库，并 seed 一个「一键发布演示项目」。演示数据包含 4 轮闭环、知识沉淀、预测账簿、人工闸门和 Agent 运行记录。\n\n## 项目结构\n\n```text\n.\n├── alaya-core\u002F     # 纯 TypeScript 内核：飞轮、状态机、LLM provider、单元测试\n├── alaya-app\u002F      # Express + React + SQLite 本地 Web MVP\n├── scripts\u002F        # 守卫、E2E、live readiness、本地 secret 工具\n├── PRINCIPLES.md   # 项目底线：纯函数、人工闸门、审计写路径、LLM 边界等\n├── Alaya_PRD.md    # 原始产品需求文档\n└── README.md       # 当前入口文档\n```\n\n两个主要包：\n\n- `alaya-core`：回答「飞轮逻辑是否成立」。它不依赖 Web，也不依赖数据库。\n- `alaya-app`：把 core 接入数据库、页面、Scheduler、Human Gates、Sensor 和 API。\n\n## 系统架构\n\n```mermaid\nflowchart LR\n  UI[\"React Web UI\"] --> API[\"Express REST API\"]\n  API --> DB[\"SQLite + FTS5\"]\n  API --> Scheduler[\"Scheduler\"]\n  API --> Sensor[\"External Sensor\"]\n  Scheduler --> Notify[\"NotificationBus\"]\n  Notify --> Telegram[\"Telegram Bot API\"]\n  Telegram --> Phone[\"Mobile Telegram\"]\n  Scheduler --> Agents[\"5 Agents\"]\n  Sensor --> Gates[\"Human Gates\"]\n  Telegram --> Gates\n  Agents --> LLM[\"Mock or OpenAI-compatible LLM\"]\n  Agents --> Core[\"Pure Core Functions\"]\n  Core --> KB[\"Knowledge Base\"]\n  KB --> Agents\n  Gates --> Scheduler\n  DB --> UI\n```\n\n运行链路：\n\n```text\nReact\u002FVite -> Express API -> SQLite\u002FFTS5 -> Scheduler -> 5 Agents -> LLM Provider\n```\n\n所有高风险自动化都必须经过代码约束和人工闸门。LLM 可以给建议，但不能绕过预测账簿、知识状态机、审计日志和 gate budget。\n\n## 核心概念\n\n### 1. Flywheel\n\n每一轮 cycle 都会经历：\n\n```text\n预测 -> 行动 -> 观察 -> 误差归因 -> 知识沉淀 -> 下一轮引用\n```\n\n第 3 轮必须被前两轮知识真实改变，而不是形式上引用。第 4 轮继续要求产出 rollback-ready change package 和 audit summary。第 5 轮起，如果脚本化场景已经用尽，Scheduler 会生成新的自主目标，而不是复用最后一轮模板或停止在场景耗尽状态。\n\n### 2. Five Agents\n\n| Agent | 作用 |\n| --- | --- |\n| Orchestrator | 选择本轮目标、引用知识、提出预测与动作 |\n| Sensor | 收集反馈和外部信号 |\n| Builder | 形成任务或变更包 |\n| Distiller | 把观察与误差提炼成知识 |\n| Librarian | 管理知识状态、晋级、过期、冲突和隔离 |\n\n### 3. Human Gates\n\n系统内置三类闸门：\n\n- Direction gate：方向是否允许执行\n- Meaning gate：信号是否值得进入知识循环\n- Risk gate：风险、成本、阻断条件是否需要人工处理\n\nHuman Gate 可以在 Web UI 中处理，也可以通过 Telegram 接收移动端通知。非阻塞 `meaning` gate 会在 Telegram 卡片中显示批准\u002F否决按钮；阻塞型 `direction` \u002F `risk` gate 只显示 Web 深链，避免手机端一键放行高风险阻断闸。\n\nMeaning Gate 被批准后，`HumanGateService` 会把对应外部信号写成 active knowledge，并通过同一条审批服务记录 `decision_log`、`event_log` 和 `action_ledger`。Gate resolve 与知识写入在数据库事务中执行；如果知识写入失败，gate 不会被错误地标记为已批准，后续重试也会幂等补建缺失知识。\n\n### 4. Prediction Ledger\n\n每个 claim 都要能被观测和计算误差。系统不会把「感觉变好」当作成功证明，而是保存目标、实际值、误差、归因和修正动作。\n\n`metric_threshold` claim 的核心契约：\n\n- `operator` 必填且只能是 `>=` 或 `\u003C=`。误差方向因子由 `operator` 推导：`>=` 表示越大越好，`\u003C=` 表示越小越好；调用方不再手填方向。\n- `scale` 如提供必须 `>= 1e-6`；未提供时使用 `max(abs(target), 1e-6)`，避免 target 为 0 时除零。\n- `metric_threshold` 的 `weight` 必须至少为 3；`E_cycle` 计算也会在 compute 层强制关键指标权重下限，避免大量低价值预测稀释关键失败。\n- `E_cycle` 同时输出 `worstClaimError`，用于连续两轮关键 claim 超阈值的单独判定。\n\n所有可测 claim，包括 `metric_threshold`、`binary`、`categorical` 和 `directional`，都可以携带预测契约字段：\n\n```text\nexpectedObservation\ntimeWindow\nsuccessThreshold\nfailureThreshold\nuncertainty\n```\n\nScheduler 会用这些字段判断预测是否能成为可靠学习信号。New Project 的 Onboarding Interview 强制用户设置首条可测 claim 的指标、operator 和目标阈值；Project Setup 可后续调整，但同样只允许 `>=` \u002F `\u003C=`。\n\n### 5. Knowledge Base\n\n知识不是普通笔记。每条知识都有置信度、状态、来源、引用记录、有效期和治理字段。过期、冲突或未经验证的知识不能无条件支撑下一轮决策。\n\nLibrarian 会对近义知识做熵减合并：保留主条目，给被合并条目写入 `supersededBy`，不做物理删除。检索和高风险证据集默认排除 stale、quarantined、conflict 和 superseded 条目。\n\n任务前知识注入由 `alaya-app\u002Fserver\u002FknowledgeInjection.ts` 负责：系统根据当前任务文本从 FTS5 检索 active\u002Fstrong 且未被 supersede 的知识，构造有上限的 `[PRIOR KNOWLEDGE]` 上下文并写回 `usageCount`、`lastInjectedAt` 和审计事件。显式 schema migration 会执行 FTS5 `rebuild`，确保旧库已有知识也能被新建索引检索到；shadow\u002Fstaging\u002Fproduction 的常态启动只校验 schema readiness。\n\n时间衰减由 `applyTimeDecay` 和 Scheduler 共同执行。`lastVerifiedAt` 保留真实验证时间，`lastDecayedAt` 记录最近一次自动衰减时间，避免周期性 tick 对同一历史区间重复衰减。被衰减到阈值以下的知识会降级为 stale，并通过 `time_decay_scheduler` 写入审计日志。\n\n## 自主进化与长期验证\n\nAlaya 的默认 4 轮场景仍然作为治理回归基线保留。超过第 4 轮后，系统会基于当前项目身份、世界模型、已验证知识、上轮误差和近期反馈生成下一轮目标。\n\n自主进化有四类停机风险闸：\n\n- `evolution_stalled`：连续误差不改善。\n- `goal_repetition`：新目标与历史目标或被拒方向重复。\n- `maturation_stall`：决策知识增长但 strong 知识不成熟。\n- `knowledge_explosion`：可决策知识规模异常增长。\n\n长程离线验证：\n\n```bash\nnpm run e2e:long-evolution\n```\n\n该脚本会跑 20 轮 mock LLM 飞轮，检查不再出现 `scenario_exhausted`、目标不重复、知识规模有界、合并事件有审计记录、blocking gate 不膨胀。\n\n## Web 功能地图\n\n| 页面 | 作用 |\n| --- | --- |\n| Dashboard | 当前项目、cycle、风险、预算、最近知识 |\n| Human Gates | 批准、修改或否决方向闸、意义闸、风险闸 |\n| Prediction Ledger | 查看预测、观察、误差和归因 |\n| Knowledge Base | 搜索知识、查看置信度、来源和 Agent 引用 |\n| Cycle Review | 复盘单轮 cycle、Agent 输出、复利证据和本轮高风险 action ledger 时间线 |\n| Flywheel Health | 查看每轮新增知识、晋级、纠错、知识注入、知识状态和复利证明 |\n| New Project | Onboarding Interview，创建新项目 |\n| Project Setup | 修正 seed identity、world model、redlines 和第一轮 claim |\n\n## Telegram 移动端通知与审批\n\nTelegram 集成让 Alaya 在手机上主动提醒用户：有 blocking gate、safety mode 或 pending Human Gate 时，不需要一直打开桌面浏览器。实现位于 `alaya-app\u002Fserver\u002Fnotifications\u002F`，由 `scheduler.ts` 懒加载 `NotificationBus` 与 `TelegramAdapter`。\n\n### 功能范围\n\n| 场景 | 行为 |\n| --- | --- |\n| Scheduler 新建 pending gate | 推送 Telegram 卡片；按 `gateId` 去重，避免每个 tick 重复通知 |\n| 非阻塞 `meaning` gate | 卡片显示 `✅ 批准` \u002F `❌ 否决`，点击后走 `HumanGateService`，写入 `decision_log`、`event_log` 和 `action_ledger` |\n| 阻塞 `direction` \u002F `risk` gate | 卡片只显示 `在 Web 处理`，跳到 `\u002F#\u002Fhuman-gates?gate=...` |\n| Safety mode | 推送纯文本通知，包含项目、原因和 Web UI 链接 |\n| `\u002Fstatus` | 返回所有项目的当前 cycle、pending gates、知识数和最后事件时间 |\n| `\u002Fgates` | 列出所有 pending gates；可直接处理 non-blocking meaning gate |\n| `\u002Fhelp` | 返回可用命令 |\n\n### 本地配置\n\n复制并编辑本地 env。不要提交真实 token：\n\n```bash\ncp alaya-app\u002F.env.example alaya-app\u002F.env\n```\n\n最小配置：\n\n```bash\nALAYA_CAP_EXTERNAL_NOTIFICATION=true\nALAYA_NOTIFICATION_PROVIDER=telegram\nALAYA_TELEGRAM_BOT_TOKEN=\u003CBotFather token>\nALAYA_TELEGRAM_CHAT_ID=\u003Cyour chat id>\nALAYA_BASE_URL=http:\u002F\u002Flocalhost:5000\nALAYA_ALLOWED_NETWORK_HOSTS=api.github.com,api.openai.com,api.minimax.io,api.minimaxi.com,api.telegram.org\n```\n\n如果 5000 端口被占用：\n\n```bash\nPORT=5001\nALAYA_BASE_URL=http:\u002F\u002Flocalhost:5001\n```\n\n启动：\n\n```bash\nnpm --prefix alaya-app run dev\n```\n\n打开 Web UI：\n\n```text\nhttp:\u002F\u002Flocalhost:5001\u002F#\u002Fhuman-gates\n```\n\n### 获取 Telegram Chat ID\n\n1. 在 Telegram 里找 `@BotFather` 创建 bot，拿到 token。\n2. 给 bot 发任意消息。\n3. 请求 `https:\u002F\u002Fapi.telegram.org\u002Fbot\u003CTOKEN>\u002FgetUpdates`。\n4. 在返回 JSON 中找到 `message.chat.id`，填入 `ALAYA_TELEGRAM_CHAT_ID`。\n\nBot 可选命令菜单：\n\n```text\nstatus - 查看飞轮当前状态\ngates - 列出所有待处理闸门\nhelp - 查看使用帮助\n```\n\n### 安全与审计\n\n- 所有出站 Telegram 请求必须同时通过 `ALAYA_CAP_EXTERNAL_NOTIFICATION` 和 `ALAYA_ALLOWED_NETWORK_HOSTS`。\n- 网络 host 固定校验为 `api.telegram.org`；token 格式会在 adapter 构造时验证。\n- 使用原生 `fetch` 调 Telegram Bot API，不引入 `node-telegram-bot-api`，避免其历史依赖链中的 critical audit 漏洞。\n- Telegram callback 不直接写 `storage.updateGate`；批准\u002F否决统一走 `HumanGateService`，保留 capability gate、运行模式、事件日志和 action ledger。\n- Long polling 的 update offset 持久化到 `telegram-update-offset.json`，该文件已加入 `alaya-app\u002F.gitignore`。\n- 所有 Telegram MarkdownV2 文本都会转义动态内容；通知失败只记录错误，不阻塞 Scheduler 主流程。\n\n## P0\u002FP1 证据化内核\n\n本轮 P0\u002FP1 在本地 SQLite 架构上增加可追踪、可评测、可审计的证据层，不依赖外部 OTel 或 LangSmith 服务。\n\n- `trace_events` 记录 OTel-compatible 的 cycle state、agent run、LLM call、knowledge injection、error classification、principle transition、approval 和 action risk 事件；`event_log` 保留为原有审计流。\n- `action_ledger` 记录高风险动作的 risk level、approval gate、rollback plan、audit summary 和 idempotency key。只有 `approved` direction gate，或与该动作 idempotency key 匹配的 `approved` risk gate，才能放行需要审批的动作；`pending`、`modified`、`rejected` 都不会被视为批准。\n- `RiskLevel` 分为 `read_only`、`draft_only`、`local_write`、`external_write`、`destructive`、`financial`、`compliance_sensitive`。内部 local write 默认可免审批；external\u002Fdestructive\u002Ffinancial\u002Fcompliance-sensitive 必须经过 gate。\n- Model router 默认沿用 `ALAYA_LLM_PROVIDER` \u002F `OPENAI_MODEL`，也支持 `ALAYA_MODEL_ROUTING_JSON` 和 role-specific env override；`llm_calls` 会记录 provider\u002Fmodel\u002Froute reason。\n- `npm run benchmark:smoke` 使用 deterministic mock cases 覆盖 round4、knowledge injection、rollback package、source reliability、principle decay、prompt injection、action risk、model routing 和 trace completeness。\n\n## 常用命令\n\n从仓库根目录运行：\n\n```bash\nnpm run test:all       # core + app + scripts 测试\nnpm run guard          # 治理底线守卫\nnpm run typecheck      # core + app 类型检查\nnpm run build          # Web app 生产构建\nnpm run flywheel            # 4 轮飞轮模拟\nnpm run e2e:long-evolution  # 20 轮自主进化离线验收\nnpm run e2e:github          # GitHub Issue Sensor 完整链路，建议指向 sandbox repo\nnpm run e2e:github-autonomous # 自主调度 + GitHub Sensor 完整链路\nnpm run benchmark:smoke      # P0\u002FP1 deterministic benchmark\nnpm run provider:canary -- --projectId \u003CprojectId> --provider mock  # provider\u002Fmodel\u002Frole canary\nnpm run trace:export -- --cycle \u003CcycleId>  # 导出 cycle trace JSONL\nnpm run audit:upgrade       # 升级 readiness 审计\nnpm run validation:summary  # 汇总 validation-logs 下最新 SUMMARY.csv\nnpm run secret:scan         # 高置信 secret 扫描\nnpm run ops:pre-upgrade     # 升级前状态检查\nnpm run ops:backup          # SQLite state 备份\nnpm run ops:migrate         # 显式 schema migration\nnpm run ops:restore -- --backup tmp\u002Falaya-backups\u002F\u003Cbackup>  # 默认 dry-run 恢复\nnpm run ops:post-upgrade    # 升级后 guard\u002Fcore\u002Fprobe 验证\nnpm run shadow:report -- --out tmp\u002Fshadow-report.md\n```\n\nTypeScript 运行入口统一使用 `node --import tsx`。这避免在受限环境里直接调用 `tsx` CLI 时创建 IPC pipe 失败，同时保留同样的 TS\u002FESM 加载能力。核心入口包括 app dev\u002Fbuild、core flywheel、真实 LLM E2E 和长程自主进化 E2E。\n\n## 运行模式与安全模型\n\nAlaya 现在有明确的运行模式。模式由 `ALAYA_MODE` 控制；如果未设置，`NODE_ENV=test` 映射到 `test`，`NODE_ENV=production` 映射到 `production`，其他情况默认为 `development`。\n\n| 模式 | 典型用途 | 默认安全策略 |\n| --- | --- | --- |\n| `development` | 本地开发、快速调试 | 允许本地写和 mock LLM；外部真实写仍需显式路径 |\n| `test` | 单元测试、集成测试 | 不需要真实外部 secret；测试 fixture 可以使用安全假值 |\n| `shadow` | 影子运行、只观察不真实写 | 非只读 API 默认 dry-run；写入意图进入 `action_ledger` |\n| `staging` | 受控预发 | 高风险能力默认 deny，需要显式 capability flag |\n| `production` | 生产长期运行 | env fail-fast；demo seed 禁用；高风险能力最小权限 |\n\n### API 鉴权与内置 UI\n\n`\u002Fapi\u002F*` 在 `shadow`、`staging`、`production` 中默认需要 API key。服务端接受两种等价形式：\n\n```bash\nAuthorization: Bearer $ALAYA_API_KEY\nX-Alaya-API-Key: $ALAYA_API_KEY\n```\n\n`development` 和 `test` 只有在设置了 `ALAYA_API_KEY` 或 `ALAYA_REQUIRE_API_AUTH=true` 时才强制鉴权。`\u002Fhealthz` 与 `\u002Freadyz` 不需要 API key；`\u002Fmetrics` 使用 loopback\u002FCIDR allowlist 单独保护。\n\n内置 React UI 不会把 API key 打进 bundle，也不会从服务端公开读取 key。生产或 shadow 静态 UI 打开后，在左侧 Project 区域的 `API Key` 输入框填入 key 并保存；前端会把 key 保存在当前浏览器 tab 的 `sessionStorage`，并自动为 React Query、`apiRequest()` 和手写 API fetch 加上 `Authorization: Bearer ...`。关闭 tab 后需要重新输入。点击“清除”会移除本 tab 的 key 并刷新查询。\n\n命令行检查：\n\n```bash\ncurl -fsS http:\u002F\u002F127.0.0.1:5000\u002Fhealthz\ncurl -fsS -H \"Authorization: Bearer $ALAYA_API_KEY\" http:\u002F\u002F127.0.0.1:5000\u002Fapi\u002Fprojects\n```\n\n`shadow`、`staging`、`production` 缺少 `ALAYA_API_KEY` 会在 env validation 阶段 fail fast。这样不会出现 `\u002Freadyz` 看起来正常、但所有 `\u002Fapi\u002F*` 请求返回 `503 api authentication is not configured` 的半可用状态。\n\nCapability gate 覆盖高风险动作。所有 flag 都通过环境变量开启，默认不要在长期运行里打开。\n\n| Capability | Env | 默认 long-run 行为 | 当前接入点 |\n| --- | --- | --- | --- |\n| filesystem write | `ALAYA_CAP_FILESYSTEM_WRITE` | deny | 预留给本地写 adapter；shadow API 兜底 dry-run |\n| shell execution | `ALAYA_CAP_SHELL_EXECUTION` | deny | 当前业务未接 shell adapter；若新增必须先 gate |\n| GitHub write | `ALAYA_CAP_GITHUB_WRITE` | deny | 当前 GitHub 路径只读 issue sensor；写 adapter 必须先 gate |\n| database migration | `ALAYA_CAP_DATABASE_MIGRATION` | deny | 只用于显式 `ops:migrate` \u002F `dist\u002Fmigrate.cjs` |\n| unknown network | `ALAYA_CAP_NETWORK_UNKNOWN` | deny | LLM\u002FOpenAI-compatible fetch 与 GitHub fetch 之前检查 |\n| LLM call | `ALAYA_CAP_LLM_CALL` | deny in production unless enabled | `callLlm()` 的真实 provider 路径 |\n| knowledge write | `ALAYA_CAP_KNOWLEDGE_WRITE` | shadow dry-run, staging\u002Fprod deny | 非只读 API、知识\u002F项目\u002Fcycle\u002F反馈写路径 |\n| scheduler loop | `ALAYA_CAP_SCHEDULER_LOOP` | deny | `startCycleScheduler()` 启动前检查 |\n| external notification | `ALAYA_CAP_EXTERNAL_NOTIFICATION` | deny | Telegram `sendMessage`、`editMessageText`、`answerCallbackQuery`、`getUpdates` 等出站通知路径 |\n\nShadow 模式下，`POST \u002Fapi\u002Fknowledge` 这类 mutating API 会返回：\n\n```json\n{\n  \"status\": \"dry_run\",\n  \"mode\": \"shadow\",\n  \"capability\": \"knowledge_write\",\n  \"target\": \"POST \u002Fknowledge\"\n}\n```\n\n同时 `action_ledger` 会写入 `capability.knowledge_write`，`status=dry_run`，包含 actor、mode、capability、target、input hash、结果和时间戳。handler 不会执行真实写入。\n\n生产模式下，相同的默认行为是 `403`，除非显式设置对应 capability。这个设计避免“只在测试里测 gate，但真实路由没接入”的假通过。\n\n高成本端点限速：\n\n```text\nALAYA_COST_RATE_LIMIT_WINDOW_MS=60000\nALAYA_COST_RATE_LIMIT_MAX=10\n```\n\n如果这两个变量被误写成非数字，运行时会回退到默认值而不是关闭 limiter。`POST \u002Fapi\u002Fcycles\u002F:id\u002Frun-full` 和 `POST \u002Fapi\u002Fscheduler\u002Ftick` 都走这个保护；`\u002Fhealthz`、`\u002Freadyz`、`\u002Fmetrics` 不受高成本限速影响。\n\n## 数据库迁移、备份与恢复\n\n开发和测试模式可以在启动时自动创建\u002F补齐 SQLite schema。`shadow`、`staging`、`production` 的稳态启动不会静默执行 DDL；如果 schema 缺表或缺关键列，启动会 fail fast，提示运行显式迁移。\n\n本地迁移流程：\n\n```bash\nnpm run ops:pre-upgrade\nnpm run ops:backup\nALAYA_CAP_DATABASE_MIGRATION=true npm run ops:migrate\nnpm run ops:post-upgrade\n```\n\n`ops:migrate` 会运行 `alaya-app\u002Fserver\u002Fmigrate.ts`。生产构建后对应入口是 `dist\u002Fmigrate.cjs`，Docker shadow 初始化使用这个入口。\n\n备份：\n\n```bash\nnpm run ops:backup\n```\n\n默认输出到：\n\n```text\ntmp\u002Falaya-backups\u002Fbackup-\u003Ctimestamp>\u002F\n```\n\n备份内容包括 SQLite DB 和 WAL\u002FSHM sidecar。脚本会写 `manifest.json`，只记录出现过的 env 变量名，不记录 env 值；`.env` 和 secret 文件不会被备份。\n\n恢复默认是 dry-run：\n\n```bash\nnpm run ops:restore -- --backup tmp\u002Falaya-backups\u002F\u003Cbackup-dir>\n```\n\n确认恢复前必须停止服务，然后显式加 `--confirm`：\n\n```bash\nnpm run ops:restore -- --backup tmp\u002Falaya-backups\u002F\u003Cbackup-dir> --confirm\n```\n\nSQLite 备份一致性在服务停止或 WAL checkpoint 后最强。生产\u002F长期 shadow 运行前应先停服务或确认没有活跃写入，再做关键备份。\n\n## Docker Shadow 部署与 smoke 验证\n\n本节是短 smoke，不是 7 天 shadow run。7 天 shadow run 文档在 [docs\u002Fops\u002F05-shadow-run-7d.md](.\u002Fdocs\u002Fops\u002F05-shadow-run-7d.md)，本次不自动执行。\n\n构建镜像：\n\n```bash\ndocker build -t alaya:local .\ndocker tag alaya:local alaya:shadow\n```\n\n渲染 compose：\n\n```bash\ndocker compose -f deploy\u002Fdocker-compose.shadow.yml config\n```\n\n第一次使用新的 shadow volume，或升级后需要 schema 变更时，先运行一次显式迁移：\n\n```bash\nALAYA_SHADOW_PORT=5055 docker compose -f deploy\u002Fdocker-compose.shadow.yml run --rm \\\n  -e ALAYA_CAP_DATABASE_MIGRATION=true \\\n  alaya node dist\u002Fmigrate.cjs\n```\n\n正常启动保持 `ALAYA_CAP_DATABASE_MIGRATION=false`：\n\n```bash\nALAYA_SHADOW_PORT=5055 docker compose -f deploy\u002Fdocker-compose.shadow.yml up -d --no-build\ncurl -fsS http:\u002F\u002Flocalhost:5055\u002Fhealthz\ncurl -fsS http:\u002F\u002Flocalhost:5055\u002Freadyz\ncurl -fsS http:\u002F\u002Flocalhost:5055\u002Fmetrics\n```\n\n证明 shadow 写操作不会真实执行：\n\n```bash\ncurl -fsS -X POST http:\u002F\u002Flocalhost:5055\u002Fapi\u002Fknowledge \\\n  -H 'Content-Type: application\u002Fjson' \\\n  --data '{\"id\":\"kb_shadow_probe\",\"projectId\":\"proj_shadow\",\"title\":\"probe\",\"content\":\"dry run only\"}'\n\ncurl -fsS 'http:\u002F\u002Flocalhost:5055\u002Fapi\u002Faction-ledger?limit=5'\n```\n\n预期：第一个请求返回 `202 dry_run`；第二个请求能看到 `capability.knowledge_write` 且 `status=dry_run`。\n\n停止：\n\n```bash\nALAYA_SHADOW_PORT=5055 docker compose -f deploy\u002Fdocker-compose.shadow.yml down\n```\n\n容器安全属性：\n\n- Dockerfile 使用 `node:20-bookworm-slim`，没有 `latest`。\n- build\u002Fruntime 分阶段，runtime 运行用户是 `alaya`，不是 root。\n- `.dockerignore` 排除 `.env`、数据库、日志、缓存、tmp、coverage、node_modules 和 `.git`。\n- compose 使用 read-only root filesystem。\n- 可写位置限制在 named volumes：`\u002Fvar\u002Flib\u002Falaya`、`\u002Fvar\u002Flog\u002Falaya`、`\u002Fvar\u002Fcache\u002Falaya`。\n- shadow compose 不挂载宿主根目录，不使用 privileged。\n\n## 可观测性与审计账本\n\n运行端点：\n\n```text\nGET \u002Fhealthz   # 进程活着，尽量不因依赖失败而 500\nGET \u002Freadyz    # 配置、数据库、关键目录可写性、schema readiness\nGET \u002Fmetrics   # Prometheus text\n```\n\n`\u002Fmetrics` 包含：\n\n```text\nalaya_uptime_seconds\nalaya_mode_info\nalaya_scheduler_cycles_total\nalaya_scheduler_cycle_duration_ms\nalaya_actions_total\nalaya_actions_denied_total\nalaya_capability_denials_total\nalaya_llm_requests_total\nalaya_llm_tokens_input_total\nalaya_llm_tokens_output_total\nalaya_llm_estimated_cost_usd_total\nalaya_external_feedback_items_total\nalaya_knowledge_injections_total\nalaya_stall_events_total\nalaya_errors_total\nalaya_last_successful_cycle_timestamp\nalaya_llm_agent_latency_p50_ms{agent=...}\nalaya_llm_agent_latency_p95_ms{agent=...}\nalaya_llm_agent_error_rate{agent=...}\n```\n\nLLM 调用现在同时保存：\n\n- `input_token_count`\n- `output_token_count`\n- `token_count`\n- `estimated_cost`\n- `llm_failure_type`：`timeout`、`rate_limit`、`auth`、`schema_error`、`invalid_json`、`safety_refusal`、`network`、`provider_error`、`unknown`\n\n前端 Ledger、`\u002Fapi\u002Fllm-calls\u002Fsummary`、`\u002Fapi\u002Fllm-calls\u002Flatency` 和 `\u002Fmetrics?format=json` 都能用于核对 input\u002Foutput split、失败类型和分 Agent latency。聚合值可以从 `llm_calls` 与 `trace_events` 原始记录交叉核对。\n\n审计持久化：\n\n- `event_log`：storage 写路径的 before\u002Fafter diagnostics，写入前脱敏。\n- `trace_events`：cycle、agent、LLM、知识注入、风险动作等 OTel-compatible trace，attributes 写入前脱敏。\n- `action_ledger`：高风险动作和 capability decision，包含 status、risk、approval gate、rollback plan、payload 和 idempotency key，payload\u002Faudit\u002Frollback 写入前脱敏。\n\n脱敏覆盖 bearer token、Cookie\u002FSet-Cookie、GitHub\u002FOpenAI\u002FSlack token、AWS key id、数据库 URL 密码、private key block、email、明显 phone number，以及对象中 `apiKey\u002Ftoken\u002Fsecret\u002Fpassword\u002Fdatabase_url` 等 secret-like key。Phone redaction 需要至少 10 位数字并带有 `+` 或多个分隔符，因此普通日期如 `2026-06-06`、分组编号如 `1234-5678` 会保留上下文，不会被误替换为 `[redacted-phone]`。\n\nWeb 开发：\n\n```bash\nnpm run dev\n```\n\nUI 卡顿回归测试需要先启动 Web 服务。默认检测 `http:\u002F\u002F127.0.0.1:5001`。\n\n终端 A：\n\n```bash\nPORT=5001 npm run dev\n```\n\n终端 B：\n\n```bash\nnpm run e2e:ui-freeze\n```\n\n如需指定地址：\n\n```bash\nALAYA_E2E_BASE_URL=http:\u002F\u002F127.0.0.1:5000 npm run e2e:ui-freeze\n```\n\n完整 live 验收会调用真实 LLM 和 GitHub，需要本机 secret：\n\n```bash\nnpm run e2e:live\n```\n\n`alaya-app` 内也提供同名代理入口，供 CI 和脚本在 app 工作目录中调用：\n\n```bash\nnpm --prefix alaya-app run flywheel:live\n```\n\n## 真实 LLM 与 Secret\n\n默认不调用真实模型。启用 OpenAI-compatible provider：\n\n```bash\nALAYA_LLM_PROVIDER=openai \\\nOPENAI_API_KEY=... \\\nOPENAI_BASE_URL=https:\u002F\u002Fapi.openai.com\u002Fv1 \\\nOPENAI_MODEL=gpt-4.1-mini \\\nnpm run dev\n```\n\nMiniMax 等兼容端点可通过 `OPENAI_BASE_URL` 和 `OPENAI_MODEL` 切换。\n\n为了避免把 key 写入 shell history，可以使用本地 key file：\n\n```bash\nnpm run setup:secrets\nnpm run setup:secrets:check\n```\n\n该工具默认只写用户配置目录，也可用 `OPENAI_API_KEY_FILE` \u002F `GITHUB_TOKEN_FILE`\n显式指定其他本地路径：\n\n```text\n$HOME\u002F.config\u002Falaya\u002Fopenai-api-key\n$HOME\u002F.config\u002Falaya\u002Fgithub-token\n```\n\n文件权限为 `0600`，不会打印 secret 值。\n\nGitHub Actions 中请添加 `LLM_API_KEY` 和 `GH_PAT` 两个 Secrets。不要自定义名为\n`GITHUB_TOKEN` 的 Secret；这是 GitHub Actions 的保留令牌名。\n\n真实 LLM preflight：\n\n```bash\nOPENAI_API_KEY_FILE=$HOME\u002F.config\u002Falaya\u002Fopenai-api-key \\\nOPENAI_BASE_URL=https:\u002F\u002Fapi.minimax.io\u002Fopenai \\\nOPENAI_MODEL=MiniMax-M3 \\\nnpm run e2e:llm\n```\n\n`ALAYA_E2E_ALLOW_SKIP=true` 只在没有可用 key 时允许跳过真实调用；如果本机存在 key 但 key 无效，E2E 会 fail closed 并显示 provider 返回的错误。\n\n真实 4 轮飞轮：\n\n```bash\nOPENAI_API_KEY_FILE=$HOME\u002F.config\u002Falaya\u002Fopenai-api-key \\\nOPENAI_BASE_URL=https:\u002F\u002Fapi.minimax.io\u002Fopenai \\\nOPENAI_MODEL=MiniMax-M3 \\\nnpm run e2e:llm-flywheel\n```\n\n## CI 与本地长程验证\n\nGitHub Actions 工作流位于 `.github\u002Fworkflows\u002Fci.yml` 和 `.github\u002Fworkflows\u002Fdeploy-readiness.yml`：\n\n- `unit-and-integration`：安装 root\u002Fapp\u002Fcore 依赖，运行 guard、app focused regression、app full test、app typecheck、core test、core typecheck、script tests 和 core flywheel simulation。\n- `live-llm-validation`：只在 `main` 分支 push 后尝试运行真实 LLM\u002FGitHub live validation；缺少 secret 时明确跳过。\n- `deploy-readiness`：默认不需要真实 secret，运行 secret scan、env\u002Fredaction\u002Fcapability\u002Fhealth focused tests、pre-upgrade check、Docker build、shadow compose config 和 principles guard。\n\nActions secrets：\n\n| Secret | 用途 |\n| --- | --- |\n| `LLM_API_KEY` | OpenAI-compatible provider key，可指向 MiniMax |\n| `GH_PAT` | GitHub live sensor \u002F issue E2E token |\n| `OPENAI_BASE_URL` | 可选，默认 `https:\u002F\u002Fapi.minimax.io\u002Fopenai` |\n| `OPENAI_MODEL` | 可选，默认 `MiniMax-M3` |\n\n24h fail-closed 本地验证脚本：\n\n```bash\n.\u002Fscripts\u002F24h_validation.sh\n```\n\n常用参数：\n\n```bash\nALAYA_VALIDATION_DURATION_SECONDS=86400 \\\nALAYA_VALIDATION_SLEEP_SECONDS=600 \\\nALAYA_HEALTH_URL=http:\u002F\u002F127.0.0.1:5000\u002Fapi\u002Fflywheel\u002Fhealth?projectId=... \\\n.\u002Fscripts\u002F24h_validation.sh\n```\n\n24h 脚本每轮运行 principles guard 和 mock flywheel simulation，每 3 轮尝试 live validation。缺少 secret 时标记 `SKIP`，有 secret 但 API 网络不可达时标记 `SKIP_NET`。如果 guard、simulation 或 live 步骤出现 `FAIL`，最终退出码为非零；连续 3 次 live failure 会提前停止。\n\n12h 长程观测脚本：\n\n```bash\n.\u002Fscripts\u002F12h_validation.sh\n```\n\n常用参数：\n\n```bash\nALAYA_VALIDATION_DURATION_SECONDS=43200 \\\nALAYA_VALIDATION_SLEEP_SECONDS=600 \\\nALAYA_VALIDATION_MAX_ROUNDS=72 \\\n.\u002Fscripts\u002F12h_validation.sh\n```\n\n12h 脚本用于长时间稳定性观察：principles guard 失败仍然立即停止；simulation、live、live connectivity `SKIP_NET` 和 flywheel health 属于非关键检查，同一检查项连续 3 次失败会写入 `alerts.log`，但不会中断 runner。连续计数按检查项独立维护，避免 health failure 被 unrelated live\u002Fsim success 清零。\n\n12h\u002F24h 验证脚本会先检查 `ALAYA_READY_URL`，默认 `http:\u002F\u002Flocalhost:5000\u002Freadyz`。如果没有现成服务且 `ALAYA_VALIDATION_START_APP=true`，脚本会启动 `npm run dev`，等待 `\u002Freadyz` 就绪后再进入 runner，确保 `\u002Fapi\u002Fflywheel\u002Fhealth` 可读，`compoundingProof.round1vs4KnowledgeDelta` 不再因为健康 API 未启动而只能显示 `NA`。\n\nGitHub Issue Sensor E2E 默认优先使用 sandbox 环境变量，避免污染真实项目：\n\n```bash\nALAYA_E2E_GITHUB_SANDBOX_OWNER=\u003Cowner> \\\nALAYA_E2E_GITHUB_SANDBOX_REPO=\u003Crepo> \\\nGH_PAT=\u003Ctoken> \\\nnpm run e2e:github\n```\n\n完整链路覆盖：\n\n```text\nGitHub Issue 入库 -> Sensor Agent 提炼 -> Human Meaning Gate 推送 ->\n人工批准 -> active knowledge -> 下轮 Cycle 知识注入\n```\n\n汇总最近一次验证：\n\n```bash\nnpm run validation:summary\n```\n\n或指定路径：\n\n```bash\nnpm run validation:summary -- validation-logs\u002F\u003Crun>\u002FSUMMARY.csv\n```\n\n## 本地数据\n\n默认配置：\n\n```text\nPORT=5000\nHOST=0.0.0.0\nREUSE_PORT=false\nALAYA_BASE_URL=http:\u002F\u002Flocalhost:5000\nALAYA_CAP_EXTERNAL_NOTIFICATION=false\nALAYA_NOTIFICATION_PROVIDER=telegram\nALAYA_TELEGRAM_BOT_TOKEN=\nALAYA_TELEGRAM_CHAT_ID=\n```\n\n可复制 `alaya-app\u002F.env.example` 后按需修改。\n\n运行后生成：\n\n```text\nalaya-app\u002Fdata.db\nalaya-app\u002Fdata.db-shm\nalaya-app\u002Fdata.db-wal\n```\n\n这些文件不会提交到仓库。需要重置演示数据时，停止服务后删除 `alaya-app\u002Fdata.db*`，再重新启动。\n\n## API 概览\n\n核心 API：\n\n```text\nGET  \u002Fapi\u002Fprojects\nPOST \u002Fapi\u002Fprojects\nPATCH \u002Fapi\u002Fprojects\u002F:id\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fdashboard\nGET  \u002Fapi\u002Fflywheel\u002Fhealth?projectId=...\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fcycles\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fpredictions\nPOST \u002Fapi\u002Fpredictions\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fscheduler\u002Ftick\nPOST \u002Fapi\u002Fscheduler\u002Ftick\n\nGET  \u002Fapi\u002Fhuman-gates\nPOST \u002Fapi\u002Fhuman-gates\u002F:id\u002Fapprove\nPOST \u002Fapi\u002Fhuman-gates\u002F:id\u002Fmodify\nPOST \u002Fapi\u002Fhuman-gates\u002F:id\u002Freject\n\nGET  \u002Fapi\u002Fknowledge?projectId=...\nGET  \u002Fapi\u002Fknowledge\u002F:id\nPOST \u002Fapi\u002Fknowledge\u002Fsearch\nPOST \u002Fapi\u002Fknowledge\u002F:id\u002Fapprove\nPOST \u002Fapi\u002Fknowledge\u002F:id\u002Fquarantine\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fknowledge-reviews\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fknowledge\u002Fconflicts\u002Fscan\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fknowledge\u002Freview-reminders\nPOST \u002Fapi\u002Fknowledge-reviews\u002F:id\u002Fresolve\n\nGET  \u002Fapi\u002Fcycles\u002F:id\u002Freview\nGET  \u002Fapi\u002Fcycles\u002F:id\u002Ftraces\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Ftraces?limit=...\nPOST \u002Fapi\u002Fcycles\u002F:id\u002Frun-full\nGET  \u002Fapi\u002Fllm-calls\u002Fsummary?projectId=...\nGET  \u002Fapi\u002Fllm-calls\u002Flatency\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fops-metrics\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fprovider-canary\n\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Forg-modules\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Forg-modules\nGET  \u002Fapi\u002Forg-modules\u002F:id\nPATCH \u002Fapi\u002Forg-modules\u002F:id\nDELETE \u002Fapi\u002Forg-modules\u002F:id\nGET  \u002Fapi\u002Forg-modules\u002F:id\u002Fmarkdown\nPOST \u002Fapi\u002Forg-modules\u002F:id\u002Fknowledge\n```\n\n外部反馈与集成：\n\n```text\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fintegrations\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fintegrations\u002Fgithub\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fintegrations\u002Fgithub\u002Fissues\u002Fsync\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Ffeedback\u002Fform\nGET  \u002Fapi\u002Fprojects\u002F:id\u002Fbusiness-signals\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fbusiness-signals\u002Fimport\nPOST \u002Fapi\u002Fprojects\u002F:id\u002Fbuilder\u002Fcodex\u002Fplan\nPOST \u002Fapi\u002Fbuilder\u002Fcodex\u002Fapply\n```\n\n实现入口：\n\n- `alaya-app\u002Fserver\u002Froutes.ts`\n- `alaya-app\u002Fserver\u002Fstorage.ts`\n- `alaya-app\u002Fserver\u002Fflywheel.ts`\n- `alaya-app\u002Fserver\u002Fscheduler.ts`\n- `alaya-app\u002Fserver\u002FexternalFeedback.ts`\n- `alaya-app\u002Fserver\u002FbusinessSignals.ts`\n- `alaya-app\u002Fserver\u002FknowledgeReview.ts`\n- `alaya-app\u002Fserver\u002FbuilderAdapter.ts`\n- `alaya-app\u002Fserver\u002FproviderCanary.ts`\n- `alaya-app\u002Fserver\u002FopsMetrics.ts`\n- `alaya-app\u002Fserver\u002ForgModules.ts`\n- `alaya-app\u002Fserver\u002Fnotifications\u002F`\n- `alaya-app\u002Fserver\u002FhumanGateService.ts`\n\n契约要点：\n\n- `POST \u002Fapi\u002Fprojects` 使用 onboarding schema，必须提供 `firstClaimMetric`、`firstClaimOperator` 和 `firstClaimTarget`；`firstClaimOperator` 只允许 `>=` \u002F `\u003C=`。\n- `PATCH \u002Fapi\u002Fprojects\u002F:id` 的 `redlines` 字段是字符串数组；服务端负责持久化为 JSON 字符串。\n- `POST \u002Fapi\u002Fpredictions` 的 `claims` 字段走统一 `claimSchema`，会拒绝缺失 operator、`operator ==`、`scale=0` 和 metric weight 小于 3 的关键指标 claim。\n- `GET \u002Fapi\u002Fcycles\u002F:id\u002Freview` 返回 `actionLedger`，前端 Cycle Review 用它展示本轮高风险动作时间线。\n- Business Signal import 会强制使用 URL project id 覆盖 body 内的 `projectId`，敏感信号写入审计前脱敏，并只创建 feedback + Meaning Gate。\n- Builder Codex apply 默认 dry-run；`dryRun:false` 在 long-run mode 下归类为 `shell_execution`，默认拒绝，且即使审批通过也只记录 manual apply path。\n- Provider canary 在 long-run mode 下归类为 `llm_call`，真实 provider 需要显式 capability 与 secret；mock canary 可用于本地和 CI。\n\n## 验证记录\n\n### 2026-06-07 roadmap gap closure\n\n本次闭合路线图剩余 A-F 能力：知识冲突\u002F复核、Builder Codex dry-run adapter、provider canary 与 LLM failure taxonomy、运营 KPI、业务信号导入和组织模块模板。完整证据见 [docs\u002Fvalidation\u002F2026-06-07-roadmap-gap-closure.md](.\u002Fdocs\u002Fvalidation\u002F2026-06-07-roadmap-gap-closure.md)。\n\n已通过：\n\n```bash\nnpm run guard\nnpm run typecheck\nnpm run test:all\nnpm run build\nnpm run benchmark:smoke\nnpm run flywheel\nnpm run e2e:long-evolution\nnpm run secret:scan\n```\n\n结果摘要：\n\n| 项目 | 结果 |\n| --- | --- |\n| Focused roadmap tests | 42\u002F42 PASS |\n| Core tests | 52\u002F52 PASS |\n| App tests | 156\u002F156 PASS |\n| Script tests | 18\u002F18 PASS |\n| Benchmark smoke | 12\u002F12 PASS |\n| Long evolution E2E | 20 cycles PASS |\n| Secret scan | PASS |\n\n### 2026-06-07 P0\u002FP1\u002FP2 hardening validation\n\n本次本地验证覆盖数学命门修复、GitHub Sensor 入库链路、四类自主停机风险闸、灰区弱累加三条主路径、Onboarding Claim operator 和 Cycle Review action ledger 可视化。\n\n已通过：\n\n```bash\nnpm run test:all\nnpm run typecheck\nnpm run build\nnpm run guard\n```\n\n结果摘要：\n\n| 项目 | 结果 |\n| --- | --- |\n| Core tests | 52\u002F52 PASS |\n| App tests | 125\u002F125 PASS |\n| Script tests | 18\u002F18 PASS |\n| Typecheck | PASS |\n| Production build | PASS |\n| Principles guard | 17\u002F17 PASS |\n\n构建仍会输出一个既有 PostCSS `from` option warning，退出码为 0，不影响本次构建产物。\n\n### 2026-06-05\u002F06 12h real LLM validation\n\n本地完成一次完整 12 小时长程验证，真实 LLM 路径接入 MiniMax OpenAI-compatible endpoint，GitHub API 连通性预检通过。\n\n```bash\nALAYA_VALIDATION_DURATION_SECONDS=43200 \\\nALAYA_VALIDATION_SLEEP_SECONDS=600 \\\nALAYA_VALIDATION_MAX_ROUNDS=72 \\\nbash scripts\u002F12h_validation.sh\n```\n\n结果摘要：\n\n| 项目 | 结果 |\n| --- | --- |\n| 时间窗口 | 2026-06-05 17:53:53 - 2026-06-06 05:57:32 CST |\n| 总时长 | 12h 03m 39s |\n| 总轮次 | 69，12 小时时长门限先于 72 轮上限触发 |\n| Principles guard | 69\u002F69 PASS |\n| Mock flywheel simulation | 69\u002F69 PASS |\n| Real LLM flywheel live | 23\u002F23 PASS, rounds 3\u002F6\u002F...\u002F69 |\n| Planned live skips | 46 |\n| Real LLM calls | 460 |\n| Tokens | 280,935 |\n| Estimated cost | 0.057997 USD |\n| Alerts | 0 |\n| Residual runner\u002Fprocess | 0 |\n| Summary | `validation-logs\u002F12h_20260605_175353\u002FSUMMARY.csv` |\n| Detailed report | `docs\u002Fvalidation\u002F2026-06-06-12h-real-llm-validation.md` |\n\n23 个 live 轮次均返回 `ok: true`，每次包含 `llmCalls.count=20`、`eventLogCount=56`、`decisionLogCount=4`。日志扫描未发现 `fetch failed`、`ETIMEDOUT`、`ECONNRESET`、`ENETUNREACH` 或 TCP 443 timeout 类失败。\n\n认知迭代结论：在 `e2e:llm-flywheel` 验收范围内，4-cycle 多 Agent 飞轮可持续运行；后续 cycle 会引用前序知识改变决策，不重复 rejected direction，预测误差会回流到 distiller\u002Fworld-model 更新，cycle 4 形成 rollback\u002Faudit 导向的新原则。这支持“核心设计符合预期、认知可持续迭代、知识库呈现熵减配平特征”的阶段性结论。\n\n边界说明：本次验证不等同于完整 `npm run e2e:live` \u002F GitHub issue sensor 业务链路通过。Health endpoint 未运行，23 次 health probe 均为空响应，`delta=NA`；本次熵减结论来自 live E2E 行为断言，而不是 health API 的 `compoundingProof.round1vs4KnowledgeDelta` 量化指标。\n\nPost-run 修复：审计发现旧版 12h runner 的非关键失败计数是全局计数，health 连续失败会被 unrelated sim\u002Flive success 清零，导致三连 health alert 不触发。当前版本已改为按检查项独立计数，并用 9 轮 forced-failure smoke 验证：`live connectivity` 与 `flywheel health` 都在第 9 轮写入 alert，脚本仍正常完成。\n\n### 2026-06-05 3h real LLM validation\n\n本地使用 12h validation runner 压缩为 3 小时窗口完成一次真实 LLM 验证循环：\n\n```bash\nALAYA_VALIDATION_DURATION_SECONDS=10800 \\\nALAYA_VALIDATION_SLEEP_SECONDS=600 \\\nALAYA_VALIDATION_MAX_ROUNDS=18 \\\nbash scripts\u002F12h_validation.sh\n```\n\n结果摘要：\n\n| 项目 | 结果 |\n| --- | --- |\n| 时间窗口 | 2026-06-05 07:45:06 - 10:45:29 CST |\n| 总轮次 | 18 |\n| Principles guard | 18\u002F18 PASS |\n| Mock flywheel simulation | 18\u002F18 PASS |\n| Real LLM flywheel live | 6\u002F6 PASS, rounds 3\u002F6\u002F9\u002F12\u002F15\u002F18 |\n| Non-critical errors | 0 |\n| Alerts | 0 |\n| Summary | `validation-logs\u002F12h_20260605_074506\u002FSUMMARY.csv` |\n\n6 个 live 轮次均返回 `ok: true`，每次包含 `llmCalls.count=20`，合计约 73,327 tokens，未出现 `fetch failed`、`ETIMEDOUT` 或 TCP 443 超时类错误。本机连通性检查中 MiniMax endpoint 可达，GitHub API 返回 HTTP 200。\n\n边界说明：本次验证覆盖的是 `npm run e2e:llm-flywheel` 的真实 LLM 路径，并证明当前机器能访问真实模型端点；它不等同于完整 `npm run e2e:live` \u002F GitHub issue sensor 端到端业务链路通过。GitHub 业务链路仍需单独跑完整 live E2E 验收。\n\n最近本地验证覆盖：\n\n- `npm run test:all`\n- `npm run guard`\n- `npm run typecheck`\n- `npm run build`\n- `npm run benchmark:smoke`\n- `npm run flywheel`\n- `npm run e2e:long-evolution`\n- `npm run secret:scan`\n- `npm run ops:migrate`\n- Docker shadow migration + health\u002Fready\u002Fmetrics smoke\n- `npm run e2e:ui-freeze`\n- `cd alaya-app && node --import tsx --test tests\u002Fschema_migration.test.ts tests\u002Fupdate_confidence.decay.test.ts`\n- `node --test scripts\u002Ftests\u002Flive-readiness.test.mjs`\n\n知识库详情页稳定性修复已经过压力验证：在大量 Agent 引用记录下，`\u002Fapi\u002Fknowledge\u002F:id` 只返回有限引用，前端只渲染有限列表，并通过浏览器 smoke test 检查页面切换、知识搜索、详情点击和主线程长任务。\n\n本次治理增强额外覆盖：\n\n- 旧库已有 `knowledge_items` 在 FTS5 迁移后可被知识注入检索。\n- Scheduler tick 会自动执行 stale knowledge 时间衰减，并通过 `lastDecayedAt` 避免重复衰减同一时间区间。\n- `\u002Fhealth` 页面按当前项目查询 flywheel health 和 pending gates。\n- 24h 验证脚本在任何 FAIL 后以非零退出码结束。\n- Telegram P0\u002FP1 覆盖单向通知、双向卡片、MarkdownV2 转义、callback 审批审计、gateId 去重、long-polling offset、`\u002Fstatus`\u002F`\u002Fgates` 命令和真实 Bot API 发送 smoke。\n\n已知构建提示：\n\n- 当前构建可能出现一个 PostCSS `from` 选项提示，不影响本地构建结果。\n\n## 路线图\n\n| 项目 | 状态 | 入口 |\n| --- | --- | --- |\n| 知识冲突检测、过期提醒和复核任务 | 已完成 | `POST \u002Fapi\u002Fprojects\u002F:id\u002Fknowledge\u002Fconflicts\u002Fscan`、`POST \u002Fapi\u002Fprojects\u002F:id\u002Fknowledge\u002Freview-reminders`、`POST \u002Fapi\u002Fknowledge-reviews\u002F:id\u002Fresolve` |\n| Builder Codex\u002FCodex CLI 变更包 adapter | 已完成 dry-run MVP | `POST \u002Fapi\u002Fprojects\u002F:id\u002Fbuilder\u002Fcodex\u002Fplan`、`POST \u002Fapi\u002Fbuilder\u002Fcodex\u002Fapply`；非 dry-run apply 需要 shell capability + 匹配 idempotency risk gate |\n| Provider canary、分 Agent latency 和 LLM 失败恢复分类 | 已完成 | `POST \u002Fapi\u002Fprojects\u002F:id\u002Fprovider-canary`、`npm run provider:canary`、`GET \u002Fapi\u002Fllm-calls\u002Flatency`、`\u002Fmetrics?format=json` |\n| 真实使用运营指标 | 已完成 API MVP | `GET \u002Fapi\u002Fprojects\u002F:id\u002Fops-metrics`，覆盖 gate resolution、LLM cost、measurable claim ratio、knowledge reuse、blocking backlog、compounding gain proxy |\n| 通用业务信号 Sensor adapter | 已完成 CSV\u002FJSON 本地导入 MVP | `POST \u002Fapi\u002Fprojects\u002F:id\u002Fbusiness-signals\u002Fimport`，详见 [docs\u002Fbusiness-signals.md](.\u002Fdocs\u002Fbusiness-signals.md) |\n| 组织模块知识模板 | 已完成 API MVP | `GET\u002FPOST \u002Fapi\u002Fprojects\u002F:id\u002Forg-modules`、Markdown export、draft knowledge conversion，详见 [docs\u002Forg-modules.md](.\u002Fdocs\u002Forg-modules.md) |\n\n## 文档索引\n\n| 文件 | 内容 |\n| --- | --- |\n| [PRINCIPLES.md](.\u002FPRINCIPLES.md) | 项目底线和治理约束 |\n| [Alaya_PRD.md](.\u002FAlaya_PRD.md) | 原始产品需求文档 |\n| [Alaya_实现方案与架构评审.md](.\u002FAlaya_实现方案与架构评审.md) | 实现方案、架构评审和 PRD 漏洞分析 |\n| [alaya-core\u002FREADME.md](.\u002Falaya-core\u002FREADME.md) | Core 内核说明 |\n| [alaya-app\u002FBUILD_SPEC.md](.\u002Falaya-app\u002FBUILD_SPEC.md) | Web MVP 构建规格 |\n| [alaya-app\u002FBUILD_REPORT.md](.\u002Falaya-app\u002FBUILD_REPORT.md) | 构建与验证报告 |\n| [docs\u002Fbusiness-signals.md](.\u002Fdocs\u002Fbusiness-signals.md) | 通用业务信号 adapter、CSV\u002FJSON 导入、脱敏和 Meaning Gate 流程 |\n| [docs\u002Forg-modules.md](.\u002Fdocs\u002Forg-modules.md) | 组织模块五问模板、Markdown export 和知识转换规则 |\n| [docs\u002Fops\u002F00-baseline-audit.md](.\u002Fdocs\u002Fops\u002F00-baseline-audit.md) | hardening 前仓库基线与入口图 |\n| [docs\u002Fops\u002F01-secrets-and-env.md](.\u002Fdocs\u002Fops\u002F01-secrets-and-env.md) | env、secret、capability 和脱敏说明 |\n| [docs\u002Fops\u002F02-deployment.md](.\u002Fdocs\u002Fops\u002F02-deployment.md) | Docker\u002Fsystemd 部署与升级流程 |\n| [docs\u002Fops\u002F03-state-backup-rollback.md](.\u002Fdocs\u002Fops\u002F03-state-backup-rollback.md) | 状态盘点、备份、恢复和迁移策略 |\n| [docs\u002Fops\u002F04-validation-matrix.md](.\u002Fdocs\u002Fops\u002F04-validation-matrix.md) | development\u002Ftest\u002Fshadow\u002Fstaging\u002Fproduction 验证矩阵 |\n| [docs\u002Fops\u002F05-shadow-run-7d.md](.\u002Fdocs\u002Fops\u002F05-shadow-run-7d.md) | 7 天 shadow run 操作手册。本次提交不执行该长跑 |\n| [docs\u002Fops\u002F98-verification-ledger.md](.\u002Fdocs\u002Fops\u002F98-verification-ledger.md) | 交叉验证证据台账 |\n| [docs\u002Fops\u002F99-long-run-readiness-report.md](.\u002Fdocs\u002Fops\u002F99-long-run-readiness-report.md) | long-run readiness 审计报告 |\n\n## License\n\nMIT\n","2026-06-11 04:11:05","CREATED_QUERY"]