dsh-data-domain-knowledge 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +360 -0
- package/cordis.patch.yml +410 -0
- package/eval/README.md +76 -0
- package/eval/evaluate-retrieval.mjs +121 -0
- package/eval/queries.example.jsonl +2 -0
- package/lib/client.js +111415 -0
- package/lib/types/config-schema.d.ts +35 -0
- package/lib/types/config-schema.d.ts.map +1 -0
- package/lib/types/config-schema.js +34 -0
- package/lib/types/config-schema.js.map +1 -0
- package/lib/types/convert/core-loader.d.ts +32 -0
- package/lib/types/convert/core-loader.d.ts.map +1 -0
- package/lib/types/convert/core-loader.js +60 -0
- package/lib/types/convert/core-loader.js.map +1 -0
- package/lib/types/convert/host.d.ts +88 -0
- package/lib/types/convert/host.d.ts.map +1 -0
- package/lib/types/convert/host.js +479 -0
- package/lib/types/convert/host.js.map +1 -0
- package/lib/types/convert/ingest.d.ts +125 -0
- package/lib/types/convert/ingest.d.ts.map +1 -0
- package/lib/types/convert/ingest.js +228 -0
- package/lib/types/convert/ingest.js.map +1 -0
- package/lib/types/convert/settings-schema.d.ts +18 -0
- package/lib/types/convert/settings-schema.d.ts.map +1 -0
- package/lib/types/convert/settings-schema.js +26 -0
- package/lib/types/convert/settings-schema.js.map +1 -0
- package/lib/types/convert/types.d.ts +46 -0
- package/lib/types/convert/types.d.ts.map +1 -0
- package/lib/types/convert/types.js +41 -0
- package/lib/types/convert/types.js.map +1 -0
- package/lib/types/diagnosis/cards.d.ts +71 -0
- package/lib/types/diagnosis/cards.d.ts.map +1 -0
- package/lib/types/diagnosis/cards.js +482 -0
- package/lib/types/diagnosis/cards.js.map +1 -0
- package/lib/types/diagnosis/problem-classes.d.ts +51 -0
- package/lib/types/diagnosis/problem-classes.d.ts.map +1 -0
- package/lib/types/diagnosis/problem-classes.js +66 -0
- package/lib/types/diagnosis/problem-classes.js.map +1 -0
- package/lib/types/diagnosis/schema.d.ts +65 -0
- package/lib/types/diagnosis/schema.d.ts.map +1 -0
- package/lib/types/diagnosis/schema.js +208 -0
- package/lib/types/diagnosis/schema.js.map +1 -0
- package/lib/types/diagnosis/seed-source.d.ts +20 -0
- package/lib/types/diagnosis/seed-source.d.ts.map +1 -0
- package/lib/types/diagnosis/seed-source.js +96 -0
- package/lib/types/diagnosis/seed-source.js.map +1 -0
- package/lib/types/diagnosis/seed.d.ts +50 -0
- package/lib/types/diagnosis/seed.d.ts.map +1 -0
- package/lib/types/diagnosis/seed.js +242 -0
- package/lib/types/diagnosis/seed.js.map +1 -0
- package/lib/types/diagnosis/store.d.ts +81 -0
- package/lib/types/diagnosis/store.d.ts.map +1 -0
- package/lib/types/diagnosis/store.js +409 -0
- package/lib/types/diagnosis/store.js.map +1 -0
- package/lib/types/diagnosis/types.d.ts +124 -0
- package/lib/types/diagnosis/types.d.ts.map +1 -0
- package/lib/types/diagnosis/types.js +13 -0
- package/lib/types/diagnosis/types.js.map +1 -0
- package/lib/types/directory-picker.d.ts +94 -0
- package/lib/types/directory-picker.d.ts.map +1 -0
- package/lib/types/directory-picker.js +110 -0
- package/lib/types/directory-picker.js.map +1 -0
- package/lib/types/extract-model.d.ts +76 -0
- package/lib/types/extract-model.d.ts.map +1 -0
- package/lib/types/extract-model.js +193 -0
- package/lib/types/extract-model.js.map +1 -0
- package/lib/types/extract.d.ts +121 -0
- package/lib/types/extract.d.ts.map +1 -0
- package/lib/types/extract.js +549 -0
- package/lib/types/extract.js.map +1 -0
- package/lib/types/fts.d.ts +96 -0
- package/lib/types/fts.d.ts.map +1 -0
- package/lib/types/fts.js +184 -0
- package/lib/types/fts.js.map +1 -0
- package/lib/types/index.d.ts +39 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +1112 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/intent/engine.d.ts +108 -0
- package/lib/types/intent/engine.d.ts.map +1 -0
- package/lib/types/intent/engine.js +501 -0
- package/lib/types/intent/engine.js.map +1 -0
- package/lib/types/intent/host.d.ts +88 -0
- package/lib/types/intent/host.d.ts.map +1 -0
- package/lib/types/intent/host.js +389 -0
- package/lib/types/intent/host.js.map +1 -0
- package/lib/types/intent/preset-tools.d.ts +37 -0
- package/lib/types/intent/preset-tools.d.ts.map +1 -0
- package/lib/types/intent/preset-tools.js +45 -0
- package/lib/types/intent/preset-tools.js.map +1 -0
- package/lib/types/intent/settings-schema.d.ts +59 -0
- package/lib/types/intent/settings-schema.d.ts.map +1 -0
- package/lib/types/intent/settings-schema.js +57 -0
- package/lib/types/intent/settings-schema.js.map +1 -0
- package/lib/types/intent/store.d.ts +75 -0
- package/lib/types/intent/store.d.ts.map +1 -0
- package/lib/types/intent/store.js +139 -0
- package/lib/types/intent/store.js.map +1 -0
- package/lib/types/intent/tools.d.ts +63 -0
- package/lib/types/intent/tools.d.ts.map +1 -0
- package/lib/types/intent/tools.js +108 -0
- package/lib/types/intent/tools.js.map +1 -0
- package/lib/types/intent/types.d.ts +189 -0
- package/lib/types/intent/types.d.ts.map +1 -0
- package/lib/types/intent/types.js +62 -0
- package/lib/types/intent/types.js.map +1 -0
- package/lib/types/knowledge-bases.d.ts +266 -0
- package/lib/types/knowledge-bases.d.ts.map +1 -0
- package/lib/types/knowledge-bases.js +1107 -0
- package/lib/types/knowledge-bases.js.map +1 -0
- package/lib/types/layout.d.ts +262 -0
- package/lib/types/layout.d.ts.map +1 -0
- package/lib/types/layout.js +312 -0
- package/lib/types/layout.js.map +1 -0
- package/lib/types/migrate.d.ts +110 -0
- package/lib/types/migrate.d.ts.map +1 -0
- package/lib/types/migrate.js +280 -0
- package/lib/types/migrate.js.map +1 -0
- package/lib/types/recall-rank.d.ts +158 -0
- package/lib/types/recall-rank.d.ts.map +1 -0
- package/lib/types/recall-rank.js +261 -0
- package/lib/types/recall-rank.js.map +1 -0
- package/lib/types/runtime.d.ts +568 -0
- package/lib/types/runtime.d.ts.map +1 -0
- package/lib/types/runtime.js +3045 -0
- package/lib/types/runtime.js.map +1 -0
- package/lib/types/settings-schema.d.ts +117 -0
- package/lib/types/settings-schema.d.ts.map +1 -0
- package/lib/types/settings-schema.js +92 -0
- package/lib/types/settings-schema.js.map +1 -0
- package/lib/types/settings-volatile.d.ts +102 -0
- package/lib/types/settings-volatile.d.ts.map +1 -0
- package/lib/types/settings-volatile.js +114 -0
- package/lib/types/settings-volatile.js.map +1 -0
- package/lib/types/types.d.ts +799 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/types.js +387 -0
- package/lib/types/types.js.map +1 -0
- package/lib/types/wiki-types.d.ts +68 -0
- package/lib/types/wiki-types.d.ts.map +1 -0
- package/lib/types/wiki-types.js +322 -0
- package/lib/types/wiki-types.js.map +1 -0
- package/package.json +101 -0
- package/preset/tita-data-agent/agent.cordis.yml +376 -0
- package/preset/tita-data-agent/preset.yml +3 -0
- package/python/requirements.txt +8 -0
- package/scripts/doctor.mjs +70 -0
- package/scripts/e2e-pipeline.mjs +355 -0
- package/scripts/install-agent-preset.mjs +92 -0
- package/scripts/setup-embedding.sh +34 -0
- package/scripts/sync-agent-preset.mjs +188 -0
- package/src/client/AgentPresetCard.tsx +247 -0
- package/src/client/DirectoryPicker.tsx +357 -0
- package/src/client/InfoHint.tsx +65 -0
- package/src/client/IntentLogicTab.tsx +185 -0
- package/src/client/IntentTab.tsx +715 -0
- package/src/client/KnowledgeBaseTab.tsx +1454 -0
- package/src/client/KnowledgeGraphView.tsx +306 -0
- package/src/client/KnowledgePanel.tsx +381 -0
- package/src/client/KnowledgeStepRail.tsx +60 -0
- package/src/client/NodeSettings.tsx +392 -0
- package/src/client/PreviewSections.tsx +116 -0
- package/src/client/RecallPanel.tsx +399 -0
- package/src/client/TypeDefinitionDrawer.tsx +215 -0
- package/src/client/WikiFlowCard.tsx +226 -0
- package/src/client/WikiTypeEditor.tsx +332 -0
- package/src/client/agent-preset.ts +121 -0
- package/src/client/arch/AgentArchitectureGraph.tsx +219 -0
- package/src/client/arch/NodeLogicPanel.tsx +133 -0
- package/src/client/arch/ProblemDetailPanel.tsx +88 -0
- package/src/client/arch/model.ts +691 -0
- package/src/client/architecture.css +191 -0
- package/src/client/architecture.tsx +530 -0
- package/src/client/attribution/AttributionGraph.tsx +104 -0
- package/src/client/attribution/AttributionTab.tsx +332 -0
- package/src/client/attribution/CaseView.tsx +102 -0
- package/src/client/attribution/GraphStage.tsx +87 -0
- package/src/client/attribution/RunView.tsx +184 -0
- package/src/client/attribution/StageChrome.tsx +403 -0
- package/src/client/attribution/ViewSwitch.tsx +107 -0
- package/src/client/attribution/graph-options.ts +381 -0
- package/src/client/attribution/model.ts +462 -0
- package/src/client/config-scope.ts +119 -0
- package/src/client/convert/ConvertPanel.tsx +594 -0
- package/src/client/convert/styles.css +138 -0
- package/src/client/convert/styles.ts +49 -0
- package/src/client/format.ts +39 -0
- package/src/client/graph/layout.ts +181 -0
- package/src/client/graph.css +113 -0
- package/src/client/index.ts +98 -0
- package/src/client/problem-domains.ts +114 -0
- package/src/client/styles.css +940 -0
- package/src/client/styles.ts +11 -0
- package/src/client/useFitScale.ts +68 -0
- package/src/config-schema.ts +45 -0
- package/src/convert/core-loader.ts +68 -0
- package/src/convert/host.ts +579 -0
- package/src/convert/ingest.ts +367 -0
- package/src/convert/settings-schema.ts +27 -0
- package/src/convert/types.ts +65 -0
- package/src/diagnosis/cards.ts +498 -0
- package/src/diagnosis/problem-classes.ts +117 -0
- package/src/diagnosis/schema.ts +260 -0
- package/src/diagnosis/seed-source.ts +107 -0
- package/src/diagnosis/seed.ts +291 -0
- package/src/diagnosis/store.ts +432 -0
- package/src/diagnosis/types.ts +152 -0
- package/src/directory-picker.ts +164 -0
- package/src/extract-model.ts +227 -0
- package/src/extract.ts +632 -0
- package/src/fts.ts +203 -0
- package/src/index.ts +1091 -0
- package/src/intent/README.md +63 -0
- package/src/intent/engine.ts +527 -0
- package/src/intent/host.ts +462 -0
- package/src/intent/preset-tools.ts +48 -0
- package/src/intent/settings-schema.ts +63 -0
- package/src/intent/store.ts +143 -0
- package/src/intent/tools.ts +139 -0
- package/src/intent/types.ts +245 -0
- package/src/knowledge-bases.ts +1160 -0
- package/src/layout.ts +350 -0
- package/src/migrate.ts +262 -0
- package/src/python/embedding_worker.py +471 -0
- package/src/recall-rank.ts +299 -0
- package/src/runtime.ts +3069 -0
- package/src/settings-schema.ts +94 -0
- package/src/settings-volatile.ts +122 -0
- package/src/types.ts +1140 -0
- package/src/wiki-types.ts +357 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import type { AttributionGraphData } from './types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 案例 = **一篇 wiki 定义 + 一条有序排查路径**。
|
|
5
|
+
*
|
|
6
|
+
* 两段各有明确消费者,不能合并:
|
|
7
|
+
* - `sections` 是给人读、给向量召回的散文(可 diff、可评审、可追溯);
|
|
8
|
+
* - `path` 是给图和剪枝用的结构(有序、可判真假、带被否定的分支)。
|
|
9
|
+
*
|
|
10
|
+
* 序和枚举一旦写进散文,归并算法就再也读不到它们了 —— 所以路径单独成段。
|
|
11
|
+
*/
|
|
12
|
+
export interface CaseSection {
|
|
13
|
+
heading: string
|
|
14
|
+
body: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CasePathStep {
|
|
18
|
+
nodeId: string
|
|
19
|
+
label: string
|
|
20
|
+
note: string
|
|
21
|
+
/** 这一步的结论是「否定」:它把某个假设置于死地,而不是坐实。 */
|
|
22
|
+
refuted?: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AttributionCase {
|
|
26
|
+
id: string
|
|
27
|
+
title: string
|
|
28
|
+
symptomId: string
|
|
29
|
+
sections: CaseSection[]
|
|
30
|
+
path: CasePathStep[]
|
|
31
|
+
durationMinutes: number
|
|
32
|
+
/** 误导段:最贵的那条知识。没有它,下次还会有人在同一个假设上烧掉四十分钟。 */
|
|
33
|
+
misleading?: { nodeId: string; label: string; wastedMinutes: number; why: string }
|
|
34
|
+
rootCause: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Seed 图谱:与 0021 §11 的三个案例同源,用来说明「同一现象有多个根因、否定边有用、
|
|
39
|
+
* 误导边昂贵」。
|
|
40
|
+
*
|
|
41
|
+
* 它现在有两重身份:
|
|
42
|
+
* 1. **首次启动的起点** —— `DiagnosisStore.ensure()` 在 `05_diagnosis/` 为空时把它写成
|
|
43
|
+
* 真实的 jsonl,之后用户可以手改,不会被覆盖回去;
|
|
44
|
+
* 2. **回归样本** —— 上面那三条结论需要一个稳定的夹具,所以它不会被删除。
|
|
45
|
+
*/
|
|
46
|
+
export const SEED_GRAPH: AttributionGraphData = {
|
|
47
|
+
nodes: [
|
|
48
|
+
// ── 类型层:问题侧(每个现象带问题大类 / 子类,见 0021 §4.5) ───────────
|
|
49
|
+
// 三个**具体**现象,而不是一个「指标报表 T-1 异常」—— 大类是切面,不是节点;
|
|
50
|
+
// 把「T-1 指标异常」这种泛指做成节点,等于让三个不同的故障在图上长得一模一样。
|
|
51
|
+
{
|
|
52
|
+
id: 'S1', kind: 'symptom', layer: 'type', title: '日报 GMV 为 0',
|
|
53
|
+
problemClass: 'missing', problemSubclass: 'missing-zero',
|
|
54
|
+
summary: '观测量:日报 GMV + 单日窗口;精确为 0 而不是偏低。',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'S2', kind: 'symptom', layer: 'type', title: '订单数只剩昨日 12%',
|
|
58
|
+
problemClass: 'deviation', problemSubclass: 'deviation-drop-sharp',
|
|
59
|
+
summary: '观测量:日报订单数 + 单日窗口;下降 88%,按渠道切开后缺口集中在新增渠道。',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'S3', kind: 'symptom', layer: 'type', title: 'DAU 突增 3.1 倍',
|
|
63
|
+
problemClass: 'deviation', problemSubclass: 'deviation-rise-sharp',
|
|
64
|
+
summary: '观测量:DAU + 单日窗口;放大 3.1 倍且只有 T-1 单日,相邻日期正常。',
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
{ id: 'H1', kind: 'hypothesis', layer: 'type', title: '上游分区未产出', failureMode: 'upstream-missing', reuseCount: 12,
|
|
68
|
+
summary: '当日 dwd / ods 分区不存在 → 指标必然为 0。反例:分区在但行数为 0 时不是它。',
|
|
69
|
+
discriminator: '当日 dwd / ods 分区不存在 → 指标必然为 0',
|
|
70
|
+
notWhen: '分区存在但行数为 0(那是 H4);分区正常而指标仍为 0(那是口径或消费侧)' },
|
|
71
|
+
{ id: 'H2', kind: 'hypothesis', layer: 'type', title: '口径 / 版本变更', failureMode: 'spec-change', reuseCount: 5,
|
|
72
|
+
summary: '口径版本切换未同步 → 同名词指标在不同版本下口径不同。',
|
|
73
|
+
discriminator: '口径版本切换后,同名词指标在两版定义下口径不一致',
|
|
74
|
+
notWhen: '口径未变更时本假设不成立 —— 不要用「名字一样」当作口径一致的证据' },
|
|
75
|
+
{ id: 'H3', kind: 'hypothesis', layer: 'type', title: '维表映射丢失', failureMode: 'data-processing', reuseCount: 4,
|
|
76
|
+
summary: '新渠道未补录维表 → join 落 unknown 后被 where 过滤。',
|
|
77
|
+
discriminator: '维表 join 后 unknown 占比显著升高,且缺口集中在新增维度成员上',
|
|
78
|
+
notWhen: 'unknown 占比正常时本假设不成立;缺口若均匀分布在各维度上,应转 H4 或 H5' },
|
|
79
|
+
{ id: 'H4', kind: 'hypothesis', layer: 'type', title: '重复 / 回刷', failureMode: 'data-processing', reuseCount: 6,
|
|
80
|
+
summary: '上游重跑写入重复行 → 计数类指标放大。',
|
|
81
|
+
discriminator: '主键不唯一,或分区行数同比放大',
|
|
82
|
+
notWhen: '主键唯一性检查通过(T4.1)时本假设不成立 —— 这是最常被误判的一条' },
|
|
83
|
+
{ id: 'H5', kind: 'hypothesis', layer: 'type', title: '时间窗口 / 时区', failureMode: 'data-processing', reuseCount: 2,
|
|
84
|
+
summary: '跨天事件被补写进 T-1 分区 → 单日指标异常放大。',
|
|
85
|
+
discriminator: '分区内事件时间跨天,且只有 T-1 单日异常',
|
|
86
|
+
notWhen: '相邻日期同时异常时应转 H2;事件时间落在单日内则应转 H4' },
|
|
87
|
+
{ id: 'H6', kind: 'hypothesis', layer: 'type', title: '权限 / 过滤条件', failureMode: 'permission', reuseCount: 1,
|
|
88
|
+
summary: '行级权限或 where 条件变更 → 结果集被静默收窄。',
|
|
89
|
+
discriminator: '结果集被行级权限或 where 条件静默收窄',
|
|
90
|
+
notWhen: '权限与过滤条件在本周期未变更时本假设不成立' },
|
|
91
|
+
{ id: 'H7', kind: 'hypothesis', layer: 'type', title: '下游 BI 缓存 / 增量', failureMode: 'consumption', reuseCount: 3,
|
|
92
|
+
summary: '缓存或增量刷新未触发 → 展示侧滞后,明细不受影响。',
|
|
93
|
+
discriminator: 'BI 展示侧滞后,但直连明细的数字正常',
|
|
94
|
+
notWhen: '明细对账一致(T7.2)时本假设不成立;注意 T7.1「缓存时间正常」不足以否定它' },
|
|
95
|
+
|
|
96
|
+
// `code` 是这张卡片的稳定标识:假设卡片里写的是编码(`failure_mode: data-processing`),
|
|
97
|
+
// 边要连到节点 —— 少了它,「编码 → 节点」就只能靠 F1..F5 的位置去猜。
|
|
98
|
+
{ id: 'F1', kind: 'failure-mode', layer: 'type', title: '上游未产出', code: 'upstream-missing' },
|
|
99
|
+
{ id: 'F2', kind: 'failure-mode', layer: 'type', title: '口径变更', code: 'spec-change' },
|
|
100
|
+
{ id: 'F3', kind: 'failure-mode', layer: 'type', title: '数据处理', code: 'data-processing' },
|
|
101
|
+
{ id: 'F4', kind: 'failure-mode', layer: 'type', title: '消费与展示', code: 'consumption' },
|
|
102
|
+
{ id: 'F5', kind: 'failure-mode', layer: 'type', title: '权限与过滤', code: 'permission' },
|
|
103
|
+
|
|
104
|
+
{ id: 'T1.1', kind: 'check', layer: 'type', title: '查分区存在性', costMinutes: 1, automation: 'auto', owner: '@duty',
|
|
105
|
+
summary: '分区 dwd_ord_di/dt 是否存在。不存在 → 支持 H1。',
|
|
106
|
+
verdictTrue: '分区不存在', verdictFalse: '分区存在' },
|
|
107
|
+
{ id: 'T1.2', kind: 'check', layer: 'type', title: '查任务实例状态', costMinutes: 1, automation: 'auto', owner: '@duty',
|
|
108
|
+
summary: '上游任务实例是否 failed。failed → 支持 H1。',
|
|
109
|
+
verdictTrue: '实例状态 failed', verdictFalse: '实例状态 success / running' },
|
|
110
|
+
{ id: 'T2.1', kind: 'check', layer: 'type', title: '口径版本对比', costMinutes: 15, automation: 'manual', owner: '@metric-owner',
|
|
111
|
+
summary: '对比近两次口径版本定义。口径变化 → 支持 H2。',
|
|
112
|
+
verdictTrue: '近两次口径定义不一致', verdictFalse: '口径定义逐字一致' },
|
|
113
|
+
{ id: 'T3.1', kind: 'check', layer: 'type', title: 'unknown 占比', costMinutes: 2, automation: 'auto', owner: '@duty',
|
|
114
|
+
summary: '维表 join 后 unknown 占比。显著升高 → 支持 H3。',
|
|
115
|
+
verdictTrue: 'unknown 占比 > 5%', verdictFalse: 'unknown 占比 ≤ 5%' },
|
|
116
|
+
{ id: 'T4.1', kind: 'check', layer: 'type', title: '主键唯一性', costMinutes: 3, automation: 'auto', owner: '@duty',
|
|
117
|
+
summary: '主键唯一性检查。通过 → 否定 H4。这是最常被误判的一条。',
|
|
118
|
+
verdictTrue: '存在重复主键', verdictFalse: '主键唯一 → 否定 H4' },
|
|
119
|
+
{ id: 'T5.1', kind: 'check', layer: 'type', title: '事件时间分布', costMinutes: 8, automation: 'auto', owner: '@duty',
|
|
120
|
+
summary: '分区内事件时间分布。跨天 → 支持 H5。',
|
|
121
|
+
verdictTrue: '分区内事件时间跨出 T-1 单日窗口', verdictFalse: '事件时间全部落在 T-1 内' },
|
|
122
|
+
{ id: 'T7.1', kind: 'check', layer: 'type', title: '查缓存时间戳', costMinutes: 2, automation: 'auto', owner: '@duty',
|
|
123
|
+
summary: '缓存时间正常并不能否定 H7 —— 便宜检查给不出结论。',
|
|
124
|
+
verdictTrue: '缓存时间戳过期', verdictFalse: '缓存时间正常 —— 注意:这一条**不足以**否定 H7' },
|
|
125
|
+
{ id: 'T7.2', kind: 'check', layer: 'type', title: '直连明细对账', costMinutes: 35, automation: 'manual', owner: '@analyst',
|
|
126
|
+
summary: '明细对账一致 → 否定 H7。要否定它必须做这次贵检查。',
|
|
127
|
+
verdictTrue: '明细与报表数字不一致', verdictFalse: '明细与报表一致 → 否定 H7' },
|
|
128
|
+
|
|
129
|
+
// ── 引用层 ────────────────────────────────────────────────────────────
|
|
130
|
+
{ id: 'dwd_ord_di', kind: 'asset', layer: 'reference', title: 'dwd_ord_di' },
|
|
131
|
+
{ id: 'ods_order_sync', kind: 'asset', layer: 'reference', title: 'ods_order_sync' },
|
|
132
|
+
{ id: 'dim_channel_df', kind: 'asset', layer: 'reference', title: 'dim_channel_df' },
|
|
133
|
+
|
|
134
|
+
// ── 实例层(默认折叠,展开后用于演示「证据与复用」) ────────────────────
|
|
135
|
+
// 案例节点是**图上的桩**:标题必须与 `SEED_CASES[].title` 是同一个字符串,否则同一份
|
|
136
|
+
// 知识会有两份标题(而且还真的不一致过:「只剩」vs「只有」)。画布要在标签前显示案例 id,
|
|
137
|
+
// 那是渲染层的事(见 `nodeStyleFor` 的 labelText)。
|
|
138
|
+
{ id: 'CASE-001', kind: 'case', layer: 'instance', title: '日报 GMV 为 0' },
|
|
139
|
+
{ id: 'CASE-002', kind: 'case', layer: 'instance', title: '订单数只有昨日 12%' },
|
|
140
|
+
{ id: 'CASE-003', kind: 'case', layer: 'instance', title: 'DAU 突增 3.1 倍' },
|
|
141
|
+
{ id: 'C1', kind: 'cause', layer: 'instance', title: 'C1 ODS 任务失败' },
|
|
142
|
+
{ id: 'C2', kind: 'cause', layer: 'instance', title: 'C2 渠道维表未补录' },
|
|
143
|
+
{ id: 'C3', kind: 'cause', layer: 'instance', title: 'C3 跨天事件补写' },
|
|
144
|
+
{ id: 'E1', kind: 'evidence', layer: 'instance', title: 'E1 分区不存在' },
|
|
145
|
+
{ id: 'E7', kind: 'evidence', layer: 'instance', title: 'E7 明细对账一致' },
|
|
146
|
+
],
|
|
147
|
+
edges: [
|
|
148
|
+
// 层内:现象 → 假设(含一条僵尸边,用来演示「权重过期」)
|
|
149
|
+
//
|
|
150
|
+
// **三个现象共享同一批假设,这是这张图最重要的性质。** 每条现象只连它真正可能的原因,
|
|
151
|
+
// 于是「同一个假设被几个现象指向」就成了它的复用读数;而「为 0」与「突增」两个看起来
|
|
152
|
+
// 相反的故障,会在 H4(重复 / 回刷)上相遇 —— 这正是案例各长一棵树时永远看不见的东西。
|
|
153
|
+
{ id: 'e-s1-h1', source: 'S1', target: 'H1', kind: 'may_be_caused_by' },
|
|
154
|
+
{ id: 'e-s1-h2', source: 'S1', target: 'H2', kind: 'may_be_caused_by', staleDays: 94 },
|
|
155
|
+
{ id: 'e-s1-h3', source: 'S1', target: 'H3', kind: 'may_be_caused_by' },
|
|
156
|
+
{ id: 'e-s1-h4', source: 'S1', target: 'H4', kind: 'may_be_caused_by' },
|
|
157
|
+
{ id: 'e-s1-h5', source: 'S1', target: 'H5', kind: 'may_be_caused_by' },
|
|
158
|
+
{ id: 'e-s1-h6', source: 'S1', target: 'H6', kind: 'may_be_caused_by' },
|
|
159
|
+
{ id: 'e-s1-h7', source: 'S1', target: 'H7', kind: 'may_be_caused_by' },
|
|
160
|
+
|
|
161
|
+
// 突降:产出缺失、重复回刷、维表过滤、缓存滞后都能造成下降;口径与权限这次不在列。
|
|
162
|
+
{ id: 'e-s2-h1', source: 'S2', target: 'H1', kind: 'may_be_caused_by' },
|
|
163
|
+
{ id: 'e-s2-h3', source: 'S2', target: 'H3', kind: 'may_be_caused_by' },
|
|
164
|
+
{ id: 'e-s2-h4', source: 'S2', target: 'H4', kind: 'may_be_caused_by' },
|
|
165
|
+
{ id: 'e-s2-h7', source: 'S2', target: 'H7', kind: 'may_be_caused_by' },
|
|
166
|
+
|
|
167
|
+
// 突增:放大只可能来自重复计数、跨天补写、缓存重复展示 —— 缺口类的原因在这里不成立。
|
|
168
|
+
{ id: 'e-s3-h4', source: 'S3', target: 'H4', kind: 'may_be_caused_by' },
|
|
169
|
+
{ id: 'e-s3-h5', source: 'S3', target: 'H5', kind: 'may_be_caused_by' },
|
|
170
|
+
{ id: 'e-s3-h7', source: 'S3', target: 'H7', kind: 'may_be_caused_by' },
|
|
171
|
+
|
|
172
|
+
// 层内:假设 → 检查(H6 故意没有,它就是图上的空区)
|
|
173
|
+
{ id: 'e-h1-t11', source: 'H1', target: 'T1.1', kind: 'verified_by' },
|
|
174
|
+
{ id: 'e-h1-t12', source: 'H1', target: 'T1.2', kind: 'verified_by' },
|
|
175
|
+
{ id: 'e-h2-t21', source: 'H2', target: 'T2.1', kind: 'verified_by' },
|
|
176
|
+
{ id: 'e-h3-t31', source: 'H3', target: 'T3.1', kind: 'verified_by' },
|
|
177
|
+
{ id: 'e-h4-t41', source: 'H4', target: 'T4.1', kind: 'verified_by' },
|
|
178
|
+
{ id: 'e-h5-t51', source: 'H5', target: 'T5.1', kind: 'verified_by' },
|
|
179
|
+
{ id: 'e-h7-t71', source: 'H7', target: 'T7.1', kind: 'verified_by' },
|
|
180
|
+
{ id: 'e-h7-t72', source: 'H7', target: 'T7.2', kind: 'verified_by' },
|
|
181
|
+
|
|
182
|
+
// 层内:假设 → 失败模式(切面)
|
|
183
|
+
{ id: 'e-h1-f1', source: 'H1', target: 'F1', kind: 'categorized_as' },
|
|
184
|
+
{ id: 'e-h2-f2', source: 'H2', target: 'F2', kind: 'categorized_as' },
|
|
185
|
+
{ id: 'e-h3-f3', source: 'H3', target: 'F3', kind: 'categorized_as' },
|
|
186
|
+
{ id: 'e-h4-f3', source: 'H4', target: 'F3', kind: 'categorized_as' },
|
|
187
|
+
{ id: 'e-h5-f3', source: 'H5', target: 'F3', kind: 'categorized_as' },
|
|
188
|
+
{ id: 'e-h6-f5', source: 'H6', target: 'F5', kind: 'categorized_as' },
|
|
189
|
+
{ id: 'e-h7-f4', source: 'H7', target: 'F4', kind: 'categorized_as' },
|
|
190
|
+
|
|
191
|
+
// 跨层:资产反向索引
|
|
192
|
+
{ id: 'e-a-dwd-h1', source: 'dwd_ord_di', target: 'H1', kind: 'indexed_from' },
|
|
193
|
+
{ id: 'e-a-ods-h1', source: 'ods_order_sync', target: 'H1', kind: 'indexed_from' },
|
|
194
|
+
{ id: 'e-a-dim-h3', source: 'dim_channel_df', target: 'H3', kind: 'indexed_from' },
|
|
195
|
+
|
|
196
|
+
// 跨层:检查产出证据、证据支持或否定假设
|
|
197
|
+
{ id: 'e-t11-e1', source: 'T1.1', target: 'E1', kind: 'produces' },
|
|
198
|
+
{ id: 'e-e1-h1', source: 'E1', target: 'H1', kind: 'supports' },
|
|
199
|
+
{ id: 'e-t72-e7', source: 'T7.2', target: 'E7', kind: 'produces' },
|
|
200
|
+
{ id: 'e-e7-h7', source: 'E7', target: 'H7', kind: 'refutes' },
|
|
201
|
+
|
|
202
|
+
// 跨层:假设确认成根因
|
|
203
|
+
{ id: 'e-h1-c1', source: 'H1', target: 'C1', kind: 'confirmed_as' },
|
|
204
|
+
{ id: 'e-h3-c2', source: 'H3', target: 'C2', kind: 'confirmed_as' },
|
|
205
|
+
{ id: 'e-h5-c3', source: 'H5', target: 'C3', kind: 'confirmed_as' },
|
|
206
|
+
|
|
207
|
+
// 跨层:案例实例化(三个案例各归各的现象,但收敛到**同一批假设**)
|
|
208
|
+
{ id: 'e-case1-s1', source: 'CASE-001', target: 'S1', kind: 'instance_of', count: 1 },
|
|
209
|
+
{ id: 'e-case2-s2', source: 'CASE-002', target: 'S2', kind: 'instance_of', count: 1 },
|
|
210
|
+
{ id: 'e-case3-s3', source: 'CASE-003', target: 'S3', kind: 'instance_of', count: 1 },
|
|
211
|
+
],
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** 三个 seed 案例,与上面图谱里的节点 id 对齐(0021 §11)。 */
|
|
215
|
+
export const SEED_CASES: AttributionCase[] = [
|
|
216
|
+
{
|
|
217
|
+
id: 'CASE-001',
|
|
218
|
+
title: '日报 GMV 为 0',
|
|
219
|
+
symptomId: 'S1',
|
|
220
|
+
durationMinutes: 65,
|
|
221
|
+
rootCause: 'ODS 任务 ods_order_sync 02:40 失败且未启用重试,dwd_ord_di/dt 分区未产出。',
|
|
222
|
+
sections: [
|
|
223
|
+
{ heading: '现象', body: '2026-08-11 日报 GMV = 0,前一日 128.4 万。指标值精确为 0 而不是偏低。' },
|
|
224
|
+
{ heading: '影响面', body: '全量受影响,不随维度细分变化 —— 这个特征把「口径类」原因基本排除了。' },
|
|
225
|
+
{ heading: '排查过程', body: '先确认分区是否存在(1 分钟),再确认上游任务实例状态;随后被下游缓存方向带走约 40 分钟,最终用明细对账否定它。' },
|
|
226
|
+
{ heading: '根因', body: '上游 ODS 任务在 02:40 失败,重试未启用。分区缺失导致下游 dwd 无输入,指标落 0。' },
|
|
227
|
+
{ heading: '修复与防复发', body: '补 dwd_ord_di 分区;给 ods_order_sync 加失败告警与自动重试;分区存在性检查加入日报前置校验。' },
|
|
228
|
+
],
|
|
229
|
+
path: [
|
|
230
|
+
{ nodeId: 'S1', label: 'S1', note: '进入:日报 GMV = 0' },
|
|
231
|
+
{ nodeId: 'H1', label: 'H1', note: '按优先分 29 排第一' },
|
|
232
|
+
{ nodeId: 'T1.1', label: 'T1.1', note: '查分区存在性 → 分区不存在' },
|
|
233
|
+
{ nodeId: 'E1', label: 'E1', note: '产出证据,支持 H1' },
|
|
234
|
+
{ nodeId: 'C1', label: 'C1', note: '确认根因' },
|
|
235
|
+
],
|
|
236
|
+
misleading: {
|
|
237
|
+
nodeId: 'H7',
|
|
238
|
+
label: 'H7 下游 BI 缓存',
|
|
239
|
+
wastedMinutes: 40,
|
|
240
|
+
why: 'T7.1 查缓存时间戳只要 2 分钟且返回「正常」,但**这个便宜检查给不出结论**;要否定 H7 必须做 35 分钟的人工明细对账。浪费不发生在笨检查上,而发生在这种「便宜检查无结论、贵检查没人愿意先做」的夹缝里。',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
id: 'CASE-002',
|
|
245
|
+
title: '订单数只有昨日 12%',
|
|
246
|
+
symptomId: 'S2',
|
|
247
|
+
durationMinutes: 22,
|
|
248
|
+
rootCause: '新增渠道未补录维表,dim_channel_df join 落 unknown 后被 where channel is not null 过滤。',
|
|
249
|
+
sections: [
|
|
250
|
+
{ heading: '现象', body: '订单数 8,412,前一日 70,110,下降 88%。' },
|
|
251
|
+
{ heading: '影响面', body: '按渠道维度切开后,缺口集中在新增的两个渠道 —— 这个线索直接指向维表而不是上游。' },
|
|
252
|
+
{ heading: '排查过程', body: '按优先分先做最便宜的分区存在性检查(1 分钟),分区在,H1 被否定;接着做 H4 的主键唯一性检查,通过,H4 也被否定;转查 H3 的 unknown 占比,88%,一击确认。两次否定各花不到 3 分钟。' },
|
|
253
|
+
{ heading: '根因', body: '新渠道未补录维表,join 落 unknown,被下游过滤条件静默丢弃。' },
|
|
254
|
+
{ heading: '修复与防复发', body: '补录渠道维表;把 unknown 占比纳入日常巡检;下游过滤改为「先报警再过滤」。' },
|
|
255
|
+
],
|
|
256
|
+
path: [
|
|
257
|
+
{ nodeId: 'S2', label: 'S2', note: '进入:订单数下降 88%' },
|
|
258
|
+
{ nodeId: 'H1', label: 'H1', note: '优先分第一(1 分钟的分区检查)' },
|
|
259
|
+
{ nodeId: 'T1.1', label: 'T1.1✗', note: '分区存在 → 否定 H1', refuted: true },
|
|
260
|
+
{ nodeId: 'H4', label: 'H4', note: '剩余先验最高' },
|
|
261
|
+
{ nodeId: 'T4.1', label: 'T4.1✗', note: '主键唯一性通过 → 否定 H4', refuted: true },
|
|
262
|
+
{ nodeId: 'H3', label: 'H3', note: '转向维表映射' },
|
|
263
|
+
{ nodeId: 'T3.1', label: 'T3.1', note: 'unknown 占比 88%' },
|
|
264
|
+
{ nodeId: 'C2', label: 'C2', note: '确认根因' },
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
id: 'CASE-003',
|
|
269
|
+
title: 'DAU 突增 3.1 倍',
|
|
270
|
+
symptomId: 'S3',
|
|
271
|
+
durationMinutes: 35,
|
|
272
|
+
rootCause: '上游重跑把跨天事件补写进 T-1 分区,事件时间与处理时间边界被跨越。',
|
|
273
|
+
sections: [
|
|
274
|
+
{ heading: '现象', body: 'DAU 112 万 → 347 万,无对应投放或活动。' },
|
|
275
|
+
{ heading: '影响面', body: '只有 T-1 单日放大,相邻日期正常 —— 这排除了口径变更(口径类会同时影响多天)。' },
|
|
276
|
+
{ heading: '排查过程', body: '主键唯一性通过,H4 被否定;再查缓存时间戳,返回「正常」但**这一条给不出结论**(与 CASE-001 是同一个坑);最后查事件时间分布,发现跨天事件,命中 H5。' },
|
|
277
|
+
{ heading: '根因', body: '上游重跑把跨天事件补写进 T-1 分区。' },
|
|
278
|
+
{ heading: '修复与防复发', body: '重跑加事件时间边界校验;分区写入前检查事件时间下界。' },
|
|
279
|
+
],
|
|
280
|
+
path: [
|
|
281
|
+
{ nodeId: 'S3', label: 'S3', note: '进入:DAU 突增 3.1×' },
|
|
282
|
+
{ nodeId: 'H4', label: 'H4', note: '优先分第一(重复数据会放大计数)' },
|
|
283
|
+
{ nodeId: 'T4.1', label: 'T4.1✗', note: '主键唯一性通过 → 否定 H4', refuted: true },
|
|
284
|
+
{ nodeId: 'H7', label: 'H7', note: '转向展示侧' },
|
|
285
|
+
{ nodeId: 'T7.1', label: 'T7.1~', note: '缓存时间正常 —— 但这一条给不出结论' },
|
|
286
|
+
{ nodeId: 'H5', label: 'H5', note: '转向时间窗口' },
|
|
287
|
+
{ nodeId: 'T5.1', label: 'T5.1', note: '事件时间跨天' },
|
|
288
|
+
{ nodeId: 'C3', label: 'C3', note: '确认根因' },
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
]
|