06 · 知识维护与治理 · 落地方案
06 · 知识维护与治理 · 落地方案
对应蓝图 §7。本文解决:知识入库后如何保持新鲜、一致、无冗余?
状态:草案(M2.4 / M2.5 / M3.1 / M3.2 / M4.4 / M5.2 / M5.3 / M5.4 待确认)
前置依赖:04-知识存储(元数据 Schema 与
flags字段)· 03-知识审核(owner_group与 Steward 派生)关联文档:02-知识验证(冲突检测写入
flags)· 05-知识检索与引用(审计日志作为边际价值输入)· 07-评测与反馈闭环(同类问题复发率)· 08-约束执行(Sunset 期 Hook 阻断)
1. 定位与边界
维护与治理覆盖知识"入库之后、下线之前"的全部动作:版本裁决、漂移检测、影响分析、Sunset 生命周期、边际价值评估。它不解决"知识如何产生"(→ 01)或"知识如何被使用"(→ 05),只解决"知识如何保持可信"。
与 03 的分工:03 §3.1 定义"谁负责"(Owner 团队制 + Steward 派生规则),本文定义"做什么、何时做、做到什么程度"。
角色归属更正:原表述称 03 定义了「Owner / Steward / 园艺」三个角色,实际 03 全文没有「知识园艺」这一角色。该角色的职责定义在本文 §3.5,其在四类分工中的归属见 09 §2.4。此处保留说明是因为角色清单不一致会直接影响 CODEOWNERS 与告警接收人配置。
与 02 的分工:02 在 MR 合并前拦截格式与引用错误(单次),本文在 MR 合并后持续监控知识是否仍然正确(连续)。
2. 核心设计决策
2.1 版本裁决:七条规则 + 五级权威源
蓝图 §7.1 给出七条裁决顺序,不能简化为"按修改时间"。落地为 scripts/version-arbiter.py,输入两条主张,输出胜方与理由。
依据与置信度:本节与 §2.2 的语义过滤信号清单、§2.4 的边际价值量纲统一,在蓝图附录中均标注为自拟 / 方向性依据——即它们是工程推导结论,没有外部标准或公开实测数据支撑。落地时须按 09 §7 的校准计划实测后再固化,不得在评审中把它们表述为业界通行做法。
七条裁决顺序(按序执行,命中即停):
| 序号 | 裁决维度 | 判定方式 | 数据来源 |
|---|---|---|---|
| 1 | 适用系统/服务/环境/版本是否匹配 | 比对 frontmatter applies_to 与问题上下文 | 问题上下文 + frontmatter |
| 2 | 是否经过正式审核 | status == active 且 review_state == approved | frontmatter |
| 3 | 是否已发布或生效 | effective_at <= now() | frontmatter |
| 4 | 当前时间是否在有效区间 | effective_at <= now() < expires_at | frontmatter |
| 5 | 是否被 supersedes 指向的新版本替代 | 查反向引用 | frontmatter |
| 6 | 权威源等级是否更高 | 按 T1–T5 等级表(下表) | source_type 字段 |
| 7 | 无法裁决 | 标记 flags: [conflicted],不允许模型自选 | 写入 flags |
权威源等级表(第 6 条使用):
| 等级 | 类型 | 示例 |
|---|---|---|
| T1 | 机器可校验的契约与 Schema | OpenAPI / Proto / IDL / Migration |
| T2 | 运行时事实 | 发布平台状态、配置中心实际生效值、IAM 实际授权 |
| T3 | 已审批的知识条目与 ADR | status: active 的 docs/knowledge/**、已合并 ADR |
| T4 | 设计文档与评审结论 | Wiki、Confluence、设计评审纪要 |
| T5 | 沟通记录 | IM、会议纪要、MR 评论 |
关键约束:T1/T2 与 T3–T5 冲突时,以 T1/T2 为准并立即对低等级条目标记 drift_detected;同级冲突才进入 conflicted 流程。T5 不得单独作为确定性答案来源(与 05 §8 拒答规则一致)。
2.2 漂移检测:语义过滤 + 告警聚合
直接按"源文件是否有新提交"判定漂移会产生 Owner 无法处理的告警量(格式化、注释改动、无关重构都会触发),最终导致告警被集体忽略——治理系统最典型的失效方式。
两级判定:
# scripts/drift-check.py
# 一次性建立 路径 → 最新 commit 的反向映射,避免逐条调 git
commit_map = parse( git log --name-only --pretty=format:%H -- {watched_paths} )
for entry in knowledge_entries(status == active):
path = resolve(entry.source_uri)
latest = commit_map[path]
if latest == entry.source_revision:
continue # 未漂移
# 零级:源文件已被删除 → 最高优先级,不走语义过滤
# 必须在 diff 之前判定:文件删除后 git diff rev..latest -- path 返回空,
# 语义过滤会把空 hunk 判为「无关变更」并静默推进 auto_rebase_to,
# 导致「源已删除」被记录为「已是最新」,删除残留率因此不可能归零。
if not exists_at(latest, path):
report_drift(entry, kind = 'source_deleted', priority = 'high')
continue
# 一级:源文件确有变更 → 记录候选,不立即告警
changed_hunks = git diff entry.source_revision..latest -- {path}
# 二级:只有命中语义相关变更才升级为需处理漂移
if matches_semantic_filter(changed_hunks, entry.knowledge_type):
entry.flags += [drift_detected]
entry.flagged_at = now()
enqueue_alert(entry.owner_group, aggregate = daily_digest)
else:
entry.auto_rebase_to = latest # 无关变更:静默推进基线语义相关变更信号清单(按知识类型):
| 知识类型 | 判定为语义相关变更的信号 |
|---|---|
| Contract(HTTP/RPC 接口) | 路径、方法、请求/响应 Schema、字段必填性、错误码变化 |
| Procedure(操作步骤) | 函数签名、命令、配置项名称或默认值变化 |
| Policy(架构/业务规则) | 规则涉及的类、注解、状态机分支变化 |
| Concept(设计背景) | 仅当被引用的代码位置整体删除或迁移时才判定 |
| 全部类型 | 源文件被删除 → 由 §2.2 伪码的零级分支直接判定为 source_deleted,升级为高优先级,不进入语义过滤(否则空 diff 会被判为无关变更) |
明确不判定为漂移:纯空白与换行变化、Markdown 格式化、注释文字调整、日志文案修改、与知识主张无关的代码块变更。
告警聚合:按 owner_group 做每日摘要(daily digest),单个团队单日告警条数超过阈值时合并为一条汇总通知,不逐条推送。
2.3 flags 字段独立于 status
status 枚举固定为 draft | active | deprecated | revoked(04 §3)。漂移与过期是叠加在 status 之上的独立标记,写入 flags 数组:
flags: [] # 取值:drift_detected | verification_overdue | owner_missing | steward_missing | conflicted
flagged_at: # ISO 8601,最近一次打标时间(CI 写入,人工不得手改)一条知识可以同时是 status: active 且 flags: [drift_detected, verification_overdue]——"仍然生效但已待复核"正是治理最需要表达的复合状态。
owner_missing 与 steward_missing 必须是两个独立标记,因为它们是两种检查、两个时机、两种处置:
| 标记 | 检查内容 | 时机 | 处置 | 载体 |
|---|---|---|---|---|
owner_missing | owner_group 在 GitLab 中不存在 | MR CI(同步) | Error,阻断合并——新增孤儿知识率 = 0 的唯一机制载体 | 03 §7 S3 |
steward_missing | owner_group 存在,但派生不出 Steward(组内无满足资历条件的成员) | 每日定时扫描 | 告警 + 由 owner_group 的 Owner 角色成员认领 | 03 §6.2 |
原设计用同一个 owner_missing 承载两者,会把「组织调整窗口期的 Steward 空缺」升级为阻断无关 MR 合并的 Error——团队重命名或成员批量变动时,整个仓库的知识 MR 会被集体卡住。
机制成本须写进方案:owner_group 存在性校验依赖 GET /groups/:id,需要读 API 的 Token 与配额;组数多时应缓存(建议 TTL 1 小时)并处理 GitLab 可见性限制(私有组对 Token 不可见时会误判为「不存在」,须区分 404 与 403)。
2.4 边际价值:统一量纲到人时/年
蓝图 §7.7 指出原公式"价值分 − 成本分"量纲不同不可计算。改为统一量纲到"人时/年":
年度价值(人时/年)
= 年检索命中次数 × 单次命中节省的人时 × 命中有效率
年检索命中次数 ← 05 §9.3 审计日志的 retrieved_chunks
单次命中节省的人时 ← 实测:无知识库 vs 有知识库的定位耗时差
命中有效率 ← 命中后未被点踩、且未触发返工的比例(07 §2.4)
年度成本(人时/年)
= 年更新次数 × 单次更新人工耗时
+ 年复核次数 × 单次复核人工耗时
年更新次数 ← git log 统计该条目的实际提交次数
年复核次数 ← 由 04 §3.5 的分级复核周期决定
单次耗时 ← 实测抽样
边际价值 = 年度价值 − 年度成本 (单位:人时/年)模块关键度不进公式,而作为否决项(等级量无法与人时相乘):
两个维度必须先有可执行定义,否则下表不可判定(§6 已把「模块关键度的分级标准」列为待实测项,但下表已经在用它做否决):
- 模块关键度:建议由
docs/knowledge/**的目录级_index.yaml显式声明criticality: high | normal,不做事后推断。理由是关键度是业务判断,无法从代码指标推导;由 Owner 在建立路由地图时一次性声明,成本最低且可审计。未声明的目录默认normal。 - 模块状态:建议用可计算代理量——该模块
source_uri指向的目录在最近 N 个自然月内的非 bot 提交数。活跃= N 月内有提交;活跃但低频= 有提交但低于阈值;无活跃开发= 无提交;模块已废弃= 目录已删除或在_index.yaml中标记archived。N 与阈值属待实测项。
| 边际价值 | 模块关键度 | 模块状态 | 决策 |
|---|---|---|---|
| 正 | 任意 | 活跃 | 正常维护 |
| 正 | 任意 | 活跃但低频 | 保留,按 04 §3.5 降低复核频率 |
| 正 | 高 | 无活跃开发 | 保留,标记为低频关键知识 |
| 正 | 低 | 无活跃开发 | 保留,延长复核周期至上限 |
| 负 | 高 | 无活跃开发 | 不归档,转人工评审(关键度否决) |
| 负 | 低 | 无活跃开发 | 连续观察期满后归档 |
| 负 | 任意 | 模块已废弃 | 立即标记 deprecated,进入 Sunset |
三重防误删保护(缺一不可):
- 豁免类别:安全、合规、资金、权限相关知识不参与边际价值评估,永不自动归档。
- 关键度否决:边际价值为负但模块关键度高时不归档。
- 人工审核:任何归档动作必须经 Owner 审核,系统只产出建议清单。
观察期不可省略:边际价值基于历史统计,而知识价值有滞后性——一条事故复盘知识可能一年只被检索一次,但那一次避免的是重大故障。观察期内若命中一次高价值场景(如事故归因引用),统计窗口应重置。
本模型的三个输入目前都依赖尚未建成的能力,实施前必须逐项确认前置条件:
| 输入 | 依赖 | 当前状态 | 前置条件 |
|---|---|---|---|
| 年检索命中次数 | 05 §9.3 审计日志的 retrieved_chunks | 字段已定义 | 审计日志保留期必须 ≥ 观察期长度。若 M4.4 取 180 天而合规确定的保留期短于 180 天,边际价值在数学上无法计算(RT1.4 因此不只是合规问题,也是本模型的硬约束) |
| 命中有效率 | 「命中后未被点踩、且未触发返工」 | ❌ 无数据源 | 05 §9.3 的审计字段中没有点踩 / 返工 / 人工介入任何一项,07 §2.3 已把它们标注为需新增埋点。埋点落地前,命中有效率只能取 1.0(等于不折算),须在报表中显式标注该假设 |
| 年更新次数 | git log 统计 | 可计算 | 须排除 bot 提交(见 §3.5 的自证循环风险) |
「单次命中节省的人时」是两组对照实测,需要专门安排无知识库 / 有知识库的对照任务,成本不低且样本量小时方差极大。在该值实测出来之前,边际价值的绝对数值没有意义,只能用同一批条目的相对排序做归档建议——这一点必须写进 §3.5 的清单说明,否则 Owner 会把 -2.5 人时/年 当作可信数字。
2.5 Sunset 生命周期
接口废弃时进入 deprecated 状态,frontmatter 增量字段:
status: deprecated
deprecated_at: # ISO 8601
replacement_api: # 替代接口 URI
migration_guide: # 迁移指南链接
sunset_at: # 计划下线日期
known_consumers: # 已知调用方清单
owner_group: # 责任团队Schema 归属:上述 6 个增量字段(
deprecated_at/replacement_api/migration_guide/sunset_at/known_consumers/auto_rebase_to)已统一登记到 04 §3.7 字段字典。字段定义只在使用方文档中出现会造成 Schema 双头——04 自称是元数据 Schema 的唯一权威,若 Sunset 字段不在其中,索引 Pipeline 与 CI 校验都无法据 04 生成完整校验规则。
known_consumers的数据来源必须明确:它不能靠人工维护(必然过期)。P1 阶段由 CODEOWNERS 反查 + 人工确认填充;P3 关系图谱(§3.4)上线后改为从consumes边自动派生,人工填写值仅作兜底。
四条控制要求:
- 新代码调用废弃接口时阻断(通过 08 §3.1 的 Hook 校验)。
- 存量调用按
sunset_at时间告警。 - 文档和知识条目同步标记废弃。
- 删除前确认调用方和引用清零。
3. 实施细节
3.1 事件同步与对账(蓝图 §7.2)
三种机制互补:
| 机制 | 触发时机 | 作用 |
|---|---|---|
| 事件同步 | 实时(Webhook) | 捕获 Git / Wiki / MR / 权限变化 |
| 定时对账 | 每日凌晨 | 比较 source_revision 和 content_hash,补偿丢失事件 |
| 合并门禁 | MR 合并前 | 检查受影响知识是否同步更新(02 §4.1 已实现) |
3.2 契约变更触发知识检查(蓝图 §7.3)
落地工具链:
| 变更类型 | 检测工具 | 触发条件 |
|---|---|---|
| OpenAPI / Proto | openapi-diff / buf breaking | **/openapi.yaml 或 **/*.proto 变更 |
| Migration | 社区版能力:Flyway validate(仅比对已应用迁移的 name / type / checksum)、Liquibase checksum(仅检测 changeset 文件是否被改)。真实 Schema 漂移检测:Flyway check -drift(Teams / Pipelines 付费;Community 版仅 PostgreSQL 预览)、Liquibase diff / diffChangeLog。migrate -dryRun 同为付费能力 | db/migration/**/*.sql 变更 |
| 配置 | 自定义 diff 脚本 | application*.yml 或 @ConfigurationProperties 类变更 |
| 公共接口 | japicmp / 自研 ABI 分析 | api/ 包下类变更 |
| 规则 | Semgrep / ArchUnit 测试 | .semgrep.yml 或 *Test.java 变更 |
工具链选型的许可证前提:上表「检测工具」列区分了社区版与付费能力,因为两者的检测范围完全不同——
validate/ checksum 只能发现「迁移脚本文件被人改过」,无法发现「数据库实际结构与迁移脚本推导出的结构不一致」(即真实漂移)。若目标是后者,必须先确认 Flyway Teams 或 Liquibase 商业许可已到位,否则该行的检测能力不成立。无许可时的替代方案是:以迁移脚本为唯一真源,禁止手工 DDL,并用information_schema快照做每日对账(自研,成本低但需自行维护比对规则)。
3.3 漂移检测 CI 定时任务
GitLab CI 的 job 定义中不存在 schedule: 关键字;定时流水线由 UI(Build → Pipeline schedules)或 API 配置 cron 表达式,YAML 里只能通过 $CI_PIPELINE_SOURCE == "schedule" 判断当前是否为定时触发。
# .gitlab-ci.yml
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
knowledge-drift-check:
stage: validate
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"' # cron "0 2 * * *" 在 Pipeline schedules 上配置
script:
- python3 scripts/drift-check.py --notify --aggregate=daily
artifacts:
paths:
- drift-report.json
expire_in: 1 week
artifacts: reports:没有drift这个子键。其合法子键为固定枚举:accessibility/annotations/api_fuzzing/browser_performance/codequality/container_scanning/coverage_report/coverage_fuzzing/cyclonedx/dast/dependency_scanning/dotenv/junit/load_performance/metrics/requirements/sarif/sast/secret_detection/terraform。写drift:会在 CI lint 阶段直接报错,Job 无法创建。本节开头刚好指出了同类的schedule:错误,此处属同一类失误。若需要在 MR 页面可视化漂移结果,可用的合法路径是
reports: annotations:(把漂移项渲染为行内批注)或reports: dotenv:(把摘要作为变量传递给下游 Job);仅归档报告文件则用上面的artifacts: paths:。
3.4 影响分析:三源融合(蓝图 §7.5)
核心关系 kind(自定义扩展 Backstage):
kind 归属说明(已更正):Backstage Software Catalog 的原生 kind 只有 9 个——Component、API、System、Domain、Resource、Location、Group、User、Template。
| 上图节点 | 是否为原生 kind | 正确建模方式 |
|---|---|---|
API / System / Domain | ✅ 是 | 直接使用 |
Service | ❌ 不是 | 建模为 Component,spec.type: service |
Table | ❌ 不是 | 建模为 Resource,spec.type: database(或 table) |
Owner | ❌ 不是 | 用 Group / User 表达,通过 spec.owner 关联,不新建 kind |
CodeSymbol / Config / Feature / Document / Policy / Module / Asset / Job | ❌ 不是 | 自定义 kind,须走 Backstage 的模型扩展机制注册 |
自定义 kind 的代价必须写进选型:Backstage 的核心插件(Catalog 页面、依赖图、TechDocs、Scaffolder 模板)只理解原生 kind,自定义 kind 在这些插件中不会被识别,需要自行开发前端展示与关系渲染。因此 M3.2「A. Backstage Catalog / B. 自研图数据库」的真实取舍不是「复用 vs 自建」,而是「复用原生 kind 的表达力 + 为自定义 kind 自建插件」vs「全自建」。
自定义 kind 一旦注册,必须固化 Schema 版本,不允许在关系图中隐式新增字段。
owner_group 格式转换:frontmatter 使用简写形式(如 ocp/backend),对接 Backstage Catalog 时由索引 Pipeline 转换为 {kind}:{namespace}/{name}(如 group:default/ocp-backend),两者不得混用。
3.5 知识园艺 Agent
职责:周期扫描孤儿/过期/低边际价值条目,产出待处理清单。
运行频率:每周一次(CI 定时任务)。
输出:
# reports/gardening/YYYY-MM-DD.yaml
# 每个条目均须带 first_flagged_at 与 report_count,用于区分「本周新增」与「历史未处理」
orphan_entries: # owner_missing:owner_group 在 GitLab 中不存在
- knowledge_id: K001
reason: owner_group 在 GitLab 中已不存在
first_flagged_at: 2026-09-01
report_count: 7
steward_missing_entries: # steward_missing:组存在但派生不出 Steward
- knowledge_id: K004
reason: owner_group 内无满足资历条件的成员
first_flagged_at: 2026-10-15
report_count: 1
drift_entries: # drift_detected:源已变更且命中语义过滤
- knowledge_id: K005
days_since_flagged: 6
source_deleted: false # true 时为高优先级(§2.2 零级分支)
conflict_entries: # conflicted:版本裁决第 7 条命中
- knowledge_id: K006
days_since_flagged: 4
arbitrating_authority: T2
expired_entries: # verification_overdue:超过复核周期仍未复核
- knowledge_id: K002
days_overdue: 15
low_value_entries: # 边际价值为负且不在豁免类别
- knowledge_id: K003
marginal_value: -2.5 # 人时/年
observation_days: 180 # 已连续观察天数。示例,非规范值——观察期长度由 §5.2 M4.4 决策、按 §6 实测校准
suggested_actions:
- knowledge_id: K001
action: notify_steward
- knowledge_id: K002
action: notify_owner
- knowledge_id: K003
action: notify_owner_and_steward关键约束:园艺 Agent 不得有自动删除权(蓝图 §7.7.3 三重防误删),只产出建议清单,由 Owner 与 Steward 人工决策。
周报必须覆盖全部 5 个 flags 取值(§2.3),否则治理清单长期漏掉两类最高风险的条目:
flags 取值 | 是否进周报 | 对应清单 | SLA | 逾期升级 |
|---|---|---|---|---|
owner_missing | 原设计已覆盖 | orphan_entries | 5 个工作日 | → owner_group 的上级 Group Owner |
steward_missing | 原设计已覆盖(混在 orphan 里,须拆开) | orphan_entries 独立小节 | 5 个工作日 | → 同上 |
verification_overdue | 原设计已覆盖 | expired_entries | 按 04 §3.5 分级周期 | → Steward |
drift_detected | ❌ 原设计缺失 | drift_entries | 5 天(§4「漂移未处理天数」) | → Owner + Steward |
conflicted | ❌ 原设计缺失 | conflict_entries | 3 天(§4「冲突未决时长」) | → 按蓝图 §7.1 权威源等级裁决 |
去重与幂等:周报是周期产物,同一条目会连续多周出现。必须记录 first_flagged_at 与 report_count,并在清单中区分「本周新增」与「历史未处理」——否则 Owner 每周收到同一份长清单,第三周起就会整体忽略,这正是 §2.2 开头指出的治理系统典型失效方式。
low_value_entries 的机器自证风险:若 §2.5 的 auto_rebase_to 由园艺 Agent 自身提交,这些机器提交会被 git log 统计为「年更新次数」,从而抬高该条目的年度成本、压低边际价值,形成「园艺 Agent 越勤快、越多条目被判为低价值」的自证循环。规避方式:成本项的年更新次数统计排除 bot 账号提交(按 author_email 过滤)。
3.6 实施步骤
| 步骤 | 优先级 | 内容 | 产出物 | 前置条件 |
|---|---|---|---|---|
| S1 | P0 | owner_group 存在性校验(MR CI,Error 级) | knowledge-lint.py --check-owner-group | 03 §7 S3;GitLab 读 API Token 已配置 |
| S2 | P0 | flags 字段 Schema 与写入权限约定 | 04 §3.7 字段字典登记 | M2.3 已确认(flags 独立于 status) |
| S3 | P1 | version-arbiter.py 七条裁决 | 脚本 + 裁决理由输出 | 02 §4.4 受控谓词已定义;source_type 已采集 |
| S4 | P1 | drift-check.py 语义过滤 + 删除零级分支 | 脚本 + daily digest | S2;knowledge_type 已作为 P0 必填字段采集 |
| S5 | P1 | Pipeline Schedule 配置(cron 0 2 * * *) | .gitlab-ci.yml + schedule 实体 | S4;M3.1 决策 |
| S6 | P1 | 契约变更检测工具链接入 | openapi-diff / buf breaking / Migration 检测 | 许可证确认(见 §3.2 注) |
| S7 | P2 | 边际价值统计 + 处置建议清单 | 园艺周报(覆盖 5 个 flags) | 05 §9.3 审计保留期 ≥ 观察期;07 埋点落地 |
| S8 | P2 | Sunset 生命周期自动化 | sunset_at 告警 + M5.4 的 MR 发起 | M5.2 / M5.3 / M5.4 决策 |
| S9 | P3 | 影响分析三源融合 + 关系图谱 | Backstage Catalog 接入 | M3.2 决策;LD9 图谱建模归属决策(09 §6.2) |
顺序约束:S1 必须在任何知识条目合并前就位,否则「新增孤儿知识率 = 0」这项 P0 硬门禁没有载体(09 §3.1 已把它列为 P0 建设项)。S7 依赖 07 的反馈埋点,属跨文档依赖,埋点未落地前不得启动边际价值评估——否则会用「命中有效率 = 1.0」的假设产出归档建议,直接导致误删。
4. 度量指标
| 指标 | 计算方式 | 目标 | 性质 |
|---|---|---|---|
| 过期知识率 | 超过复核时间仍为 Active 的比例 | ≤ 10% | 阈值待实测 |
| 新增孤儿知识率 | 本次 MR 引入的 owner_group 无效条目比例 | = 0 | 机制保证(CI 校验 owner_group 在 GitLab 中存在,Error 级阻断合并) |
| 孤儿检出率 | 每日扫描检出的孤儿数 / 实际孤儿数 | 100% | 机制保证(扫描覆盖全部 active 条目,可脚本判定) |
| 存量孤儿收敛速度 | 存量孤儿条目数随时间的变化 | 趋势下降 | 趋势指标。原「孤儿知识率 = 0 / 机制保证」是标注拔高:机制只能保证「孤儿必被检出并标记 owner_missing」,消除依赖是否有团队认领(03 §6 离职资产转移),不是机制能强制成立的量 |
| 漂移未处理天数 | drift_detected 到 Owner 处理的平均天数 | ≤ 5 天 | 阈值待实测 |
| 冲突未决时长 | 冲突知识平均解决时间 | ≤ 3 天 | 阈值待实测 |
| 同步 P95 时延 | 源变更到新版本可检索的时间 | ≤ 24 小时 | 阈值待实测 |
| 删除残留率 | 源删除后仍能召回的比例 | = 0 | 阈值待实测(降级理由见下) |
为什么本项不能标「机制保证」:机制保证的定义是「由设计机制强制成立、可被脚本直接判定」。但 (a) M5.3「物理删除 vs 保留 tombstone」仍是待确认决策,Tombstone 机制在本文与 04 中均无任何设计;(b) §2.2 的漂移伪码只能检测源文件「变更」——
git log --name-only对已删除路径同样产生记录,但随后的git diff rev..latest -- path返回空,matches_semantic_filter拿到空 hunk 会判为「无关变更」并静默推进auto_rebase_to,结果是源文件被删除后知识条目不仅不告警,反而被自动标记为最新;(c) 索引侧无删除对账。三条缺口任一存在都不成立,故降级。补齐路径见 §2.2 的删除判定分支与 §5.2 M5.3。
5. 决策点清单
5.1 已确认决策
| 编号 | 决策点 | 选定方案 | 依据 |
|---|---|---|---|
| M1.1 | 版本裁决是否按修改时间 | 否,按七条规则顺序裁决 | 蓝图 §7.1 |
| M1.2 | 权威源是否分级 | 是,T1–T5 五级 | 蓝图 §7.1 |
| M1.3 | T1/T2 与 T3–T5 冲突时以谁为准 | T1/T2 为准,低等级立即标记 drift_detected | 蓝图 §7.1 |
| M2.1 | 漂移检测是否按源文件提交判定 | 否,需语义过滤,避免告警洪水 | 蓝图 §7.4.2 |
| M2.2 | 漂移告警是否逐条推送 | 否,按 owner_group 做 daily digest | 蓝图 §7.4.2 |
| M2.3 | flags 是否写入 status 字段 | 否,独立 flags 数组,不污染 status | 蓝图 §7.4.1 |
| M4.1 | 边际价值是否统一量纲 | 是,统一到人时/年 | 蓝图 §7.7.2 |
| M4.2 | 模块关键度是否进公式 | 否,作为否决项 | 蓝图 §7.7.3 |
| M4.3 | 安全/合规/资金/权限知识是否参与边际价值评估 | 否,永不自动归档 | 蓝图 §7.7.3 |
| M5.1 | Sunset 是否需要新增状态值 | 否,复用既有 status: deprecated(04 §3 的枚举已含该值),只增加 §2.5 的 6 个增量字段 | 蓝图 §7.6 |
5.2 待确认决策
| 编号 | 决策点 | 候选方案 | 建议 |
|---|---|---|---|
| M2.4 | 语义过滤的信号清单如何维护 | A. 硬编码在脚本 / B. 配置文件 + 热更新 | B,按知识类型配置 |
| M2.5 | 告警聚合阈值如何设定 | A. 单团队单日 ≥ 5 条合并 / B. ≥ 10 条合并 | 首轮实测后校准 |
| M3.1 | 漂移检测 CI 定时任务的执行时间 | A. 每日凌晨 2 点 / B. 每日上午 9 点 | A,避开工作高峰 |
| M3.2 | 影响分析的关系图存储 | A. Backstage Catalog / B. 自研图数据库 | A,复用现有基础设施 |
| M4.4 | 边际价值观察期长度 | A. 90 天 / B. 180 天 | B(初始建议值,非规范值)。§6 已把「边际价值观察期长度」列为待实测项,两处口径必须一致:B 只作为首轮起点,实测后按 §6 校准。示例 YAML 中的 observation_days 已加注「示例,非规范值」 |
| M5.2 | Sunset 阶段存量调用的告警频率 | A. 每周 / B. 每日 | A,避免告警疲劳 |
| M5.3 | Sunset 完成后知识条目是否物理删除 | A. 物理删除 / B. 保留为 tombstone | B,保留引用完整性。选 B 则必须补 Tombstone 设计(当前全文无设计):tombstone 条目的 frontmatter 形态、是否进索引(应不进,但须保留 chunk_ref 可解析)、保留期、以及 §4「删除残留率」的判定脚本如何区分「tombstone 命中」与「真残留」 |
| M5.4 | sunset_at 到期后由谁推进 deprecated → revoked | A. CI 定时任务自动推进 / B. CI 只发起 MR,由 Owner 审批后推进 | B。revoked 不可逆且直接导致召回消失(§3.2 关键约束),自动推进等于把不可逆动作交给无人工闸门的定时任务;配 M5.2 的到期前告警即可 |
6. 待实测项
- 语义相关变更的信号清单(按知识类型)
- 告警聚合阈值
- 每日摘要的推送时间
- 单次命中节省的人时(两组对照实测,季度复测)
- 命中有效率
- 单次更新与复核耗时
- 边际价值观察期长度
- 模块关键度的分级标准
7. 与其他文档的接口
| 接口方 | 接口内容 | 方向 |
|---|---|---|
| 02 知识验证 | 冲突检测结果写入 flags: [conflicted] | 02 → 本文 |
| 03 知识审核 | Owner 团队接收漂移告警并处理 | 本文 → 03 |
| 04 知识存储 | flags 字段写入 frontmatter;status: deprecated 进入 Sunset | 本文 → 04 |
| 05 检索与引用 | 审计日志的 retrieved_chunks 作为边际价值计算的输入 | 05 → 本文 |
| 07 评测与反馈 | 同类问题复发率作为边际价值评估的辅助信号 | 07 → 本文 |
| 08 约束执行 | Sunset 阶段新代码调用废弃接口时由 Hook 阻断 | 本文 → 08 |