121 lines
10 KiB
Markdown
121 lines
10 KiB
Markdown
# RUNTIME GUARDRAILS
|
||
|
||
## 1. 目的
|
||
- 本文档承接 PMFlow 的长运行边界、跨链路守门规则与已知运行假设。
|
||
- `AGENTS.md` 保留必须立即遵守的摘要规则;本文件提供更细的运行时约束与环境边界。
|
||
- `CLAUDE.md` 只保留当前架构摘要、关键入口和高价值提醒;长清单统一收口到这里。
|
||
|
||
## 2. 同步规则
|
||
- 任何影响运行边界、守门策略、失败语义、已知环境假设的改动,都必须同步更新:
|
||
- `AGENTS.md`
|
||
- `docs/architecture/RUNTIME_GUARDRAILS.md`
|
||
- 任何影响目录结构、模块归属与关键入口的改动,还必须同步更新:
|
||
- `CLAUDE.md`
|
||
- `docs/architecture/ARCHITECTURE_INVENTORY.md`
|
||
- 任何影响主链路由、函数名、运行时流向的改动,还必须同步更新:
|
||
- `docs/architecture/DATAFLOW.md`
|
||
- `backend/.openclaw/pmflow-routing-rules.json`
|
||
|
||
## 3. 核心运行边界
|
||
|
||
### 3.1 平台与写路径
|
||
- 数据库写操作必须通过 Alembic migration,禁止直接 `ALTER TABLE`。
|
||
- 运行期禁止 DDL;仅迁移路径允许执行 `CREATE/ALTER/DROP/...`。
|
||
- 运行环境数据库仅允许 PostgreSQL(`postgresql+asyncpg`),禁止回落 SQLite。
|
||
- 新增接口必须遵循响应包络:`{code, message, data}`。
|
||
- 禁止在 API 层写业务逻辑;业务逻辑归属 `services/`。
|
||
- 禁止在前端组件内直接调用 `fetch`,必须通过 `frontend/src/api/` 封装层。
|
||
- 飞书回复必须经过 `feishu_reply_outbox`,禁止同步直接发送。
|
||
- 飞书回执发送仅允许 `main.py` 的 drain loop 作为消费者,禁止在业务路径即时派发发送任务。
|
||
- 所有写接口必须落审计日志(`operation_logs`),至少包含 `trace_id/interface_path/caller`。
|
||
- `created_at_beijing` 为计算属性返回,禁止新增数据库物理列。
|
||
|
||
### 3.2 核心业务零兜底
|
||
- 模型失败、超时、空响应、结构化解析失败时,必须显式返回真实失败原因。
|
||
- 禁止使用固定兜底文案、模板句子、占位字段或 stub 数据冒充成功结果。
|
||
- 核心业务完成态不得仅按字段非空判定;必须能区分“真实生成 / 人工填写 / 模板占位 / 生成失败”。
|
||
- 技术层 fallback 仅允许用于重试、缓存、解析修复、传输兼容等基础设施环节,禁止上浮为用户可见业务结论。
|
||
- AI Steward 与其它生成链的成功/失败判定必须优先使用结构校验、字段完整性和证据一致性。
|
||
|
||
### 3.3 业务动作归因主链
|
||
- 运行时业务动作归因必须优先走:
|
||
- 对象/上下文绑定
|
||
- `SemanticContextPacket`
|
||
- `SemanticDecision`
|
||
- gatekeeper
|
||
- `backend/app` 运行时代码不得再沉淀会直接拍板 `project.create / signal_source.onboard / followup.* / query vs execute` 的中文关键词、正则、`looks_like_*`、`*_HINTS/*_KEYWORDS` 规则仓。
|
||
- 协议级锚点(`reply_to_message_id/button/work_item_id`)、租户权限、幂等等确定性规则可以保留,但展示反馈、草稿确认/修改/取消、followup 动作归类、`query vs execute` 不能再由关键词最终拍板。
|
||
- 若问题根因属于“动作路由错误 / 上下文劫持 / 独立业务流误触发”,主修法必须优先落在 ingress 分流、active topic/draft 检测、`SemanticContextPacket` 组包、`SemanticDecision` 结构化判断与 gatekeeper 放行条件。
|
||
- `workflow_semantic_planner` 当前职责是 packet / bundle 组装、兼容层收口与冷启动接入,不再作为新的关键词仓。
|
||
|
||
### 3.4 LLM 与模型路由
|
||
- `llm_service` 运行时路由必须显式传入 `routing_meta`,至少统一:
|
||
- `tier_alias`
|
||
- `response_contract`
|
||
- `fallback_policy`
|
||
- `execution_mode`
|
||
- 禁止再通过函数名片段、hint 常量或模板词在底层推断 tier、结构化输出或 fallback 策略。
|
||
- 所有 LLM 调用禁止静默兜底与 stub 假成功;low 失败时必须优先强制升级到 high 重试并保留低/高两段日志,high 仍失败时才显式报错。
|
||
- 用户可见问答链路(`function_name` 含 `answer/reply/qa`)禁止使用 `reasoning_content` 回退,避免思考过程外漏。
|
||
- `integrations(type='model_routing')` 的 runtime tier override 不得把 `adaptive_rag_answer_normal` / `adaptive_rag_answer_deep` 这类用户可见 QA 主函数降级到 `low`。
|
||
- 模型默认值与 provider/tier 映射以 `backend/.openclaw/pmflow-routing-rules.json` 为唯一配置源。
|
||
|
||
### 3.5 Requirement Plan / Draft / Followup
|
||
- `requirement_plan` 必须是多轮状态机,不得退回单轮模板问答。
|
||
- `MountedTopicWorkspace.plan_status` 必须显式落库区分 `idle / collecting / options_ready / plan_ready / awaiting_execute_confirm / suspended`。
|
||
- `requirement_plan` 的 A/B/C 可以固定为用户可见骨架,但业务选项、推荐项、理由和代价必须走“上下文包 -> 模型结构化决策 -> gatekeeper -> 渲染”。
|
||
- 正在收敛中的 `requirement_plan` 必须支持碎片化回复,不能因缺少新的 `semantic_bundle` 回落到普通 query。
|
||
- 用户显式说“聊个新需求 / 另一个需求 / 跟上一个无关”时,必须先清掉继承的旧 `current_project_id`。
|
||
- 裸 `A/B/C/确认/你自行推荐` 这类低信息量回复,如果没有命中当前 active requirement session 或待确认草稿,必须明确提示当前没有进行中的收敛轮次或草稿。
|
||
- 草稿确认只认显式 `reply_to_message_id` + 明确草稿动作,或显式 `work_item_id`。
|
||
- 飞书历史队列协议已停用:卡片动作与文本 followup 只允许走 `work_item_id + work_item.resume/draft_confirm` 主链。
|
||
- AI PMO 写操作默认先生成草稿并进入 `draft_pending_confirm`,未确认前禁止自动执行入库。
|
||
|
||
### 3.6 AdaptiveRAG / Query 主链
|
||
- `POST /rag/ask` 在命中 `business_review/correction_escalation` 时,必须强制留在 `query.read_only` 主链,禁止误送到写操作草稿链。
|
||
- Feishu 新消息即使被低阶 LLM 先判成写动作,只要统一语义规划层命中 `requirement_plan/business_review/correction_escalation`,就必须在 ingress 阶段强制拉回 `query.answer`。
|
||
- 飞书与 AI PMO 入口(含 `message_intent=mixed`)问答链路必须绕过 deterministic/snapshot 快路径,统一落到场景化 Prompt 生成。
|
||
- 通用行业趋势问答不得注入数据库、项目历史或外部实时搜索结果;只有显式带项目上下文时才允许走 `external_trend`。
|
||
- mixed 场景回复必须强制两段格式输出:`[回答]` 与 `[已收到需求] ...,已入库处理`。
|
||
|
||
### 3.7 Signal / Project / SSTC / Briefing
|
||
- `SignalSourceRegistry` 仅作为信号源接入/幂等内部表;用户可见的项目“信号源/信号”统一落到正式 `Signal`。
|
||
- `create_project_from_natural_language` 必须支持透传 `requested_member_user_ids`,草稿确认时必须把推荐负责人并入项目创建事务。
|
||
- AI Steward `project-from-text` 归一化阶段必须优先走人员能力图谱,禁止绕过能力图谱直接拍脑袋分配。
|
||
- AI PMO `signal.create` 在用户显式要求“先分析再入库 / 自行分析”时,若批量结构化分析失败,必须返回失败安全态。
|
||
- SSTC 宪章 AI 预填充必须输出并持久化 `field_status/field_evidence/readiness/derived_artifacts`;总确认前必须校验 `readiness`。
|
||
- SSTC 发布验证清单必须优先消费 `derived_artifacts.verification_metrics`,禁止回退默认验收项。
|
||
- 老板晨报链路只允许 `BOSS/ADMIN` 访问;`snapshot/live` 语义必须分离。
|
||
- `daily-briefing-v2` 必须复用同一份租户级简报内核,禁止老板晨报与每日简报各自维护独立统计口径。
|
||
- 晨报/日报导出首版只允许前端“当前所见”打印导出,禁止新增后端二进制 PDF 生成服务。
|
||
|
||
### 3.8 Feedback / Training / Prompt Registry
|
||
- 只读问答链路的 prompt 读取优先级固定为:
|
||
- prompt registry manifest 校验
|
||
- active prompt release
|
||
- 代码 seed prompt fallback
|
||
- 回复质量迭代与训练管线的原始反馈入口统一复用 `feedback_center_records / qa_records / ai_call_logs`。
|
||
- 训练/微调 artifact 必须先进入 `trained_model_artifacts -> trained_model_deployments` 候选链路,再绑定到 `low/high` 逻辑槽位。
|
||
- training deployment 的 `accepted` 决策默认受 acceptance gate 约束。
|
||
|
||
## 4. 已知运行边界与假设
|
||
- 飞书回调字段可能缺失文件名/大小,仅保证 `attachment_id/key/type` 可用。
|
||
- 真实飞书网页 E2E 依赖本机已登录的 Chrome/Feishu 会话。
|
||
- 真实飞书网页 E2E 只负责浏览器发消息与页面诊断,结果校验统一走数据库探针。
|
||
- 显式命名的新项目请求不得仅因正文出现历史项目标题就自动绑定已有 `project_id`。
|
||
- 项目创建返回的 `signal_sources` 仅作为 AI Steward 创建结果区的内联展示;项目看板与 SSTC 信号阶段统一只读正式 `Signal`。
|
||
- 老板晨报首版的 `external_metrics` 只返回占位区块,不接 CRM / BI / 收入系统。
|
||
- `daily-briefing-v2` 与老板晨报当前只做同会话内 `snapshot/live` 同步,不引入 WebSocket 推送。
|
||
- 飞书长连接 websocket 在本地/CI 环境默认使用 `certifi` CA bundle 作为信任链。
|
||
- 飞书长连接状态分为两层:`last_received_*` 表示 SDK 已收到事件,`last_event_at` 表示 worker 完成处理。
|
||
- LLM 主链按 `OPENCLAW_ROUTING_ENABLED` 走 OpenClaw 路由规则;请求超时统一以 `LLM_REQUEST_TIMEOUT` 环境变量为准。
|
||
- 路由配置唯一真源固定为 `backend/.openclaw/pmflow-routing-rules.json`。
|
||
- World Model 静态层已接入 Redis 缓存(`wm:static:{tenant_id}:{project_id}`,TTL 600s),写操作后主动 invalidate,动态层不缓存。
|
||
- 本地 `ollama` 仅允许知识库问答链路使用,且必须通过 `llm_engine.settings.enable_local_kb_qa` 显式开启。
|
||
- IT 五轮 requirement plan 现以 `MountedDraftWorkspace.active_work_item_id + latest_*_message_id` 锚定当前 active draft;历史未绑定这些字段的旧草稿不会自动认领。
|
||
|
||
## 5. 维护建议
|
||
- 想看“必须立即遵守的规则”:先看 `AGENTS.md`
|
||
- 想看“当前架构说明和关键入口”:看 `CLAUDE.md`
|
||
- 想看“长运行边界、守门规则和已知环境假设”:看本文档
|