PMFlow/docs/architecture/RUNTIME_GUARDRAILS.md

260 lines
86 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RUNTIME GUARDRAILS
## 1. 目的
- 本文档承接 PMFlow 的长运行边界、跨链路守门规则与已知运行假设。
- `AGENTS.md` 保留必须立即遵守的摘要规则;本文件提供更细的运行时约束与环境边界。
- `CLAUDE.md` 只保留当前架构摘要、关键入口和高价值提醒;长清单统一收口到这里。
- requirement-plan、Feishu reply/thread、AdaptiveRAG、runtime semantic routing 等详细守门细则以本文档为真源,`AGENTS.md` 只保留摘要。
## 2. 同步规则
- 任何影响运行边界、守门策略、失败语义、已知环境假设的改动,都必须同步更新:
- `AGENTS.md`
- `docs/architecture/RUNTIME_GUARDRAILS.md`
- 任何影响目录结构、模块归属与关键入口的改动,还必须同步更新:
- `CLAUDE.md`
- `docs/architecture/ARCHITECTURE_INVENTORY.md`
- 任何影响主链路由、函数名、运行时流向的改动,还必须同步更新:
- `docs/architecture/DATAFLOW.md`
- `backend/.control_plane/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/` 封装层。
- MCP 模板接入中心只允许保存模板参数、命令预览、runtime probe 和手动确认状态;`backend_direct` 模板允许由 PMFlow 后端直连校验/调用,包括远程 `streamable_http` MCP 与后端内建 `backend_adapter` runtime;本地 `stdio` 模板只能通过 PMFlow Local Bridge 或兼容 MCP host 在客户本机承载。服务端不得直接写宿主机 `~/.codex/config.toml`、不得代替客户执行本机命令。GitHub 类模板只允许保存 env var 名称或占位符,禁止落明文 token。
- 飞书回复必须经过 `feishu_reply_outbox`,禁止同步直接发送。
- 飞书回执发送仅允许 `main.py` 的 drain loop 作为消费者,禁止在业务路径即时派发发送任务。
- 所有写接口必须落审计日志(`operation_logs`),至少包含 `trace_id/interface_path/caller`。
- `created_at_beijing` 为计算属性返回,禁止新增数据库物理列。
- 前端身份边界必须与真实写接口一致:`/space`、真实 `/project-launch`、`/me`、项目主链 standalone 与空间管理入口必须登录;客户空间管理入口看当前 workspace role,平台运营入口看 `platform_context.capabilities`,禁止把客户空间 `OWNER/REVIEWER` 当成 PMFlow 平台管理员;`/project-launch?demo=1` 或 `?dataSource=demo` 是唯一匿名启动台演示入口,且只能使用本地 mock/demo,不得调用真实写接口。
- 真实 `/project-launch` 的进度、操作流、审查建议、附件引用和计数必须使用当前输入、`pmflow_launch_draft_jobs` 任务状态、`pmflow_launch_drafts` 后端草案、warnings/evidence 派生;禁止在真实模式展示 `mockData.ts` 的 DevWeekly 周报 demo 内容。低信息输入必须在 `POST /pmflow-launch/drafts` 或 `POST /pmflow-launch/draft-jobs` 前置门禁返回 `input_needs_more_info` 422,让用户补充产品目标、目标用户、核心问题或材料,不得生成空草案或把“未提供”字段推进到确认创建页。Project Launch 草案必须按可变现项目启动计划生成,覆盖目标用户/痛点、核心闭环、输入或数据源、AI 处理链路、输出交互、信任确认、安全合规、变现/留存验证与反馈指标;默认目标为 7-10 条 requirements、10-16 条 tasks、4-7 条 risks、3-6 条 decisions,信息不足只能显式进入 warnings,禁止回退成薄功能 demo。真实生成优先走任务化链路:`POST /pmflow-launch/draft-jobs` 创建 job,`GET /pmflow-launch/draft-jobs/{job_id}` 轮询状态,`POST /pmflow-launch/drafts/{draft_id}/revise` 基于当前草案增量修订;“补充一句”必须保存用户真实补充并创建新 revision,旧运行中 job 只能标记 `superseded/cancelled` 或忽略结果,禁止用前端硬编码补充或 UI 暂停动画冒充 AI 可暂停/续写。
- 账号权限必须分三平面:`users` 只代表登录身份,`tenant_memberships` 代表客户个人/团队 workspace 内角色,`platform_memberships` 代表 PMFlow 内部运营身份。注册用户成为个人空间 `OWNER` 合理,但不自动拥有 `platform.*` capability,不能访问平台供应商、全局路由、route/context 治理、semantic facts 或跨租户运营数据。
- 产品语义里的空间/Workspace 当前兼容落在 `tenants` 表;手机号是用户登录、自注册和邀请绑定的主身份,`users.phone_e164` 必须全局唯一。每个注册账号必须拥有个人空间,受邀加入团队空间不能剥夺个人空间,退出团队空间后必须自动回到个人空间。团队空间只是 membership,不拥有用户账号本身。
- 项目可见性必须以后端为准:`GET /projects/`、`GET /projects/{project_id}`、PMFlow OS 项目读接口、SSTC 项目级读接口、模型上下文项目级读接口与 Space legacy `GET /ai-pmo/work-items` 均需按当前用户收口;`OWNER/REVIEWER` 可看租户级团队视图,其他角色只看本人拥有、本人参与或本人拥有的 legacy 工作项。前端隐藏模块只是体验层,不能替代接口过滤。
- Personal Space 的 `saved_ideas` 是 pre-project idea seed,只允许承接未成型想法、原始输入、来源、准备度、缺失问题、结构化 enrichment 元数据和 Project Launch draft 关联。`POST /space/saved-ideas` 可以尝试 `space_saved_idea_enrichment_v1` 做目标用户/问题/价值假设/验证信号/缺口的结构化完整度判断;该调用使用 `PROMPT_SAVED_IDEA_ENRICHMENT` 并经 Prompt 运营中心 active release 读取与 prompt 归因。问候、测试词或无实质想法输入必须显式判为 `needs_more_info` 和 0 准备度;AI 失败必须显式落 `enrichment_status="ai_failed"` 和 `system_baseline`,不得用模板字段冒充 AI 成功;该接口不得生成草案、创建项目或写项目记忆。`POST /space/saved-ideas/{idea_id}/promote` 只允许生成 `pmflow_launch_drafts` 并回到 Project Launch human review,仍需用户确认后才创建正式项目。团队空间后续扩展只能围绕共享/协作/补充权限扩展该 seed,不得把暂存想法直接升级成 Project Memory、ChangeSet、任务、执行事件或发布信号。
- Space AI Concierge 的前端产品边界固定为 `/space/ai-concierge/*`,必须在 `API_ROUTE_PROFILE=lean` 下随 core `space_api` 加载;内部可复用 RAG/AdaptiveRAG/session 读模型,但前端不得直接依赖 optional `/rag/*` 路由。AI 管家状态必须分层展示:问答能力、历史读取、真实动作建议各自独立降级;历史读取失败不能阻断新会话提问,也不能把辅助能力错误渲染成当前聊天失败。
- 用户可见错误必须使用产品语义分类,禁止直接展示 Axios/FastAPI 原始错误(如 `Request failed with status code 401`、`Could not validate credentials`、traceback)。401/无 token 必须表达为登录/会话问题;需要恢复输入时只能保存 pending intent 并由用户重新触发写操作,禁止登录后自动重放真实写请求。
### 3.2 核心业务零兜底
- 模型失败、超时、空响应、结构化解析失败时,必须显式返回真实失败原因。
- 禁止使用固定兜底文案、模板句子、占位字段或 stub 数据冒充成功结果。
- 核心业务完成态不得仅按字段非空判定;必须能区分“真实生成 / 人工填写 / 模板占位 / 生成失败”。
- 技术层 fallback 仅允许用于重试、缓存、解析修复、传输兼容等基础设施环节,禁止上浮为用户可见业务结论。
- AI Steward 与其它生成链的成功/失败判定必须优先使用结构校验、字段完整性和证据一致性。
- PMFlow OS `ChangeReviewPage` 真实模式只能展示 `ProjectTruthState.changeSets / changeItems / evidence` 的后端投影;顶部统计、待确认列表和右侧 AI 副驾评估都必须由真实 ChangeItem/Evidence 派生。没有真实待审项时必须显示空态或待补充,禁止用 demo 的知识库搜索、混合召回、固定风险/建议/计数补位。`accepted / edited / deferred` 只表示候选项已被人工处理但尚未写入 Project Memory;只要 ChangeSet 未 committed 且 ChangeItem 未 committed/skipped,就必须允许继续 accept/edit/defer,真正锁定边界是 ChangeSet commit。
- PMFlow OS 团队审查与执行边界必须保持单向主链:`TeamLayerPage` 只允许消费 `reviewerRouting / reviewDecision / approvalState / TeamFeed` 做责任路由、角色收件箱、团队动态、审查状态、阻塞解释和跳转,不得直接执行 ChangeSet commit、写 Project Memory 或成为第二套 Change Review;Execution Bridge handoff 只能针对 Project Memory commit 后已进入正式项目对象的 Task,禁止从 `pending_review` ChangeItem、候选 Task、reviewer suggestion 或 team routing item 直接创建正式执行分派。`ExecutionBridgePage` 的 Run 工作台只能把 `已确认需求 / 上下文包 / 开发 / 测试 / 审查合并 / 回写` 作为前端流转表达和证据 gate,不得因为 UI 阶段推进而自动验收、自动合并、自动写 Project Memory 或自动进入发布成功。缺 reviewer、repo/runtime、PromptPackage、测试命令、权限或回写证据时必须返回 blocked/warning,禁止冒充已开始开发或已分配成功。
### 3.3 业务动作归因主链
- 运行时业务动作归因必须优先走:
- 对象/上下文绑定
- `SemanticContextPacket`
- `SemanticDecision`
- gatekeeper
- 用户前台允许以内置 AI 会话作为主入口,但该入口必须绑定正式业务上下文与业务对象,优先服务于 `query.read_only / requirement_plan / project.create / signal.create / followup.*` 等主链,禁止演化为脱离 PMFlow 业务对象的泛化聊天产品。
- 新增 AI 前台能力时,必须优先接入“消息/上下文 -> 语义识别 -> 业务对象/草稿 -> 审计/幂等/确认 -> 入库/执行”链路;不得只停留在对话文本层或仅新增孤立聊天能力而不进入正式业务闭环。
- `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` 不能再由关键词最终拍板。
- `query.answer` 的 referential follow-up state rewrite 只能在“上一轮结构化 scope”与“当前原始问句解析出的结构化 scope”仍连续时生效。scope 比较必须优先看上一轮 `QARecord.routing_snapshot` 中的 `project_id / query_semantics.target_resolution / query_semantics.business_frame(project_binding, object_binding)`,以及当前原始问句经 `query_semantics + project scope resolver` 产出的同组字段;若当前 turn 已切到新的项目或新的业务对象,必须直接停用旧 `state_subject/state_entities` 重写并把原始问句送进后续 route preview。禁止在 `session_state` 里用项目名关键词、正则或其它 lexical shortcut 拍板“是不是换项目/换业务”。
- 冷启动 `WorkflowSemanticPlanner` 必须同时产出四挡 `interaction_boundary`(`status / recommendation / draft / execute / unclear`)与 `answer_control`。运行时允许先识别出底层 write workflow(如 `signal_source_flow:onboard`),但只要 boundary 明确禁止 draft/execute,就必须在 planner 层把最终 bundle 降回 `query.answer`,并把 `requested_level / forbidden_levels / effective_level / blocked_workflows` 显式写进 diagnostics;禁止再在执行层靠“识别到 signal_source_flow 了所以顺手起草”这类升级冲动夺权。
- `AdaptiveRAG` 的 project progress fast answer、AI PMO 的 casual chat 直答,以及 typed executor 的 signal 数量/analysis-mode 解析,现在都必须只消费结构化字段(如 `interaction_level / goal_kind / resource_role / expected_answer_shape / message_intent / requested_count / analysis_mode / operation_intent_contract`)。运行时代码不得再从自然语言文本里用中文/英文词表或正则决定“是不是信号源候选问题”“是不是闲聊”“是不是先分析再入库”“用户要几个候选”。
- AI PMO typed executor 的 `project_lookup` 直答 shortcut 现在也必须只认结构化 `message_intent=project_lookup(_question)` 与 planner 透传的 `query_semantics`;禁止再从自由文本里用 `项目列表/项目清单/项目#123` 一类词面或 `extract_project_lookup_keyword` 提前抢答。
- `query.answer` 相关运行时模块同样禁止换皮回流业务语义拍板:`AdaptiveRAG / external_query_service` 内不得维护 `_INTERNAL_ROUTE_OBJECTS / _EXTERNAL_ROUTE_OBJECTS / _SEMANTIC_QUERY_OBJECT_TYPES` 这类对象集合、`*_probe_is_strong / *_route_probe` 这类强判 helper、或 `query_kind(weather/news/company/market/model)` 这类对象到路由/类型的硬映射。若上游 `SemanticDecision / query_profile / source_policy_hint` 仍不足以唯一确定来源,必须显式保留 `uncertain` 或直接澄清,禁止执行层二次夺权。
- 若问题根因属于“动作路由错误 / 上下文劫持 / 独立业务流误触发”,主修法必须优先落在 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`
- 开发环境启动必须允许显式关闭重型副作用:`STARTUP_MODEL_PROBE_ENABLED`、`FEISHU_LONG_CONNECTION_ENABLED`、`STARTUP_WORLD_MODEL_WARMUP_ENABLED`、`STARTUP_SCHEDULERS_ENABLED`、`STARTUP_BACKGROUND_WORKERS_ENABLED` 是当前唯一允许的 startup 开关;需要压缩热重载时,应优先通过这些环境变量降载,而不是在代码里硬删启动逻辑或把副作用偷偷移到 import side effect。
- `backend/app/api/router.py` 的 optional route group 只能通过 `API_ROUTE_PROFILE` 与 `API_OPTIONAL_ROUTE_GROUPS` 控制;默认 `full` 保持现有全量 API,`lean` 只允许作为开发减载配置使用,禁止在运行时代码里基于请求内容或关键词动态裁路由。空间级 AI 使用设置依赖的 team policy API 与平台 AI Operations Console 依赖的 `ai_routing / model_routing / llm_engines` API 属于核心路由,必须在 `lean` 下继续加载,避免 `/ai-config/*` 或 `/platform/*` 变成 404。
- 开发预览端口职责必须固定:`5174` 仅保留给源码热更新前端,`docker-compose.yml` 下的静态生产预览前端默认改用 `5175`(`FRONTEND_PROD_PORT` 可覆盖);禁止再让 `5174` 在静态容器和 Vite dev server 之间来回漂移,避免浏览器验证和真实源码脱节。
- 禁止再通过函数名片段、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`。
- `backend/.control_plane/pmflow-routing-rules.json` 是 PMFlow 本地路由层 baseline/default rule pack 和冷启动 fallback;平台运行时一旦存在 `integrations(type='ai_capability_slots')` 已发布 active 槽位绑定,`low/high` tier 解析、control-plane rule、函数级 override 和低阶失败升级必须优先消费 active slot 的 primary runtime + fallback chain,禁止继续把 JSON 中的 provider/model 当成唯一实时绑定。`generate_structured_object` 在 `response_contract=structured` 时必须优先消费已发布 active `structured` slot 的 primary/fallback chain;没有 active structured slot 时才回到既有 low/high/control-plane 链路。active structured runtime 选择必须跳过 disabled/deleted runtime 和不满足 `structured_output + json_schema` 的 runtime,并在 routing meta 中记录 `slot_key=structured / slot_version / slot_runtime_source=active_slot / slot_fallback_index / slot_degraded=false`。active structured primary 调用失败后只允许继续尝试同一 active structured slot 的 fallback chain;全部 structured runtime 失败后必须显式失败,禁止再落回模板假成功或无关 low/high 路由。如果 active structured slot 已配置但没有可用 runtime,项目启动、需求结构化、任务拆解、ChangeSet extraction 等保护结构化函数必须显式失败;非保护结构化调用才允许降级到既有路径,并必须记录 `slot_runtime_source=active_slot_degraded` 与 `slot_degraded=true`。已发布 active `long_context` slot 只允许由显式长文档/长线程/跨项目上下文调用消费,即 `routing_meta.slot_key/planned_tier/tier_alias=long_context`;已发布 active `tool` slot 只允许由显式工具调用或 MCP execution planning 消费,即 `routing_meta.slot_key/planned_tier/tier_alias=tool` 或 `execution_mode=local_planner|local_worker`。long_context/tool slot 运行时必须跳过 disabled/deleted runtime 和能力不足 runtime;active slot 已配置但没有可用 runtime 时显式失败,没有 active slot 时回到既有 low/high/control-plane 链路。已发布 active `external_query` slot 只允许在 `route_mode=external` 或等价 external source policy 后由 `external_query_service` 消费,绑定对象是 `primary_provider_id / fallback_provider_ids / verifier_required / source_filtering_required / failure_policy=explicit_fail`,不是普通 LLM engine;internal query、未发布 draft 和缺 route_mode 的调用不得消费该槽。外部查询失败必须显式失败或返回 freshness guard,禁止回退普通 LLM 编造答案。能力槽位草稿只用于平台 AI Ops 编辑、校验和发布预览;运行时禁止读取未发布 draft slots。供应商能力矩阵必须分清声明能力、`capability_probe` 探测证据和后端派生 `effective_capabilities`;探测证据保存在 `integrations(type='llm_engine').config.engines[*].capabilities.capability_probe`,并继续同步兼容 `capability_evidence / capability_probe_status / capability_last_verified_at`。能力探测必须按 registry 逐项执行,`structured_output` 与 `json_schema` 独立验证;`streaming` 只表示 `stream=true` 增量响应的传输/运行特性,不属于编辑弹窗声明能力矩阵,也不得混入“已验证可用”模型能力列表;供应商页声明能力必须完整展示,不得用固定数量截断,任一声明能力缺少 live/provider_contract/operator_verified 证据时,能力状态不得显示为 passed;默认 full 探测可增加 `model_self_report` 低成本自报参考,但 `evidence_strength=model_self_report` 只用于运营提示和冲突辅助,禁止满足 protected slot 发布,供应商页只能在“模型自报参考”独立区域展示,不得混入“探测明细”能力项;默认探测计划只把声明能力纳入阻塞/聚合口径,未声明的可选能力不得展示为“没通过”或导致整体“部分通过”;长上下文供应商探测必须按供应商配置的 `max_context_tokens` 记录声明窗口,禁止把普通 `long_context` 默认硬映射为 32K,`long_context_32k/128k` 只用于显式阈值探测和槽位发布门禁;供应商编辑若改变 provider/model/base URL/API key 或声明能力矩阵,必须清空旧 `capability_probe/capability_evidence/effective_capabilities` 并回到 `untested`,只有名称等展示字段修改可保留证据;长上下文声明窗口未知官方合同时只能记录 `declared_only`,不得冒充 verified evidence;已知官方供应商/模型规格(如 DashScope `qwen-plus`)可作为 `provider_contract` verified evidence,但不写入 AI 调用审计,因为没有真实上游 endpoint 交互;平台操作人可对高成本长上下文执行人工确认,写入 `operator_verified/operator_attestation` 证据、确认窗口、来源、确认人和过期时间,该证据可满足长上下文槽位发布,但必须在 UI 和审计语义中标明“人工确认”,且不得写入 AI 调用审计或伪装成 live/provider endpoint 调用;模型自报是实际上游短调用,应写入 AI 调用审计但不得冒充 verified evidence;旧 runtime 必须由服务层按 provider/model 归一化默认能力和 `capability_probe.status=untested`,但默认/人工标签不得冒充 live probe evidence。publish validation 必须按 `SLOT_REQUIREMENTS` 检查 draft 的 primary/fallback 是否满足槽位要求,高阶槽禁止 local-only/Ollama,结构化槽要求 `structured_output + json_schema` 且具备未过期 live/provider_contract verified evidence,长上下文槽要求 `long_context + max_context_tokens >= 32768` 且具备未过期 live/provider_contract/operator_verified evidence,工具槽要求 `tool_calling` 且具备未过期 live verified evidence;external_query 槽要求至少一个 external provider 可用、MCP adapter 或 bounded live search fallback 可用、verifier 可用、source filtering fail-closed 开启,且 failure policy 必须 explicit_fail;低阶槽缺 probe 只返回 warning。`structured / tool / long_context / external_query` 是正式可配置槽位,`private / multimodal` 仍是不可配置候选槽,只展示候选状态和缺口,不得被 runtime 消费或冒充已启用。
- `GET /ai-routing/admin-console` 必须返回 `scene_slot_matrix`,把 PMFlow 业务场景解释为 `scene -> scene_contract -> required/current slot -> active runtime -> draft runtime -> scene_health -> release_gate -> impact`,供平台运营判断一次槽位发布会影响哪些能力。每个 scene row 必须包含 `scene_key / scene_label / scene_contract / lifecycle / protected / functions / required_slot / active_slot_runtime / draft_slot_runtime / active_version / draft_dirty / capability_gap / recent_failure_count / scene_health / release_gate / impact_summary`,并兼容旧字段 `current_slot / active_runtime / draft_runtime / recent_failure_rate`;active 场景默认映射为 project_launch/change_review/requirement_structuring/task_breakdown -> structured,assignee_matching -> high,internal_qa -> low/high mixed,external_query -> external_query,feishu_understanding/feishu_reply -> low。`backend/app/services/ai_routing_scene_contracts.py` 是场景合同 registry,active 场景参与健康度和发布门禁;candidate 场景(release_review、retrospective_summary、project_memory_writeback、mcp_execution_planning、contract_sync)只展示合同和预期槽位,不参与 protected release block,不得被运行时消费。`change_review` 是项目主链“发送并提取”的 protected active 场景,绑定 `pmflow_change_review_extraction_v1` 与 `PROMPT_PMFLOW_CHANGE_REVIEW_EXTRACTION`,输出待确认 ChangeSet/ChangeItems,失败必须 fail-closed。该矩阵只读聚合 active slot 发布版本、draft 预览、能力覆盖、近期失败计数和函数级路由,不写 provider、不写 slot、不写模型路由。场景路由 UI 定位为 Scene Contract & Impact Console,必须展示业务场景合同、当前槽位、active/draft runtime、能力缺口、发布影响、健康度、发布门禁、筛选排序和确定性修复动作;能力槽位详情必须展示受影响场景;供应商/槽位/失败诊断 deep-link 必须聚焦 scene/slot/capability;函数名、规则名和 override 来源不在业务场景路由页展示,函数级检查统一进入隐藏 Route Lab。当前 `sceneContracts.ts` 仅作为后端合同缺失时的前端 fallback,不得调用 LLM 或按关键词推断 runtime 路由。
- Function Runtime Profile 是业务场景路由下的“生成运行合同”,不是旧函数级模型路由覆盖。配置真源保存到 `integrations(type='ai_function_runtime_profiles')`,默认由 `backend/app/config/ai_function_runtime_profiles.py` seed;平台只允许在业务场景详情里按产品语义展示生成预算、修复预算、temperature、active/draft、真实 smoke、发布门禁和 7d 输出 token/截断观测,不向客户视图展示 raw function name、prompt key 或 provider payload。运行时只能消费已发布 active profile;draft 只能用于平台 AI Ops 编辑、validate、真实 smoke 和发布预览。`pmflow_launch_draft_v1` 与 `pmflow_change_review_extraction_v1` 的 `max_tokens / repair_max_tokens / temperature / response_mode` 必须分别通过 active profile 进入 `PMFlowLaunchService`、`PMFlowChangeReviewService` 和 `routing_meta`,禁止继续以散落常量作为唯一真源;若 profile 服务不可用,只允许使用同文件 default profile 作为冷启动兜底并保留 `profile_source` 审计。
- `GET /ai-routing/admin-console` 必须返回 `slot_observability`,按 active `low/high/structured/long_context/tool/external_query` 槽位聚合发布后真实调用表现。观测窗口固定为 24h 与 7d,指标包含 `total_calls / failed_calls / failure_rate / fallback_hits / degraded_calls / average_latency_ms / estimated_cost / recent_failure_samples`;`slot_runtime_source=active_slot_degraded` 或 `slot_degraded=true` 计入 degraded,`slot_fallback_index > 0` 计入 fallback 命中。无日志必须返回 `status=empty` 与“暂无运行样本”,禁止伪造成功率、成本或延迟。成本和延迟只展示 `ai_call_logs` 估算来源,不得包装成供应商精确账单或 SLA;该读模型不得改变 publish/rollback/runtime 路由行为。
- `GET /ai-routing/admin-console` 必须返回 `slot_recommendations`,基于 capability evidence、候选 runtime 与 `slot_observability` 生成确定性运营建议;建议不得调用 LLM,不得自动保存 draft、publish 或 rollback。建议项必须包含 `severity / slot_key / reason / evidence_summary / suggested_action`,可选 `target_engine_id`;缺 verified evidence 建议运行 capability probe,证据过期建议重新 probe,7d failure/fallback/degraded 异常建议补 fallback、评估 fallback 升 primary、修复 active slot 或回滚,low 槽成本/延迟异常建议评估低成本/低延迟候选,structured/tool/long_context 没有候选 runtime 时建议回供应商页补能力或接入新 runtime。证据不足时必须返回空建议并在 UI 展示“暂无建议”,禁止编造优化动作。
- AI 路由与供应商产品化控制台 v1 属于 PMFlow 平台 AI Operations Console,只做治理聚合、脱敏展示、平台诊断和审计;运行总览合并进 `/platform`,AI 运行层只保留“供应商与凭据 / 能力槽位 / 业务场景路由 / 成本配额缓存 / 失败诊断”明确子菜单:团队策略仍保存到 `integrations(type='ai_team_policy')`,但供应商、全局路由、函数级路由、route/context 治理和 semantic facts 操作必须要求 `platform.*` capability;函数级路由不作为运营侧常规菜单暴露,只能通过隐藏 `/platform/route-lab` 只读诊断页查看。不得在客户空间 `OWNER/REVIEWER` 权限下改写 `llm_service` runtime 路由、`backend/.control_plane/pmflow-routing-rules.json` 或 provider secret。供应商连接不是单选开关,多个连接可同时启用;`default_fallback_engine_id` 仅表示无规则命中时的全局兜底运行时,不得被展示或实现为“唯一启用模型”;能力槽位才负责把启用的供应商连接编排成 PMFlow 可消费的 primary/fallback 能力链,并且必须经过 draft -> validate -> publish -> active 的发布控制后才影响 runtime。
- 用户可见层必须使用产品语义表达 AI 模式与状态,例如“快速处理 / 深度分析 / 项目记忆查询 / 外部实时查询 / 待确认执行”。成员视图不得暴露 `low/high`、provider、model、`function_name`、`api_env`、raw routing meta 或明文 key;空间负责人只看业务场景策略;平台 AI Ops 的业务场景路由也不展示 `function_name`,函数级路线只允许隐藏 Route Lab 只读诊断。
- 函数级模型路由覆盖只允许选择已定义槽位别名(当前 `low/high`),禁止直接编辑任意 provider/model/base_url。需求规划、项目需求抽取、人员匹配等保护场景函数不得被覆盖到不满足场景要求的低能力槽;服务端必须在保存 override 前拦截,而不是只靠前端隐藏。
- AI 路由与供应商运行真源以平台“供应商与凭据”中保存的 provider/model/base_url/api_key/enabled/default_fallback/connection_status/capabilities/capability_probe 与“能力槽位”中保存的 slot primary/fallback 绑定为准;运行路由、函数覆盖路由、连通测试、能力探测、能力槽位和诊断不得使用 `DASHSCOPE_API_KEY / OPENAI_API_KEY` 等环境变量覆盖平台供应商配置,也不得把环境变量配置当成已配置供应商展示。运行调用、low/high tier 选择和低阶失败升级必须跳过 `enabled=false` 的供应商连接;连通测试可以测试停用连接但只更新测试状态,不得自动设为兜底默认;capability probe 只能回写当前 engine config 中的 `capability_probe` evidence/source/status/last_verified/blocking_reasons 及兼容 flat 字段,不得新增 schema 或直接修改 slot active。诊断只能返回 masked key、能力标签、能力来源、last verified、probe status、覆盖缺口、缺证据/证据过期缺口和中文风险说明;禁止返回 prompt、raw error、raw provider payload、raw env value 或明文 token。
- `ai_call_logs` 是平台 AI 调用审计的运行真源。`llm_service` 必须在真实 provider transport 边界记录上游 `provider_request_payload / provider_response_payload / provider_attempts`,用于平台追溯实际发送给供应商的 model/messages/response_format/agents 等参数、返回 body 与重试链;不得只记录裁剪后的业务 prompt/response 冒充上游出入参。token 口径必须优先读取上游 response payload 中的 `usage.prompt_tokens / usage.completion_tokens / usage.total_tokens`,兼容 `input_tokens / output_tokens`,只有缺失 usage 时才使用长度估算;AI 调用审计列表与详情必须能展示 completion tokens、请求 `max_tokens`、finish_reason 和 Function Runtime Profile 版本,避免把“模型空响应”和“真实返回但解析失败/截断”混成同一类问题。平台审计 API 可返回完整脱敏 provider payload;客户空间、Space、Project Launch、项目级 AI 副驾和普通回答链不得暴露这些字段或原始 headers/密钥。AI 调用失败归因必须区分 `structured_timeout / structured_json_invalid / structured_empty / structured_http_error`,不得统一压成“结构化失败”误导运营排障。
- AI 场景超时策略归属业务场景合同,不得继续散落为 transport 层写死常量。保护型结构化场景必须通过 `AISceneRuntimePolicyService` 或等价场景策略在 `routing_meta` 显式写入 `scene_timeout_policy_id / input_bucket / input_tokens_estimate / foreground_wait_seconds / provider_timeout_seconds / job_timeout_seconds / scene_fallback_policy / large_input_policy`;底层 transport 只能消费这些显式策略,不得靠 function name 私自推断。Project Launch draft 的 `AISceneRuntimePolicyService` 先按输入规模提供 small/normal/large 默认策略,平台 Function Runtime Profile active 合同可覆盖前台等待、provider/job 超时、最大重试和大输入策略;draft 合同必须在 `/platform/ai-routing-scenes` 保存、smoke 成功并发布后才进入运行时。`provider_timeout_seconds` 控制上游 HTTP client timeout,`job_timeout_seconds` 控制 draft job 外层 `wait_for` 超时失败,`max_retries` 控制 provider 网络异常/可重试 HTTP 状态的 transient retry budget,`large_input_policy=preprocess_then_generate` 在 large 输入桶执行有界材料压缩后再渲染 prompt,`foreground_wait_seconds` 进入 draft job response 供前端等待窗口消费。large 输入应进入预处理/分段结构化方向,而不是无限增加单次模型请求时间。超时必须显式落 `structured_timeout` 或 `draft_job_timeout`,禁止模板兜底冒充草案生成成功。
- `/ai-config` 用户可见定位为空间级 AI 使用设置,不是 PMFlow 平台管理后台。它只承载 readiness、团队 AI 策略、输入源、知识、MCP 模板使用和额度/连接测试;平台供应商、全局路由、route/context 治理、semantic facts、prompt/eval 与跨租户运营数据必须放在 `/platform/*` 并由 platform capability 保护。项目级页面只能通过 `AI 副驾` 展示副驾状态、来源/可信状态、上下文缺口、待确认和项目流程跳转,禁止提供项目级 provider/model/MCP 模板/底层路由覆盖入口。
- Project Launch readiness 是平台能力门禁,不是单个用户草案请求的成败灯。`GET /ai-readiness/project-launch` 必须先以平台运行租户供应商、published active `structured` 槽、scene registry、Function Runtime Profile active 合同与结构化能力证据做硬门禁;`pmflow_launch_draft_v1` 调用日志只作为 24h 内健康信号,单次最近失败在已有近期成功且连续失败少于 3 次时只能进入平台 warning,不得关闭用户端生成入口;连续失败达到阈值或缺少近期成功时才允许进入 recovering。`POST /ai-readiness/project-launch/check` 可触发真实结构化 smoke,但不得写 draft/project/task/Project Memory。
- `/platform/prompt-assets` 是平台 Prompt 运营中心,只允许 `platform.ai_routing.manage` 访问。它可以展示 `ai_prompt_registry`、默认 seed prompt、`prompt_releases`、`prompt_release_checks`、分层 `prompt_golden_cases`、`prompt_replay_runs / prompt_replay_case_results`、prompt-attributed `ai_call_logs` 质量摘要、调用点、风险级别和迁移状态,但不得出现在客户空间 AI 设置、Space、Project Launch 或项目级 AI 副驾。平台 API 允许 `editable_policy=managed_release` 且已配置化的 prompt 创建草稿、激活和回滚;`guarded_release` 只允许创建候选版本、运行 release replay run 和门禁,激活必须通过 variable contract / schema smoke / golden replay;golden replay 无 active golden case、无最新 release replay run 或最新 run 存在 blocking failed case 时必须保持 blocking,禁止伪造成通过。LLM replay 只能通过 `llm_service` + 显式 `routing_meta` 进入本地路由层,禁止在 Prompt 运营中心硬编码 provider/model;case result 必须保留 baseline/candidate AI call log、judge score/label/reason 与风险标记。`priority=blocking` 的 golden case 失败阻塞发布,`important/observation` 失败只能进入 warning/人工复核,不得自动激活。release watch 只能给健康/复核/回滚建议,不得自动回滚。标记为 `runtime_source=inline_discovered` 或 `editable_policy=needs_migration` 的条目只代表已完成清单梳理,运行时尚未改为 active release 读取;运营界面必须明确显示“待迁移”,禁止把它们表达成已经可配置生效。受保护 prompt 的编辑/激活必须继续走 replay/schema/golden case 门禁,不得因为能在清单里看到就绕过发布评审。
### 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。
- active requirement context 下的碎片化短回复(补一句、补约束、单句回答目标用户/技术路线/交付方式等)必须优先留在 requirement-plan collect / contextual promotion 主链;若当前 turn 缺少新的 `semantic_bundle`,只允许在 requirement 主链内做最小 backfill,禁止先掉回普通 `query.answer`、也禁止为了补 bundle 强制新开 requirement intent。
- requirement-plan / draft 协议动作的优先级必须固定为“当前 turn 的显式 raw protocol > 结构化 semantic bundle > card/历史 option map 推导”。裸 `A/B/C`、`我选C`、`确认`、`取消`、`重出`、`修改` 等当前 turn 明确协议动作一旦命中,就必须先锁定当前轮次动作;semantic backfill 只能在显式协议解析失败后才允许参与补全。
- 同一 `conversation_scope` 一旦存在 active requirement workspace,线程即进入 requirement mode lock:除显式“退出需求模式”外,后续消息只能走需求澄清、A/B/C/D 协议、补一句、出草稿、重出这轮等 requirement-plan 动作;闲聊或其它问答必须显式提示“当前正在需求模式”,禁止再落回 `casual_chat / business_review / query.answer`。
- internal config 问答现在必须依赖显式 `business_frame.object_binding` 区分具体配置对象;`resource_role=config` 已不允许再默认降成泛化 `config:system`。模型路由类问题应绑定 `config:model_routing`,MCP 配置类问题应绑定 `config:mcp_template_center`;若上游没有给出对象绑定,只能澄清,禁止直接答成模型引擎配置。
- `impact_judgment + impact_chain + explicit/current_project` 这类项目化影响判断问题,允许复用 project progress fast answer 主链,但即使没有抓到外部实时条目,也必须保留结构化 `external_impact`/直接影响结论,不能退回普通项目周报口吻把影响链吞掉。
- 已绑定 active requirement context 时,显式“退出需求模式”必须在 active-context followup 阶段直接把当前 requirement topic 挂起为 `status=suspended / plan_status=suspended / pending_actions=['resume_requirement_plan']`,禁止先掉进普通 `query.answer` 再靠后续 session/route 猜退出。
- 同一 `conversation_scope` 内同时存在 collecting requirement topic 与后续普通 query 产生的 idle topic 时,runtime 选择 active requirement workspace 必须优先命中仍带 active draft 的 live requirement topic;禁止因为新 topic `updated_at` 更近就把 idle query topic 误当成当前 requirement context。
- 旧 `business_review/clarify` 或其它 query-side clarify 若已经失去显式锚点,而当前 turn 给出了新的 requirement seed / 新项目 / 新业务目标,runtime 必须允许 semantic refresh 并切到新的 requirement topic,禁止旧 clarify 继续锁死线程。
- 用户显式说“聊个新需求 / 另一个需求 / 跟上一个无关”时,必须先清掉继承的旧 `current_project_id`。
- 裸 `A/B/C/确认/你自行推荐` 这类低信息量回复,如果没有命中当前 active requirement session 或待确认草稿,必须明确提示当前没有进行中的收敛轮次或草稿。
- `draft_pending_confirm` 草稿确认链只允许由显式锚点进入:`reply/thread`、卡片按钮或显式 `work_item_id`。无锚点普通消息、闲聊、新需求或独立事实问句禁止再按“同群/同人”回捞旧 pending draft。
- 同一 `conversation_scope` 一旦存在 active `draft_pending_confirm` workspace,命中上述显式锚点的后续消息必须优先回到当前草稿确认链处理,支持确认/修改/重出/取消与展示反馈;即使动作未识别,也必须显式提示“当前正在处理待确认草稿”,禁止再新开 topic 或落回 `query.answer`。
- 当 `draft_pending_confirm` 命中显式 `reply/thread` 锚点时,mounted draft / pending draft 的候选集必须先通过该锚点精确命中;同群、同 scope、同人但锚点不匹配的历史草稿不得继续参与打分、布尔探测或 fallback 回捞,避免 requirement-plan 的 `A/B/C` 回复被旧 draft confirm 链劫持。
- `draft_pending_confirm` 在 `ready / draft_pending_confirm` 状态下,无显式锚点的单个 `A/B/C/确认/取消/重出/修改` 不得继续恢复旧草稿确认链;这类 no-anchor 单句若没有当前 draft 的 `reply/thread`、卡片动作或 `work_item_id` 绑定,只能显式提示“当前没有进行中的待确认草稿”或回到普通 `query.answer`,禁止偷回旧 ready draft。
- 当同一 `conversation_scope` 内的旧 `requirement_plan` / `draft_pending_confirm` 已被判定为污染且当前消息不再显式锚定该线程时,ingress 必须先把 scope 内 active plan/draft topic 与待确认 work item 终止为 `suspended / cancelled`,并把会话回退到 `query.answer`;禁止残留 plan topic 继续吸收普通问句。
- 用户显式 `reply/thread` 某条已绑定回复并要求“基于当前信息出草稿”时,主链必须先尝试从该 reply 命中的 mounted context 升格生成 requirement-plan 草稿;若上下文不足,必须显式失败,禁止回落到 `query.answer` 冒充“草稿已生成”。
- 用户在显式 `reply/thread` 的同一需求线程里已经完成 `A/B/C` 选项收敛后,后续碎片化追问必须先尝试把该 reply 命中的 chat context 升格成 requirement-plan workspace,再走 `requirement_plan` 主链;禁止继续落到通用 `query.answer` 并把代码路径、内部函数名或工程证据泄漏到用户可见答案里。
- 用户对 requirement-plan 轮次回复 `A/B/C` 协议时,识别范围必须覆盖裸 `A/B/C`、`我选C`、`选C`、`就C吧`、`先按C` 等显式选项回复;这些协议消息必须优先使用上一轮真实选项表(`round_option_maps`)解释该选择。
- requirement-plan 的选项协议识别属于协议层,不属于业务语义拍板;运行时代码必须复用单点协议解析器输出结构化 `choice + remaining_text`,禁止在各入口重新散落正则或关键词规则来解释这类协议回复。
- requirement-plan 在飞书前台应优先渲染为交互式卡片按钮;按钮动作必须携带 `work_item_id` 与结构化动作码(如 `plan_choice / plan_continue / plan_reroll`),由按钮回调回写到当前 requirement-plan 主链,文本协议只作为兼容兜底。
- `requirement_plan_followup` 一旦由 `query` 主链产出,`ReplyRenderer` 与 capture/render 链必须原样保留该 `reply_template_key`,禁止被通用 `action_succeeded` 覆盖后退回纯文本发送。对 active requirement follow-up 这类尚未绑定专属 work item 的收敛轮次,允许临时复用 mounted topic id 作为卡片按钮 round-trip target,但该 target 只用于按钮回流与追踪,不得冒充真实业务 work item。
- Feishu requirement-plan 卡片按钮回流时,若来自飞书卡片消息,必须按 `source_system=feishu` 重入并带上 `thread_context.reply_to_message_id/root_message_id`;ingress 与 mounted runtime 必须先通过 `feishu_reply_outbox.sent_message_id -> source_message_id` 归一化 canonical thread context,再继续绑定当前 requirement-plan topic。禁止按钮动作以无锚点 `ai_pmo_ui` 会话重入,导致 requirement-plan 续链失败或回退纯文本。
- 若后续需要在任何运行时模块新增正则/关键词驱动的协议或业务语义判断,必须先经 Host 明确确认;未经确认禁止新增。协议层优先使用单点结构化 parser、state machine、上下文快照或显式 option map,若证据不足必须显式失败,禁止再用扩词表、补正则或前缀枚举做“最小修补”。
- requirement-plan 低信息量选项回复若缺少上一轮真实选项表,只能显式失败或重新发起该轮次,禁止回退到通用 IT 项目默认映射误译用户选择。
- AI PMO ingress 的 mixed sidecar 预检查不得拦截显式 `reply/thread` 下的低信息量协议回复(如 `A/B/C`、`我选C`、`就C吧`);这类消息必须优先交给 active-context / requirement-plan 主链处理,禁止先生成 `[回答]...[已收到需求]` 的 mixed 拼接回复污染主结果。
- orphan requirement-plan followup 在显式 `reply/thread` 存在时,必须先尝试从 reply 命中的 chat context 恢复或升格 requirement workspace;只有恢复失败时才允许回“当前没有进行中的 A/B/C 收敛轮次”。
- Feishu 显式 `reply/thread` 到机器人消息时,ingress 与 mounted runtime 必须先通过 `feishu_reply_outbox.sent_message_id -> source_message_id` 归一化 `root_message_id/reply_to_message_id`,并在后续 active-context / requirement-plan / draft 主链里复用同一份 canonical thread context;禁止直接用机器人 `sent_message_id` 新开 chat topic,导致 requirement-plan / draft 线程分叉。
- requirement-plan 的唯一业务真源固定为 `MountedDraftWorkspace.requirement_card`:收敛轮次、已确认字段、`round_option_maps`、`last_round_options`、`source_material` 等业务状态只能从 draft 或结构化 `requirement_plan_context` 恢复;`mounted_topic_workspaces.facts_json` 只允许保留线程索引级最小字段(当前限定为 `title / plan_profile`),`work_items.execution_result` 与 `mounted_conversation_runs.final_reply` 仅作审计/回放,禁止再从 assistant prose、topic facts 或 run 文案反推需求字段。
- `POST /ai-pmo/process-text` 与 `GET /ai-pmo/work-items` 对 requirement-plan 的前台可见状态必须直接投影 `plan_mode / plan_status / requirement_plan_context_summary`;Space legacy adapter 与其它前端入口不得再靠 `reply_template_key`、草稿 prose 或 stage 文案自行猜测当前是否仍在需求模式。独立收件页已退场,旧 `waiting_manual / draft_pending_confirm` 只能作为兼容读模型接入 `/space` 或回到主流程。
- requirement-plan 的运行时路由命名也必须单独收口:收敛轮次统一写 `requirement_plan.collect`,草稿确认前的结构化草稿统一写 `requirement_plan.draft`;`query.answer` 只保留给通用问答,禁止在 requirement-plan 主链里继续借用旧 query route 记账。
- 冷启动 `WorkflowSemanticPlanner` / `pmflow_semantic_context_decision` 若因 provider 异常、空结构化结果或网络抖动失败,`_resolve_intent` 不得直接把首轮线程打成 `error_template`;必须集中降级为带 `semantic_planner_degraded=true` 审计标记的中性 `query.answer` 场景。后续运行时必须优先重试 semantic backfill;若命中显式 active requirement context / reply anchor,仍留在 requirement-plan 主链,否则继续按普通 QA 处理,禁止无锚点把事实问句硬降级成 requirement consultation。
- 飞书历史队列协议已停用:卡片动作与文本 followup 只允许走 `work_item_id + work_item.resume/draft_confirm` 主链。
- AI PMO 写操作默认先生成草稿并进入 `draft_pending_confirm`,未确认前禁止自动执行入库。
- `project_create.create` 与 requirement draft confirm 的任务拆解是从属子步骤,不再允许阻塞项目、主信号、来源挂载与宪章的确定性创建。任务生成链必须先按 `routing_meta(tier_alias=low, response_contract=structured, execution_mode=local_planner)` 尝试,并在结构质量不足、空任务、不可映射技能或 provider 失败时升级 `high`;若高阶仍失败,运行时必须显式写回 `task_generation.status=pending` 与真实失败原因,保持 `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 阶段强制拉回受控问答主链;其中 requirement-plan 收敛轮次必须落到 `requirement_plan.collect / requirement_plan.draft`,不得再回写为 `query.answer`。
- 飞书群聊 `query/followup` 同步直答只允许显式触发:`@PMFlow`、显式 `reply_to_message_id`、卡片动作或显式 `work_item_id`;无显式触发时不得同步直答,也不得写入 followup QA 桶。
- Feishu `query/followup` 会话键在命中 `reply/thread` 锚点时必须优先使用 thread key;仅在没有显式锚点时才回落到默认的 `chat + sender` scope key。
- AdaptiveRAG 命中显式 `reply/thread` 锚点后,问题改写必须优先使用该锚点;`session_state.last_subject / last_entity_ids` 只允许在没有显式锚点时参与续写,禁止旧会话主题覆盖显式引用上下文。
- 飞书与 AI PMO 入口(含 `message_intent=mixed`)问答链路必须绕过 deterministic/snapshot 快路径,统一落到场景化 Prompt 生成。
- `query.answer` 在进入 AdaptiveRAG 检索前必须先产出单一 `source_policy`(`internal / external / uncertain`)审计字段;来源判断只允许消费上游明确锚点与单次结构化语义结果,禁止再新增基于“问题长相”的本地关键词/正则拍板层。若上游合同仍是 `uncertain`,执行层只能保持 `uncertain` 或消费上游显式给出的 `effective_source_policy`,不得私自默认 external-first。v1 禁止同一轮 query 同时混搜内部知识库与外部网页,必须先定来源再检索。
- non-plan `query.answer` 的来源裁决统一由 `Query Route Gateway` 执行,输出必须至少包含 `route_mode / decision_origin / reply_contract / probe_snapshot(contract audit)`;回复正文必须遵守显式来源合同(`内部知识库查询:` / `外部实时查询:`),`uncertain + effective_source_policy=uncertain` 必须直接澄清,禁止混合答案。
- query-route 澄清协议也属于受控 state machine:若线程上仍挂着 `pending_clarification(kind=query_route_selection)`,但当前短消息通过 `WorkflowSemanticPlanner` 给出显式 `topic_switch=new` 或命中新话题 workflow,ingress 必须先让旧澄清立即失效,再回到新的 `query.answer` 主链;禁止因为“短句”条件成立就继续消费旧 option map。
- `pending_clarification` 与 follow-up anchor selection 也不得回流到“第几条/标签名/关键词”本地解析:`mixin_followup_anchor.py` 只能通过统一结构化语义解析当前澄清回复,再把选中的 `query_route_selection` 或 `followup_anchor_selection` 显式映射回 `source_policy_hint / query_semantics_overrides / selected_qa_id`。澄清后若已选中上一轮候选 QA,主链必须把该 `selected_qa_id` 继续透传给 follow-up anchor resolver,禁止清掉原问题后再靠最近回复词面重猜。
- internal `Operation Contract / Target Resolver` 也必须优先吃统一语义规划层透传下来的 business frame(至少包括 `goal_kind / target_scope / resource_role / project_binding / object_binding / expected_answer_shape`),再决定是 `project / task / signal / config / feature / doc / user` 哪类内部对象。`mixin_target_resolution.py` 不得再让 `subject_focus / referenced_objects` 这类 coarse 字段独自决定“是不是项目/是不是配置”;缺少 business frame 时只能显式 clarify / insufficient-evidence,而不是回退到粗粒度对象猜测。
- internal object/domain clarify 也必须继续沿同一条结构化主链往下分层:当 `source_policy=internal` 已明确,但 `business_frame` 只落到大域(例如 `resource_role=config`、`feature` 或 `doc`)而尚未唯一命中内部对象时,运行时必须先通过 `internal_domain_catalog -> target_resolution(candidate_summary) -> clarification_protocol(kind=internal_target_selection)` 产出更深一层的受控澄清,再把 follow-up 选中的 `query_semantics_overrides` 回填主链并继续受控检索;禁止在澄清后复读旧答案,也禁止把泛化系统配置问题默认落成模型路由或其它单一 config 对象。
- `AdaptiveRAG` read-side 的 deterministic query / fast answer / retrieval / deep guard / feature-evidence consumer 也必须遵守同一条 business-frame-first 规则:`mixin_deterministic_query_core.py`、`mixin_fast_answer_project_main.py`、`mixin_fast_answer_semantic_p1.py`、`mixin_deterministic_query_count.py`、`mixin_deterministic_query_list.py`、`mixin_retrieval_router_db.py`、`mixin_deep_guard_answer.py`、`mixin_answer_mainline.py`、`mixin_manifest_feature_p2.py` 只能消费 `business_frame + target_resolution + query_plan` 归一化后的 entity/project binding;禁止再让 `subject_focus / referenced_objects` 之类 coarse structured compatibility 字段决定 `project / task / signal / config / feature / doc / user` 的快答、检索或 deep guard 走向。
- `PROMPT_RAG_QUERY_SEMANTICS` 与 `mixin_core_intent.py` 现在也必须保持同一条基线:上游 query semantics 只允许产出 `query_type / object_mentions / source_policy / effective_source_policy / retrieval_domains / scope_hint / feature_focus / query_profile(needs_private_context, needs_freshness, confidence) / business_frame`;不得再把 `subject_focus` 或 `query_profile.referenced_objects` 写回运行时真源、route snapshot 或 session scope。
- `Project Operating Context` 是 non-plan `query.answer` 的统一上下文基线:`/rag/ask`、`/ai-pmo/process-text` 与 kernel ingress 至少要透传 `current_project_id / current_repo_scope / page_anchor / thread_anchor / fit_scope / decision_strategy`;`Query Route Gateway` 只能在此基础上产出单次 `execution_recipe(primary_lane / fit_brief_required / external_evidence_required / plan_handoff_mode)`,external 主链若命中 `fit_brief_required=true` 必须先补 customer-safe `fit_brief`,回答 payload 只允许继续暴露 `fit_brief / external_recommendation / analysis_packet / recommended_next_step / can_enter_plan / handoff_mode`,禁止在 presenter 或下游 helper 再靠问题文本重判 “要不要进 plan”。
- external presenter 与 payload 必须显式保留系统态 `retrieval_status` 区分:`verifier_blocked / no_relevant_results / retrieval_failed / evidence_found` 不能折叠成单一“暂无外部变化”;若 `retrieval_status != evidence_found`,必须强制 `impact_status=no_direct_impact`,并清空 `external_summary / external_impact / affected_signal_sources / external_action`。
- external recommendation 只有在 verified external evidence 与 `fit_brief.signal_source_anchors` 这类 formal current-project signal-source 锚点建立直接映射时,才允许 `impact_status=direct_match`;`current_capabilities`、feature catalog 名称或 recommendation focus 文案都不得直接触发 `direct_match`。若证据只支持背景相关性,必须显式标记 `indirect_only`,禁止冒充“已命中当前项目推荐”。
- Feishu signal pipeline 的 default capture / extraction 失败路径不得再靠 `_is_simple_signal_source_request`、项目名 regex、关键词分仓或 `_heuristic_*_fallback` 自行拍板项目/信号语义;运行时只能消费统一语义层给出的 `intent_gate / signal_intake_hint` 这类结构化 hint,若结构化提取失败则必须降级为低置信 `signal` 待确认 payload,只保留原始消息、空项目绑定和 customer-safe degraded reasoning。
- Feishu `project.create` / contextual project prefill 也不得再靠 `根据这个/上面内容/项目名/范围` 这类中文关键词、regex 或 `heuristic_title/heuristic_scope` 本地推断项目字段;`mixin_intent_gate_core.py`、`mixin_context_prefill_a.py`、`mixin_context_prefill_b.py`、`mixin_serialization.py` 必须统一消费 `_extract_project_prefill()` 返回的结构化 `suggested_name / suggested_description / suggested_scope`,字段缺失时显式待确认,禁止再从原问题或最近回答词面硬凑项目范围。
- `/rag/ask`、QA session detail 与 session state replay 对前台必须显式暴露 `route_decision / clarification_code / clarification_candidates / answer_mode / grounding_status / evidence_pack / project_operating_context / execution_recipe / fit_brief / external_recommendation / analysis_packet / handoff_mode / can_enter_plan / recommended_next_step / session_state(last_subject, pending_clarification...)`;QA session detail 必须与即时回答共用同一份 `routing_snapshot.response_payload` 归档,禁止历史回放丢失 handoff 元数据;AI Steward UI 只能消费这些结构化字段展示当前对象、来源模式、仓库/执行通道、项目画像、分析结果、外部推荐状态与下一步,禁止再从回答正文、来源标签文案或按钮文案反推 route mode。
- `analysis_packet` 属于单独的 analysis layer,而不是 runtime truth 本身:builder 只允许消费 `ProjectOperatingContext / ExecutionRecipe / fit_brief / external_recommendation / InternalContextPacket / clarification state / answer contract` 等现有结构化真源,禁止从回答正文、presenter 文案或前台状态反推 packet。当前只允许四类 typed packet:`project_fit_analysis / external_impact_analysis / internal_explain_analysis / followup_explain_analysis`;共享 envelope 固定为 `packet_version / packet_type / conclusion / focus_objects(<=2) / next_step`。其中 richer packet 字段必须优先表达对象级分析:如 `current_subject / candidate_position / rejected_position / reason_chain / blocked_reason_or_gap`,禁止再让 presenter 用泛化标签句去脑补“更适合哪层”。AdaptiveRAG 与 Feishu 若需要 richer project snapshot,必须统一经 `analysis_project_snapshot_loader.py` 补 `tasks/signals + description/summary + analysis_object_refs`,禁止各 presenter 私自查询一套、解释一套。shared snapshot loader 现已 fail-closed:没有真实结构锚点时,不再从 task/signal 标题描述推导 `fit_candidate_* / fit_rejected_* / primary_*` 关系,也不再生成 `task_signal_scores / signal_task_links` 这类 token-overlap 产物。builder 现只消费显式 object ref、精确文本绑定和唯一候选这三类非语义结构证据;signal-only 项目若缺 task,也只能退到 signal ref 或诚实降级,禁止再吐“结果出来之后的解释层 / 当前主链”这类假对象。`project_fit_analysis / external_impact_analysis` 命中 `direct_match` 时,若没有 explicit dependent task ref,就只能保留 formal signal anchor,不得再靠标题/描述 overlap 把变化硬挂到某个 task。`internal_explain` 若缺少 `target_resolution`,也只允许精确文本绑定,不得回退到 partial-name/overlap 反绑。
- `analysis_packet_builder.py` 在 sparse project-fit 场景下也不得再靠“解释层/当前主链/当前项目动作”这类占位词表决定是否降级;若 `preferred/rejected` 结构对象不存在,只能显式按“对象缺失”降级,再结合 `project_description / analysis_object_refs` 解释当前已知链路和缺口。
- `analysis_packet_builder.py` 也不得再在 runtime 用 `_looks_like_engineering_task / _looks_like_signal_placeholder / _task_presentation_hint / token-overlap / partial-name match` 这类本地 second-guess 上游对象:工程任务 generic fallback、signal-only placeholder fallback、以及 external impact 是否能落到 dependent task,只能由显式 object ref、reply-anchor 继承下来的 object binding、精确文本绑定或唯一候选这几类结构证据决定;结构证据不足时必须显式降级,不能因为词面像“前端/部署/增加信号源/摘要卡片”就私自拍板。
- Feishu QA 直出文本必须消费同一份结构化 handoff 字段,但呈现层必须先消费共享 `analysis_packet` 再允许自然化改写:`mixin_receive_routing.py` 先基于 `project_operating_context.current_project_id` 补当前项目实体快照,再调用共享 builder 产出 `analysis_packet`,之后才进入渠道级改写。自然化阶段只能围绕 packet 已选定的 `current_subject / focus_objects / candidate_position / rejected_position / reason_chain / missing_mapping(next gap)` 表达,禁止新增 packet 之外的项目实体;运行时必须同时拒绝 fixed opener、`当前项目:/外部判断:/下一步:` 标签摘要、项目实体清单平铺、blocked entity 泄漏,以及 `分析包 / analysis_packet / missing_mapping / next_step / focus_objects / reason_chain` 这类内部 packet 术语。若 shared packet、自然化输出或校验失败,必须 fail-closed 回退到 packet-based deterministic 文本;对 sparse project-fit 这类 packet,deterministic fallback 也必须转成业务中文解释,禁止把 `missing_mapping` 或“至少还缺一个业务步骤/信号源”这类内部字段原样吐给用户。`draft_pending_confirm / requirement_plan_followup / pending_manual` 这类显式模板键仍优先走 action card,且 `verifier_blocked / no_relevant_results / retrieval_failed / indirect_only` 必须保留为可区分文案,禁止重新折叠成统一空兜底句。
- Feishu QA analysis fallback 也不得再靠 `_pick_feishu_entity_by_keywords` 或 `摘要/推送/拉取/清洗` 这类任务关键词去挑对象;fallback 只能复用共享 `analysis_packet.focus_objects`、当前项目实体目录和显式 object ref 的顺序提示,结构证据不足时只能退到最小 entity-order fallback,禁止 presenter 自己再做业务语义 second-guess。
- Feishu `qa_direct` 还必须执行中文化 presentation policy:若原始 `direct_reply_text` 泄出 `Project database / signal_total / pending_signal_count / 当前盘面 / 建议动作 / External Freshness Guard` 这类英文或内部术语,呈现层必须优先回退到共享 packet 文本,并且最多只补一行中文来源说明(如 `来源:项目库`、`来源:项目库 + 外部公开资料(当前仍在校验)`);推荐外部信号源这类 recommendation ask 若已有推荐正文,则必须优先直出该推荐正文并追加同样的单行中文来源说明,禁止再落回 packet fallback 或英文来源标签。
- external recommendation ask 若命中“推荐外部信号源/外部线索/外部信号”这类 recommendation-only 场景,`ExternalAnswerPresenter` 必须先产出结构化 `SignalSourceRecommendationPacket(candidates + caveat)`,再渲染业务中文;主路径目标是给出 3 个具体候选和各自业务价值,禁止只输出“先看上游输入/再看反馈来源”这类抽象架构话术。若结构化候选带过度确定性措辞、内部术语或数量不足,运行时必须 fail-closed 回退到 customer-safe fallback candidate,而不是继续把风险文案吐给用户。
- 飞书客户可见验收基线必须看“后端最终格式化输出”而不是内部 payload:非交互 QA 看 `FeishuReceiveRoutingMixin._build_feishu_qa_direct_reply_text()` 产出的 `qa_direct` 文本;强交互 requirement / draft / pending-manual 看 `FeishuCardActionMixin._build_action_card_from_capture_result()` 产出的 action card payload。禁止只根据 `rag_result.fit_brief / external_recommendation / recommended_next_step` 是否存在就宣称飞书前台验收通过。
- unified handoff 运行时必须支持独立 rollback guard,且关闭后不需要回退 ingress/context 真源:`PMFLOW_ENABLE_UNIFIED_EXECUTION_RECIPE=0` 仅把 recipe 退化为 lane-only 合同、关闭 `fit_brief_required / offer_after_answer`;`PMFLOW_ENABLE_FIT_BRIEF_EXTERNAL_RECOMMENDATION=0` 只跳过 `fit_brief / external_recommendation` 构建,不影响 external 主检索;`PMFLOW_ENABLE_DEFAULT_PLAN_HANDOFF_RENDERING=0` 只关闭默认 `offer_after_answer` 的 `recommended_next_step` 呈现,显式 `explicit_plan_now` 锚点仍必须继续生效。
- `analysis_packet` family 也必须带独立 rollout guard:`PMFLOW_ENABLE_ANALYSIS_PACKET_FAMILY=0` 时,只允许关闭 `analysis_packet` 的 payload 暴露与 Feishu packet presenter,回退到现有 handoff truth + 旧 presenter;不得因此回退 `project_operating_context / execution_recipe / fit_brief / external_recommendation` 真源或 requirement-plan/action-card 主链。
- 网页 `query.answer` 入口的显式锚点 v1 只允许消费稳定强锚点:项目页路径里的 `project_id`,以及 URL query 中已经显式存在的 `project_id / source_chat_id`;全局浮窗与项目页入口必须原样透传这些字段到 `/rag/ask`,禁止在前端或运行时新增“猜测型 source_chat_id 推断器”。
- `统一 Project Operating Context + 三路 handoff` 的实现验收必须同时通过 `docs/superpowers/specs/2026-04-17-feishu-problem-inventory.md` 中的黄金样例与对应回归测试,不能只看 architecture contract 是否对齐。
- This work is not allowed to introduce new keyword routing, regex routing, or hard-coded semantic split helpers.
- `Query Route Gateway` 只能汇总上游显式语义、审计锚点与执行结果,不得先并行跑 internal/external 语义探针再做“strong/weak/probe_conflict”裁决。internal / external 的执行分叉必须发生在来源合同已经确定之后;若合同不确定,只能停在 `uncertain/clarify`,禁止先执行双探针再回写路由结论。
- internal `query.answer` 在 `route_mode=internal` 后必须继续经过受控内部查询主链:`rag_query_semantics -> Operation Contract -> Target Resolver -> Query DSL Plan -> InternalContextPacket -> DSL normalizer -> 白名单执行器 -> semantic facts 优先(可用时)-> bounded fallback retrieval -> answer verifier`。`Operation Contract` 只负责回答合同与对象 mention,`Target Resolver` 只负责对象仲裁;planner 只允许输出结构化计划,禁止让 LLM 直接写 SQL、决定自由 join 或直接输出未取证的内部结论。
- `InternalContextPacket` 是 internal-only 运行时单一真源,至少固定携带 `packet_version / question / scope / route_decision / operation_contract / target_resolution / query_plan / executor_summary / verifier_summary / uncertainties`。`query_semantics["operation_contract"] / ["target_resolution"] / ["query_plan"]` 只允许作为上游 scratchpad 或同请求兼容镜像,不得再被 internal executor、internal verifier 或 runtime summary 注入链路当作真源读取。
- internal 主链在真正进入 fast path / bounded executor / retrieval 前,必须先完成 `InternalContextPacket` 预检;若 packet 缺失、`operation_contract.query_type` 缺失、`target_resolution.resolution_mode=clarify` 或 `query_plan.answer_contract` 缺失,只能显式返回 `clarify / explicit_insufficient_evidence`,不得继续执行 internal fast answer、deterministic query 或 retrieval。
- `query_semantics` 对 `operation_contract / target_resolution / query_plan` 的镜像写回只允许出现在单点兼容适配层;禁止在多个 internal helper 里散落回写这些字段再互相读取,避免 packet 真源再次漂移回多真源。
- `rag_query_semantics` 的内部只读 `query_type` 基线统一收口为 `existence / count / list / status / explain / diagnose / compare / unknown`;`A/B/C`、`确认`、`退出需求模式`、`继续核实` 等协议/模式/执行动作不属于 `query_type`,必须在 ingress / followup gate 提前处理,禁止掉进 `unknown` 后再误入内部查询。
- `Query DSL Plan` 必须显式携带 `query_type / entity_type / answer_contract / filters / scope / retrieval_policy / verifier_checks`。执行层只能消费该结构化计划,不得再在下游根据“问题长相”二次拍板。
- `target_resolution.resolution_mode=clarify`、`query_plan.answer_contract` 缺失或 `InternalContextPacket` 缺关键字段时,internal 路径只能显式返回 `clarify / explicit_insufficient_evidence`,禁止掉回自由问答或靠 answer 文本倒推合同。
- `semantic_facts` 是内部查询的辅助读模型,不是业务写入真源;当事实数据可用时,内部查询必须优先查 facts,再决定是否回退到受控文本/图谱/配置检索。facts 必须带 `confidence / evidence / extract_version / tenant_id`,证据不足时禁止包装成确定性内部结论。
- `semantic_facts` 自动抽取是内部查询的必经数据基线:`project / task / signal / document / user / requirement(charter) / release / review` 八类对象的 create/update 必须统一经 ORM 提交钩子收集变更,并 upsert `ingest_events(channel=semantic_fact_extract, event_key={entity_type}:{entity_id})`;禁止在各路由、controller 或零散 service 里继续手工 enqueue。
- `semantic_facts` 的 delete/archive/disable 场景只能走 `operation=deactivate` 失活旧 active facts;extract 重跑前也必须先失活旧 facts,再写入新 facts,禁止保留脏 active 数据继续参与内部查询。
- `semantic_facts` 的 manual retry 与 backfill 必须复用同一 `semantic_fact_extract` 队列和同一 worker;默认 backfill 只补 `only_missing=true`,禁止另开旁路写表或直接同步抽取。
- answer verifier 至少要校验“问法合同、证据合同、来源合同”三件事;若发现 existence/status/compare 被答成 total count、或引用证据与执行结果不一致,必须拒绝出站并显式失败或重试,禁止静默放过。
- `query.answer` 的客户可见回答必须再经过 `Answer Presentation Policy`:运行时证据统一拆为 `customer_safe` 与 `admin_debug` 双视图。客户视图只允许消费中文化 `display_label/display_summary`,禁止直接暴露 `raw_source_label`、表名、chunk id、tool trace 或 `Project database / Semantic facts / Knowledge Graph / Feishu history` 等机器/内部术语。
- 通用行业趋势/外部品牌模型 freshness 问答,禁止把项目图谱、Feature Catalog、内部文档或用户历史冒充成“外部事实”;若命中 live external `url/http(s)` 证据,必须优先基于外部结果回答;若实时外部检索为空或不足,才允许显式返回“当前未接入实时外部数据/暂无法确认最新结论”。
- external `query.answer` 在 `route_mode=external` 后必须继续进入受控外部查询主链:`External Query Planner -> External Query Gateway -> External Provider Registry -> MCP adapter 优先 -> bounded fallback live search -> external answer verifier`。AdaptiveRAG 运行时必须通过 `backend/app/services/external_query_service/` 统一执行,external probe / freshness fetch / external route retrieval 不得再绕回直接 DuckDuckGo HTML 抓取。大模型只允许产出结构化 `ExternalQueryPlan` 与 grounded answer,不得自由联网、自由调用工具或在无证据时直接给外部事实结论。
- external `query.answer` 在 verifier 之后必须继续生成 `ExternalContextPacket`,并由 `ExternalAnswerPresenter` 负责最终回答生成;presenter 只能消费问题文本、计划摘要、经 verifier 通过的外部证据摘要与外部来源摘要,禁止重新注入 `system_snapshot / user_snapshot / project_context / 内部 context_blocks`,也不得回流 `industry_trend / external_trend` 旧 scene prompt 混答。
- “推荐外部信号源/优先关注哪几类外部输入”这类 recommendation ask 不得再按 freshness fact verification 统一拒答:只要已经绑定当前项目与 recommendation goal,就必须走 recommendation-only presenter 输出 `top-N candidates + why`,并显式标注“这是推荐,不是已验证事实”;禁止继续退回 `external_verifier_blocked / 当前不能直接推荐` 这类保守拒答模板。
- `External Query Planner` 命中“推荐外部信号源”这类 recommendation ask 时,`search_queries` 必须优先围绕 `fit_brief.signal_source_objectives / signal_source_anchors` 这类当前项目任务目标与 formal object 锚点展开;structured planner 即使返回了更抽象的 `industry best practices / external data sources` 类 query,也不得把这些项目锚点查询整组覆盖掉。这个 guard 只允许作用在执行参数层,不得反向改写 route_mode、query_kind 或 formal object binding。
- recommendation-only 外部问答的分支裁决必须继续留在统一语义规划层:`answer_control.effective_level=recommendation` 需要经 `source_policy_hint/query_semantics -> ExternalQueryPlan.interaction_level` 显式透传,`ExternalAnswerPresenter` 只能消费这个结构化层级与 recommendation goal/anchors 进入 recommendation presenter,不得再在 presenter 里靠中文 cue list、关键词仓或问句正则单独判断“这是不是推荐外部信号源”。
- `ExternalAnswerPresenter` 命中“推荐外部信号源”问法且 `impact_status != direct_match` 时,若生成答案出现百分比、相关性数值、`已确认`、`无需额外对接验证` 等高确定性措辞,必须 fail-closed 回退到保守推荐文案;保守文案也必须优先引用 `fit_brief.signal_source_objectives` 里的项目任务目标,禁止再写固定三类模板或自造系统名。
- recommendation 输出若已经生成 `SignalSourceRecommendationPacket`,就不能只把它当 prose 回复后丢掉;运行时必须同步沉出可 carry-over 的 candidate set 绑定(至少包含 `candidate_set_id / project_binding / candidate refs / materialization payload`),供后续 reply-anchor follow-up 继续复用。用户后续说“把刚才推荐的写进系统 / 把第一个加进去 / 确认入库”时,必须优先从这份结构化 candidate set 恢复对象,不得重新把上一轮自然语言推荐当成自由文本再猜一遍。
- non-plan `signal_source.onboard` 若来自 recommendation carry-over 或显式 write intent,默认只允许走 `prepare_write -> confirm_write -> execute_write` 直写链;除非用户显式要求“先出草稿”或当前线程明确处于 `plan mode`,否则禁止再默认掉回 `draft_pending_confirm / requirement draft`。一旦 signal 已 materialize 且项目关联写成功,业务结果应视为 success,后续 signal-source onboarding/manual 状态只能通过 `post_process_status / signal_source_workflow.status` 暴露,不能把整条线程重新判成 `pending_manual` 漂移出主链。
- 显式 `reply/thread` 到 recommendation reply 后的 follow-up confirm(如“确认入库”)必须优先复用上一轮 `action_contract / candidate_set_binding / candidate_refs / reply_anchor_qa_context`。若这些锚点已存在,运行时不得重新退回内部查询澄清、项目列表快答或无关系统配置问答;缺的只能是结构化对象绑定,而不是再从自由文本里重猜业务目标。
- `query_route_memories` 的 manager-only summary/list/detail 治理接口只允许做只读审计和人工排查:可以暴露 `reply_contract / probe_snapshot / query_profile / feedback_outcome` 等调试快照,但不得在线自动修改 route decision、阈值或 prompt。
- 若 `ExternalContextPacket` 内 `verified_evidence` 为空,或 verifier 未通过,外部回答必须显式返回“证据不足/需要澄清”语义;禁止为了给出完整回答而退回 legacy external trend prompt、内部检索结果或项目上下文补写结论。
- `External Query Planner` 的 fallback 只允许补齐 `search_queries / preferred_domains / location_hint / time_range_hint / result_limit` 等执行参数,不得再根据 `referenced_objects / subject_focus / needs_freshness` 在运行时把问题硬分成 `weather/news/company/market/model` 等语义类别;对象归类必须来自上游单次结构化语义或显式用户对象,若没有就保持通用 external 计划并把不确定性显式带入 verifier。
- `scripts/semantic_lint.py` 必须把上述“对象词表 / probe helper / object->query_kind 映射”视为运行时违规形态;默认扫描范围至少覆盖 `backend/app/services/ai_pmo`、`backend/app/services/adaptive_rag_service`、`backend/app/services/external_query_service`、`backend/app/services/integrations`、`backend/app/services/signal` 与 `backend/app/api/ai_pmo_api`。新增或改名的同义写法也必须纳入 lint 规则,禁止只防 `*_HINTS/*_KEYWORDS/looks_like_*` 这种旧形式。
- 涉及模型事实的聊天问答,只有用户显式询问系统配置、路由、接入状态、运行时参数或 `ai-config` 等内部对象时,才允许落入 `ai_pmo / snapshot identity / 内部模型配置` 场景;否则禁止把通用“最新/当前/模型/版本”问题内化成系统配置问答。
- 内部模型配置问题(如“我们系统当前接的是哪个模型配置”)必须优先走 `integrations(llm_engine/model_routing)` 的确定性读取链,禁止再回落到 `System Snapshot / 功能目录` 类快答。
- 用户对上一条行业/外部趋势回复的事实性纠错追问,必须优先留在聊天问答链路;若锚定上一轮 `industry_trend/external_trend`,禁止切入 `ai_pmo_correction` 裁决文风。
- 外部“最新/目前/截至现在”等 freshness 问答,只有命中显式外部来源(如 `url/http(s)` 证据)时才允许记为 grounded;仅凭项目图谱、Feature Catalog、系统快照或内部资料时,必须降级为 `insufficient_evidence` 并明确说明当前未接入实时外部数据。
- 外部来源合同必须 fail-closed:若 external source filter 过滤后为空,只能返回空 sources 或 freshness guard,禁止把 `Feishu history / doc / pmflow / graph` 等内部来源兜回 external 回答的 `来源摘要`。
- prompt context hygiene 也属于展示契约的一部分:生成式回答 prompt 的 `context_blocks` 只能喂 `display_label`,不得再把 `raw_source_label` 直接喂给模型,避免模型正文复述英文机器标签或内部术语。external answer presenter 的 prompt 也必须遵守同一规则,只允许消费 external-only 的展示字段和证据摘要。
- 外部 freshness 问答的后续一句话跟进(如“继续核实”“联网查一下”“接入外部来源继续核实”)若锚定上一轮 `insufficient_evidence + External Freshness Guard` 回复,必须优先留在 `query.answer` 问答链,并先尝试 live external 检索;只有当实时外部检索仍为空或失败时,才允许继续返回 freshness guard。只有用户显式点明系统/项目/配置等内部对象并提出接入动作时,才允许继续落入 `signal_source_flow / internal onboard / draft` 等内部执行链。
- 飞书聊天可见答案禁止泄露内部函数名、文件路径、代码行号、模块名或调试字段;prompt 护栏与出站文本清洗必须同时满足该约束。
- mixed 场景回复必须强制两段格式输出:`[回答]` 与 `[已收到需求] ...,已入库处理`。
### 3.7 Signal / Project / SSTC / Briefing
- `SignalSourceRegistry` 仅作为信号源接入/幂等内部表;用户可见的项目“信号源/信号”统一落到正式 `Signal`。
- `create_project_from_natural_language` 仅可作为 Launch draft enrichment / 内部迁移能力复用,必须支持透传 `requested_member_user_ids`;草稿确认时必须把推荐负责人并入项目创建事务。
- `POST /ai-steward/project-from-text` 已下线为 410 迁移响应;任何新建项目不得绕过 `POST /pmflow-launch/drafts -> POST /pmflow-launch/drafts/{draft_id}/confirm`,不得直接从自然语言写正式 `Project / Task / Signal`。
- AI 任务分配与执行建议必须优先使用 Execution Capability Graph:先判断 `ai_direct / ai_with_user_acceptance / ai_with_technical_review / needs_human_judgement / blocked`,再给执行或审查建议;禁止仅凭静态技能标签、编程语言标签或旧团队负载百分比硬派任务。缺 repo、执行包、测试命令、工具连接、回写证据或 reviewer 时必须返回 `blocked` / `needs_human_judgement` 或明确 warning,禁止冒充可执行或已分配成功。
- AI 分配和容量判断必须使用 Adaptive Human Capacity:每日 `suggestedBaseline` 必须由当前任务池动态生成,禁止固定深度判断/审查/验收/协调比例;总容量用有效时间判断硬上限,类型占比只用于疲劳和质量风险,不得作为固定槽位限制。旧 `UserWorkload.workload_ratio` 只可作为历史成本参考,不能直接判定可分配。负责人 override 必须先模拟、再应用,且必须包含原因、审计和过期时间;加班只增加时间预算,不清除疲劳风险、高风险密度或证据不足 warning。
- 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
- Prompt registry 现在同时承载静态 catalog、guarded runtime prompts、semantic fact prompts 与 inline discovered inventory;registry 覆盖并不等于所有调用点已经 release 化。任何新增运行时 prompt 必须先登记 registry,再按风险决定 `managed_release / guarded_release / needs_migration`,不得继续只把大段 prompt 写进业务服务后不留运营索引。
- 回复质量迭代与训练管线的原始反馈入口统一复用 `feedback_center_records / qa_records / ai_call_logs`。
- `query_route_memories` 是独立的路由审计/离线评估样本表:记录 `qa_record_id / route_mode_predicted / route_mode_effective / probe_snapshot / query_profile / feedback_outcome / question_embedding`;v1 只允许沉淀与离线评估,禁止在线自动调阈值或自发改路由策略。
- `QAFeedback` 与 `FeedbackCenterRecord` 写入后必须同步回灌对应 `query_route_memories.feedback_outcome`,便于 route precision/recall 离线评估。
- 训练/微调 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` 仅作为历史创建结果区的兼容展示字段;项目看板与 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 主链按 `CONTROL_PLANE_ROUTING_ENABLED` 走 PMFlow 本地路由层 路由规则;普通请求超时以 `LLM_REQUEST_TIMEOUT` 环境变量为默认,保护型结构化调用以 Function Runtime Profile / 场景策略写入的 `provider_timeout_seconds` 为准。
- 路由配置唯一真源固定为 `backend/.control_plane/pmflow-routing-rules.json`。
- World Model 静态层已接入 Redis 缓存(`wm:static:{tenant_id}:{project_id}`,TTL 600s),写操作后主动 invalidate,动态层不缓存。
- 本地 `ollama` 的聊天/生成模型仍只允许知识库问答链路使用,且必须通过 `llm_engine.settings.enable_local_kb_qa` 显式开启;但 embedding 允许独立回退到本机 `OLLAMA_HOST + OLLAMA_EMBED_MODEL`(默认 `nomic-embed-text:latest`)获取真实向量。
- embedding 生成失败时必须显式返回空向量,禁止再回退伪向量或哈希向量冒充“可检索”。
- IT 五轮 requirement plan 现以 `MountedDraftWorkspace.active_work_item_id + latest_*_message_id` 锚定当前 active draft;历史未绑定这些字段的旧草稿不会自动认领。
- semantic facts 治理页与管理接口(overview / objects / detail / reextract / backfill)只对 `BOSS/ADMIN` 开放;非管理员不得看到队列、facts 内容或手动治理操作入口。
- semantic facts 自动抽取、治理页和 internal existence/facts-first 查询都不以前置向量库为依赖;向量检索可作为 bounded fallback,但不得取代 facts 基线。
- 当前 repo 已接入两类可复用 backend 外部检索 bridge:`microsoft_learn` 通过 `backend/app/services/mcp_config/runtime.py` 以 `streamable_http` 由 PMFlow 后端直连;`duckduckgo` 通过同文件内的 `backend_adapter` runtime 由 PMFlow 后端直接执行搜索。其余模板若无 backend-direct runtime,仍必须显式降到 bounded fallback live search,禁止静默冒充 MCP 成功。
- MCP 模板接入中心当前区分两类状态:后端直连模板的 runtime probe 只代表 PMFlow backend 对远程 MCP 或内建 backend runtime 的可达性;Local Bridge 模板的“已确认”仅表示用户手动确认客户本机已承载,不代表后端完成宿主机探活,也不负责探测客户真实文件系统或本机 host 进程状态。
## 5. 维护建议
- 想看“必须立即遵守的规则”:先看 `AGENTS.md`
- 想看“当前架构说明和关键入口”:看 `CLAUDE.md`
- 想看“长运行边界、守门规则和已知环境假设”:看本文档