dsh-data-domain-knowledge 0.1.0-alpha.2 → 0.1.0-alpha.4
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/README.md +147 -19
- package/cordis.patch.yml +25 -10
- package/lib/client.js +6400 -3326
- package/lib/doc-page.js +7761 -0
- package/lib/types/convert/host.d.ts.map +1 -1
- package/lib/types/convert/host.js +63 -11
- package/lib/types/convert/host.js.map +1 -1
- package/lib/types/convert/ingest.d.ts +7 -4
- package/lib/types/convert/ingest.d.ts.map +1 -1
- package/lib/types/convert/ingest.js +52 -14
- package/lib/types/convert/ingest.js.map +1 -1
- package/lib/types/convert/types.d.ts +2 -2
- package/lib/types/convert/types.d.ts.map +1 -1
- package/lib/types/convert/types.js +2 -2
- package/lib/types/convert/types.js.map +1 -1
- package/lib/types/diagnosis/cards.d.ts +8 -7
- package/lib/types/diagnosis/cards.d.ts.map +1 -1
- package/lib/types/diagnosis/cards.js +119 -49
- package/lib/types/diagnosis/cards.js.map +1 -1
- package/lib/types/diagnosis/run.d.ts +57 -0
- package/lib/types/diagnosis/run.d.ts.map +1 -0
- package/lib/types/diagnosis/run.js +245 -0
- package/lib/types/diagnosis/run.js.map +1 -0
- package/lib/types/diagnosis/schema.d.ts +25 -2
- package/lib/types/diagnosis/schema.d.ts.map +1 -1
- package/lib/types/diagnosis/schema.js +64 -25
- package/lib/types/diagnosis/schema.js.map +1 -1
- package/lib/types/diagnosis/seed-source.d.ts +17 -2
- package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
- package/lib/types/diagnosis/seed-source.js +19 -2
- package/lib/types/diagnosis/seed-source.js.map +1 -1
- package/lib/types/diagnosis/seed.d.ts +32 -42
- package/lib/types/diagnosis/seed.d.ts.map +1 -1
- package/lib/types/diagnosis/seed.js +187 -51
- package/lib/types/diagnosis/seed.js.map +1 -1
- package/lib/types/diagnosis/store.d.ts +95 -25
- package/lib/types/diagnosis/store.d.ts.map +1 -1
- package/lib/types/diagnosis/store.js +297 -166
- package/lib/types/diagnosis/store.js.map +1 -1
- package/lib/types/diagnosis/types.d.ts +168 -16
- package/lib/types/diagnosis/types.d.ts.map +1 -1
- package/lib/types/diagnosis/types.js +1 -1
- package/lib/types/diagnosis/types.js.map +1 -1
- package/lib/types/document-page.d.ts +39 -0
- package/lib/types/document-page.d.ts.map +1 -0
- package/lib/types/document-page.js +43 -0
- package/lib/types/document-page.js.map +1 -0
- package/lib/types/extract-model.d.ts +67 -27
- package/lib/types/extract-model.d.ts.map +1 -1
- package/lib/types/extract-model.js +225 -97
- package/lib/types/extract-model.js.map +1 -1
- package/lib/types/extract.d.ts +16 -0
- package/lib/types/extract.d.ts.map +1 -1
- package/lib/types/extract.js +19 -2
- package/lib/types/extract.js.map +1 -1
- package/lib/types/fs-atomic.d.ts +11 -0
- package/lib/types/fs-atomic.d.ts.map +1 -0
- package/lib/types/fs-atomic.js +41 -0
- package/lib/types/fs-atomic.js.map +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +466 -63
- package/lib/types/index.js.map +1 -1
- package/lib/types/intent/types.js +1 -1
- package/lib/types/intent/types.js.map +1 -1
- package/lib/types/knowledge-bases.d.ts +23 -12
- package/lib/types/knowledge-bases.d.ts.map +1 -1
- package/lib/types/knowledge-bases.js +37 -44
- package/lib/types/knowledge-bases.js.map +1 -1
- package/lib/types/layout.d.ts +3 -3
- package/lib/types/layout.d.ts.map +1 -1
- package/lib/types/layout.js +4 -4
- package/lib/types/layout.js.map +1 -1
- package/lib/types/migrate.d.ts +1 -1
- package/lib/types/migrate.js +2 -2
- package/lib/types/migrate.js.map +1 -1
- package/lib/types/model-text.d.ts +99 -0
- package/lib/types/model-text.d.ts.map +1 -0
- package/lib/types/model-text.js +103 -0
- package/lib/types/model-text.js.map +1 -0
- package/lib/types/present.d.ts +239 -0
- package/lib/types/present.d.ts.map +1 -0
- package/lib/types/present.js +255 -0
- package/lib/types/present.js.map +1 -0
- package/lib/types/recall-rank.d.ts +37 -0
- package/lib/types/recall-rank.d.ts.map +1 -1
- package/lib/types/recall-rank.js +41 -1
- package/lib/types/recall-rank.js.map +1 -1
- package/lib/types/runtime.d.ts +564 -31
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/runtime.js +2645 -292
- package/lib/types/runtime.js.map +1 -1
- package/lib/types/settings-schema.d.ts +4 -2
- package/lib/types/settings-schema.d.ts.map +1 -1
- package/lib/types/settings-schema.js +2 -0
- package/lib/types/settings-schema.js.map +1 -1
- package/lib/types/source-images.d.ts +118 -0
- package/lib/types/source-images.d.ts.map +1 -0
- package/lib/types/source-images.js +288 -0
- package/lib/types/source-images.js.map +1 -0
- package/lib/types/types.d.ts +356 -28
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js +112 -18
- package/lib/types/types.js.map +1 -1
- package/lib/types/wiki-finalize.d.ts +140 -0
- package/lib/types/wiki-finalize.d.ts.map +1 -0
- package/lib/types/wiki-finalize.js +269 -0
- package/lib/types/wiki-finalize.js.map +1 -0
- package/lib/types/wiki-types.d.ts +10 -2
- package/lib/types/wiki-types.d.ts.map +1 -1
- package/lib/types/wiki-types.js +27 -30
- package/lib/types/wiki-types.js.map +1 -1
- package/package.json +4 -3
- package/preset/tita-data-agent/agent.cordis.yml +25 -10
- package/src/client/DirectoryPicker.tsx +12 -12
- package/src/client/DrawerSection.tsx +18 -0
- package/src/client/InfoHint.tsx +21 -8
- package/src/client/IntentTab.tsx +20 -26
- package/src/client/KnowledgeBaseTab.tsx +458 -158
- package/src/client/KnowledgePanel.tsx +44 -10
- package/src/client/KnowledgeStepRail.tsx +3 -0
- package/src/client/KnowledgeToolRow.tsx +331 -0
- package/src/client/NodeSettings.tsx +20 -22
- package/src/client/PreviewSections.tsx +178 -43
- package/src/client/RecallPanel.tsx +418 -127
- package/src/client/TypeDefinitionDrawer.tsx +154 -54
- package/src/client/WikiCardReview.tsx +266 -0
- package/src/client/WikiFlowCard.tsx +57 -95
- package/src/client/WikiTypeEditor.tsx +197 -95
- package/src/client/arch/AgentArchitectureGraph.tsx +30 -14
- package/src/client/arch/NodeLogicPanel.tsx +6 -3
- package/src/client/arch/model.ts +164 -26
- package/src/client/architecture.css +25 -10
- package/src/client/architecture.tsx +66 -41
- package/src/client/asset-images.ts +125 -0
- package/src/client/attribution/AttributionGraph.tsx +481 -34
- package/src/client/attribution/AttributionTab.tsx +501 -106
- package/src/client/attribution/CaseView.tsx +9 -14
- package/src/client/attribution/GraphStage.tsx +25 -18
- package/src/client/attribution/RunView.tsx +27 -9
- package/src/client/attribution/StageChrome.tsx +280 -140
- package/src/client/attribution/graph-options.ts +611 -47
- package/src/client/attribution/model.ts +559 -30
- package/src/client/convert/ConvertPanel.tsx +36 -4
- package/src/client/doc-page.css +134 -0
- package/src/client/doc-page.tsx +242 -0
- package/src/client/index.ts +18 -0
- package/src/client/panel-state.ts +105 -0
- package/src/client/problem-domains.ts +1 -1
- package/src/client/request.ts +36 -0
- package/src/client/styles.css +397 -54
- package/src/client/useFitScale.ts +15 -2
- package/src/client/wiki-type-groups.ts +86 -0
- package/src/convert/host.ts +68 -9
- package/src/convert/ingest.ts +61 -18
- package/src/convert/types.ts +2 -2
- package/src/diagnosis/cards.ts +120 -50
- package/src/diagnosis/run.ts +251 -0
- package/src/diagnosis/schema.ts +67 -26
- package/src/diagnosis/seed-source.ts +29 -4
- package/src/diagnosis/seed.ts +187 -85
- package/src/diagnosis/store.ts +310 -173
- package/src/diagnosis/types.ts +181 -16
- package/src/document-page.ts +51 -0
- package/src/extract-model.ts +254 -99
- package/src/extract.ts +35 -3
- package/src/fs-atomic.ts +41 -0
- package/src/index.ts +499 -62
- package/src/intent/types.ts +1 -1
- package/src/knowledge-bases.ts +50 -49
- package/src/layout.ts +4 -4
- package/src/migrate.ts +2 -2
- package/src/model-text.ts +126 -0
- package/src/present.ts +367 -0
- package/src/recall-rank.ts +57 -2
- package/src/runtime.ts +2802 -293
- package/src/settings-schema.ts +2 -0
- package/src/source-images.ts +326 -0
- package/src/types.ts +446 -45
- package/src/wiki-finalize.ts +310 -0
- package/src/wiki-types.ts +28 -32
package/src/diagnosis/seed.ts
CHANGED
|
@@ -1,47 +1,27 @@
|
|
|
1
|
-
import type { AttributionGraphData } from './types.js'
|
|
1
|
+
import type { AttributionCase, AttributionGraphData, DiagnosisRunRecord } from './types.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 内置**示例**:一份排查手册 + 三篇复盘 + 三次排查日志 + 由它们编出来的那张图。
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* - `sections` 是给人读、给向量召回的散文(可 diff、可评审、可追溯);
|
|
8
|
-
* - `path` 是给图和剪枝用的结构(有序、可判真假、带被否定的分支)。
|
|
6
|
+
* 它现在只有一重身份:**用户点了「载入内置示例」才写进去的样例,以及回归夹具**。
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
* 误导边昂贵」。
|
|
8
|
+
* 原来是两重(另一重是「首次启动的起点」,由 `DiagnosisStore.ensure()` 自动写入)。
|
|
9
|
+
* 实跑反馈把它去掉了:这份示例长得像真的业务文档,而它落在用户自己的
|
|
10
|
+
* `01_source_raw/` 与 `02_wiki/` 里 —— 新装一台机器,一打开「智能归因」就凭空多出
|
|
11
|
+
* 几份来源和几十张卡片,读起来像「我的知识库内容跟着包过来了」。示例没有被删除
|
|
12
|
+
* (它仍然是稳定夹具,`tests/diagnosis-cards.test.mjs` 逐字段对着它断言),
|
|
13
|
+
* 只是不再自动落盘 —— 入口是 `DiagnosisStore.loadSample()`。
|
|
14
|
+
*
|
|
15
|
+
* **两条来源分类、两个作者**(v1.1 起):
|
|
40
16
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
17
|
+
* | 来源分类 | 谁写 | 装什么 |
|
|
18
|
+
* | --- | --- | --- |
|
|
19
|
+
* | `question` | 人 | 手册与复盘 —— 卡片 `source_refs` 指向这里 |
|
|
20
|
+
* | `agent_diagnosis_case` | Agent | 一次排查的过程记录(`SEED_RUNS`) |
|
|
21
|
+
*
|
|
22
|
+
* `SEED_GRAPH` 里**只有卡片定义得了的东西**:类型层、引用层资产、案例桩,以及六种卡片边。
|
|
23
|
+
* `evidence` / `cause` 与四条执行边由 `SEED_RUNS` 读时解析出来 —— 把「上次查到什么」
|
|
24
|
+
* 写进卡片,等于让一份可复用的知识绑死在一次执行上。
|
|
45
25
|
*/
|
|
46
26
|
export const SEED_GRAPH: AttributionGraphData = {
|
|
47
27
|
nodes: [
|
|
@@ -64,85 +44,91 @@ export const SEED_GRAPH: AttributionGraphData = {
|
|
|
64
44
|
summary: '观测量:DAU + 单日窗口;放大 3.1 倍且只有 T-1 单日,相邻日期正常。',
|
|
65
45
|
},
|
|
66
46
|
|
|
67
|
-
{ id: 'H1', kind: 'hypothesis', layer: 'type', title: '上游分区未产出',
|
|
47
|
+
{ id: 'H1', kind: 'hypothesis', layer: 'type', title: '上游分区未产出', failureReason: 'upstream-missing', reuseCount: 12,
|
|
68
48
|
summary: '当日 dwd / ods 分区不存在 → 指标必然为 0。反例:分区在但行数为 0 时不是它。',
|
|
69
49
|
discriminator: '当日 dwd / ods 分区不存在 → 指标必然为 0',
|
|
70
50
|
notWhen: '分区存在但行数为 0(那是 H4);分区正常而指标仍为 0(那是口径或消费侧)' },
|
|
71
|
-
{ id: 'H2', kind: 'hypothesis', layer: 'type', title: '口径 / 版本变更',
|
|
51
|
+
{ id: 'H2', kind: 'hypothesis', layer: 'type', title: '口径 / 版本变更', failureReason: 'spec-change', reuseCount: 5,
|
|
72
52
|
summary: '口径版本切换未同步 → 同名词指标在不同版本下口径不同。',
|
|
73
53
|
discriminator: '口径版本切换后,同名词指标在两版定义下口径不一致',
|
|
74
54
|
notWhen: '口径未变更时本假设不成立 —— 不要用「名字一样」当作口径一致的证据' },
|
|
75
|
-
{ id: 'H3', kind: 'hypothesis', layer: 'type', title: '维表映射丢失',
|
|
55
|
+
{ id: 'H3', kind: 'hypothesis', layer: 'type', title: '维表映射丢失', failureReason: 'data-processing', reuseCount: 4,
|
|
76
56
|
summary: '新渠道未补录维表 → join 落 unknown 后被 where 过滤。',
|
|
77
57
|
discriminator: '维表 join 后 unknown 占比显著升高,且缺口集中在新增维度成员上',
|
|
78
58
|
notWhen: 'unknown 占比正常时本假设不成立;缺口若均匀分布在各维度上,应转 H4 或 H5' },
|
|
79
|
-
{ id: 'H4', kind: 'hypothesis', layer: 'type', title: '重复 / 回刷',
|
|
59
|
+
{ id: 'H4', kind: 'hypothesis', layer: 'type', title: '重复 / 回刷', failureReason: 'data-processing', reuseCount: 6,
|
|
80
60
|
summary: '上游重跑写入重复行 → 计数类指标放大。',
|
|
81
61
|
discriminator: '主键不唯一,或分区行数同比放大',
|
|
82
62
|
notWhen: '主键唯一性检查通过(T4.1)时本假设不成立 —— 这是最常被误判的一条' },
|
|
83
|
-
{ id: 'H5', kind: 'hypothesis', layer: 'type', title: '时间窗口 / 时区',
|
|
63
|
+
{ id: 'H5', kind: 'hypothesis', layer: 'type', title: '时间窗口 / 时区', failureReason: 'data-processing', reuseCount: 2,
|
|
84
64
|
summary: '跨天事件被补写进 T-1 分区 → 单日指标异常放大。',
|
|
85
65
|
discriminator: '分区内事件时间跨天,且只有 T-1 单日异常',
|
|
86
66
|
notWhen: '相邻日期同时异常时应转 H2;事件时间落在单日内则应转 H4' },
|
|
87
|
-
{ id: 'H6', kind: 'hypothesis', layer: 'type', title: '权限 / 过滤条件',
|
|
67
|
+
{ id: 'H6', kind: 'hypothesis', layer: 'type', title: '权限 / 过滤条件', failureReason: 'permission', reuseCount: 1,
|
|
88
68
|
summary: '行级权限或 where 条件变更 → 结果集被静默收窄。',
|
|
89
69
|
discriminator: '结果集被行级权限或 where 条件静默收窄',
|
|
90
70
|
notWhen: '权限与过滤条件在本周期未变更时本假设不成立' },
|
|
91
|
-
{ id: 'H7', kind: 'hypothesis', layer: 'type', title: '下游 BI 缓存 / 增量',
|
|
71
|
+
{ id: 'H7', kind: 'hypothesis', layer: 'type', title: '下游 BI 缓存 / 增量', failureReason: 'consumption', reuseCount: 3,
|
|
92
72
|
summary: '缓存或增量刷新未触发 → 展示侧滞后,明细不受影响。',
|
|
93
73
|
discriminator: 'BI 展示侧滞后,但直连明细的数字正常',
|
|
94
74
|
notWhen: '明细对账一致(T7.2)时本假设不成立;注意 T7.1「缓存时间正常」不足以否定它' },
|
|
95
75
|
|
|
96
|
-
// `code` 是这张卡片的稳定标识:假设卡片里写的是编码(`
|
|
76
|
+
// `code` 是这张卡片的稳定标识:假设卡片里写的是编码(`failure_reason: data-processing`),
|
|
97
77
|
// 边要连到节点 —— 少了它,「编码 → 节点」就只能靠 F1..F5 的位置去猜。
|
|
98
|
-
{ id: 'F1', kind: '
|
|
99
|
-
{ id: 'F2', kind: '
|
|
100
|
-
{ id: 'F3', kind: '
|
|
101
|
-
{ id: 'F4', kind: '
|
|
102
|
-
{ id: 'F5', kind: '
|
|
78
|
+
{ id: 'F1', kind: 'failure_reason', layer: 'type', title: '上游未产出', code: 'upstream-missing' },
|
|
79
|
+
{ id: 'F2', kind: 'failure_reason', layer: 'type', title: '口径变更', code: 'spec-change' },
|
|
80
|
+
{ id: 'F3', kind: 'failure_reason', layer: 'type', title: '数据处理', code: 'data-processing' },
|
|
81
|
+
{ id: 'F4', kind: 'failure_reason', layer: 'type', title: '消费与展示', code: 'consumption' },
|
|
82
|
+
{ id: 'F5', kind: 'failure_reason', layer: 'type', title: '权限与过滤', code: 'permission' },
|
|
103
83
|
|
|
104
|
-
|
|
84
|
+
// 检查点:`assets[]` 是 v1.3 的必填 —— 缺了它,这条检查不知道去哪查。
|
|
85
|
+
{ id: 'T1.1', kind: 'check_point', layer: 'type', title: '查分区存在性', costMinutes: 1, automation: 'auto', owner: '@duty',
|
|
86
|
+
assets: ['dwd_ord_di'],
|
|
105
87
|
summary: '分区 dwd_ord_di/dt 是否存在。不存在 → 支持 H1。',
|
|
106
88
|
verdictTrue: '分区不存在', verdictFalse: '分区存在' },
|
|
107
|
-
{ id: 'T1.2', kind: '
|
|
89
|
+
{ id: 'T1.2', kind: 'check_point', layer: 'type', title: '查任务实例状态', costMinutes: 1, automation: 'auto', owner: '@duty',
|
|
90
|
+
assets: ['ods_order_sync'],
|
|
108
91
|
summary: '上游任务实例是否 failed。failed → 支持 H1。',
|
|
109
92
|
verdictTrue: '实例状态 failed', verdictFalse: '实例状态 success / running' },
|
|
110
|
-
{ id: 'T2.1', kind: '
|
|
93
|
+
{ id: 'T2.1', kind: 'check_point', layer: 'type', title: '口径版本对比', costMinutes: 15, automation: 'manual', owner: '@metric-owner',
|
|
94
|
+
assets: ['metric_daily_gmv'],
|
|
111
95
|
summary: '对比近两次口径版本定义。口径变化 → 支持 H2。',
|
|
112
96
|
verdictTrue: '近两次口径定义不一致', verdictFalse: '口径定义逐字一致' },
|
|
113
|
-
{ id: 'T3.1', kind: '
|
|
97
|
+
{ id: 'T3.1', kind: 'check_point', layer: 'type', title: 'unknown 占比', costMinutes: 2, automation: 'auto', owner: '@duty',
|
|
98
|
+
assets: ['dim_channel_df'],
|
|
114
99
|
summary: '维表 join 后 unknown 占比。显著升高 → 支持 H3。',
|
|
115
100
|
verdictTrue: 'unknown 占比 > 5%', verdictFalse: 'unknown 占比 ≤ 5%' },
|
|
116
|
-
{ id: 'T4.1', kind: '
|
|
101
|
+
{ id: 'T4.1', kind: 'check_point', layer: 'type', title: '主键唯一性', costMinutes: 3, automation: 'auto', owner: '@duty',
|
|
102
|
+
assets: ['dwd_ord_di'],
|
|
117
103
|
summary: '主键唯一性检查。通过 → 否定 H4。这是最常被误判的一条。',
|
|
118
104
|
verdictTrue: '存在重复主键', verdictFalse: '主键唯一 → 否定 H4' },
|
|
119
|
-
{ id: 'T5.1', kind: '
|
|
105
|
+
{ id: 'T5.1', kind: 'check_point', layer: 'type', title: '事件时间分布', costMinutes: 8, automation: 'auto', owner: '@duty',
|
|
106
|
+
assets: ['dwd_ord_di'],
|
|
120
107
|
summary: '分区内事件时间分布。跨天 → 支持 H5。',
|
|
121
108
|
verdictTrue: '分区内事件时间跨出 T-1 单日窗口', verdictFalse: '事件时间全部落在 T-1 内' },
|
|
122
|
-
{ id: 'T7.1', kind: '
|
|
109
|
+
{ id: 'T7.1', kind: 'check_point', layer: 'type', title: '查缓存时间戳', costMinutes: 2, automation: 'auto', owner: '@duty',
|
|
110
|
+
assets: ['bi_daily_dashboard'],
|
|
123
111
|
summary: '缓存时间正常并不能否定 H7 —— 便宜检查给不出结论。',
|
|
124
112
|
verdictTrue: '缓存时间戳过期', verdictFalse: '缓存时间正常 —— 注意:这一条**不足以**否定 H7' },
|
|
125
|
-
{ id: 'T7.2', kind: '
|
|
113
|
+
{ id: 'T7.2', kind: 'check_point', layer: 'type', title: '直连明细对账', costMinutes: 35, automation: 'manual', owner: '@analyst',
|
|
114
|
+
assets: ['dwd_ord_di'],
|
|
126
115
|
summary: '明细对账一致 → 否定 H7。要否定它必须做这次贵检查。',
|
|
127
116
|
verdictTrue: '明细与报表数字不一致', verdictFalse: '明细与报表一致 → 否定 H7' },
|
|
128
117
|
|
|
129
118
|
// ── 引用层 ────────────────────────────────────────────────────────────
|
|
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' },
|
|
119
|
+
{ id: 'dwd_ord_di', kind: 'asset', layer: 'reference', title: 'dwd_ord_di', assetType: 'table' },
|
|
120
|
+
{ id: 'ods_order_sync', kind: 'asset', layer: 'reference', title: 'ods_order_sync', assetType: 'job' },
|
|
121
|
+
{ id: 'dim_channel_df', kind: 'asset', layer: 'reference', title: 'dim_channel_df', assetType: 'table' },
|
|
122
|
+
{ id: 'metric_daily_gmv', kind: 'asset', layer: 'reference', title: 'metric_daily_gmv', assetType: 'metric' },
|
|
123
|
+
{ id: 'bi_daily_dashboard', kind: 'asset', layer: 'reference', title: 'bi_daily_dashboard', assetType: 'linkage' },
|
|
133
124
|
|
|
134
|
-
// ──
|
|
135
|
-
//
|
|
136
|
-
//
|
|
125
|
+
// ── 实例层:案例节点是**图上的桩**(正文与有序路径住在案例卡片里) ──────
|
|
126
|
+
// 标题必须与 `SEED_CASES[].title` 是同一个字符串,否则同一份知识会有两份标题
|
|
127
|
+
// (而且还真的不一致过:「只剩」vs「只有」)。画布要在标签前显示案例 id,
|
|
137
128
|
// 那是渲染层的事(见 `nodeStyleFor` 的 labelText)。
|
|
138
129
|
{ id: 'CASE-001', kind: 'case', layer: 'instance', title: '日报 GMV 为 0' },
|
|
139
130
|
{ id: 'CASE-002', kind: 'case', layer: 'instance', title: '订单数只有昨日 12%' },
|
|
140
131
|
{ 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
132
|
],
|
|
147
133
|
edges: [
|
|
148
134
|
// 层内:现象 → 假设(含一条僵尸边,用来演示「权重过期」)
|
|
@@ -169,7 +155,7 @@ export const SEED_GRAPH: AttributionGraphData = {
|
|
|
169
155
|
{ id: 'e-s3-h5', source: 'S3', target: 'H5', kind: 'may_be_caused_by' },
|
|
170
156
|
{ id: 'e-s3-h7', source: 'S3', target: 'H7', kind: 'may_be_caused_by' },
|
|
171
157
|
|
|
172
|
-
// 层内:假设 →
|
|
158
|
+
// 层内:假设 → 检查点(H6 故意没有,它就是图上的空区)
|
|
173
159
|
{ id: 'e-h1-t11', source: 'H1', target: 'T1.1', kind: 'verified_by' },
|
|
174
160
|
{ id: 'e-h1-t12', source: 'H1', target: 'T1.2', kind: 'verified_by' },
|
|
175
161
|
{ id: 'e-h2-t21', source: 'H2', target: 'T2.1', kind: 'verified_by' },
|
|
@@ -179,7 +165,7 @@ export const SEED_GRAPH: AttributionGraphData = {
|
|
|
179
165
|
{ id: 'e-h7-t71', source: 'H7', target: 'T7.1', kind: 'verified_by' },
|
|
180
166
|
{ id: 'e-h7-t72', source: 'H7', target: 'T7.2', kind: 'verified_by' },
|
|
181
167
|
|
|
182
|
-
// 层内:假设 →
|
|
168
|
+
// 层内:假设 → 失败原因(切面)
|
|
183
169
|
{ id: 'e-h1-f1', source: 'H1', target: 'F1', kind: 'categorized_as' },
|
|
184
170
|
{ id: 'e-h2-f2', source: 'H2', target: 'F2', kind: 'categorized_as' },
|
|
185
171
|
{ id: 'e-h3-f3', source: 'H3', target: 'F3', kind: 'categorized_as' },
|
|
@@ -188,21 +174,21 @@ export const SEED_GRAPH: AttributionGraphData = {
|
|
|
188
174
|
{ id: 'e-h6-f5', source: 'H6', target: 'F5', kind: 'categorized_as' },
|
|
189
175
|
{ id: 'e-h7-f4', source: 'H7', target: 'F4', kind: 'categorized_as' },
|
|
190
176
|
|
|
191
|
-
//
|
|
177
|
+
// 跨层:资产反向索引(这条假设**落在**哪个对象上)
|
|
192
178
|
{ id: 'e-a-dwd-h1', source: 'dwd_ord_di', target: 'H1', kind: 'indexed_from' },
|
|
193
179
|
{ id: 'e-a-ods-h1', source: 'ods_order_sync', target: 'H1', kind: 'indexed_from' },
|
|
194
180
|
{ id: 'e-a-dim-h3', source: 'dim_channel_df', target: 'H3', kind: 'indexed_from' },
|
|
195
181
|
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
{ id: 'e-
|
|
199
|
-
{ id: 'e-
|
|
200
|
-
{ id: 'e-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
{ id: 'e-
|
|
204
|
-
{ id: 'e-
|
|
205
|
-
{ id: 'e-
|
|
182
|
+
// 跨层:检查点 → 资产(`queries`,v1.3)。这条检查**要去查**哪些对象 ——
|
|
183
|
+
// 与上面那条 `indexed_from` 是两条边:两端不同,回答的问题也不同。
|
|
184
|
+
{ id: 'e-t11-dwd-q', source: 'T1.1', target: 'dwd_ord_di', kind: 'queries' },
|
|
185
|
+
{ id: 'e-t12-ods-q', source: 'T1.2', target: 'ods_order_sync', kind: 'queries' },
|
|
186
|
+
{ id: 'e-t21-metric-q', source: 'T2.1', target: 'metric_daily_gmv', kind: 'queries' },
|
|
187
|
+
{ id: 'e-t31-dim-q', source: 'T3.1', target: 'dim_channel_df', kind: 'queries' },
|
|
188
|
+
{ id: 'e-t41-dwd-q', source: 'T4.1', target: 'dwd_ord_di', kind: 'queries' },
|
|
189
|
+
{ id: 'e-t51-dwd-q', source: 'T5.1', target: 'dwd_ord_di', kind: 'queries' },
|
|
190
|
+
{ id: 'e-t71-bi-q', source: 'T7.1', target: 'bi_daily_dashboard', kind: 'queries' },
|
|
191
|
+
{ id: 'e-t72-dwd-q', source: 'T7.2', target: 'dwd_ord_di', kind: 'queries' },
|
|
206
192
|
|
|
207
193
|
// 跨层:案例实例化(三个案例各归各的现象,但收敛到**同一批假设**)
|
|
208
194
|
{ id: 'e-case1-s1', source: 'CASE-001', target: 'S1', kind: 'instance_of', count: 1 },
|
|
@@ -211,7 +197,7 @@ export const SEED_GRAPH: AttributionGraphData = {
|
|
|
211
197
|
],
|
|
212
198
|
}
|
|
213
199
|
|
|
214
|
-
/** 三个 seed
|
|
200
|
+
/** 三个 seed 案例卡片,与上面图谱里的节点 id 对齐(0021 §11)。 */
|
|
215
201
|
export const SEED_CASES: AttributionCase[] = [
|
|
216
202
|
{
|
|
217
203
|
id: 'CASE-001',
|
|
@@ -289,3 +275,119 @@ export const SEED_CASES: AttributionCase[] = [
|
|
|
289
275
|
],
|
|
290
276
|
},
|
|
291
277
|
]
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* 三次排查的**过程记录**(`agent_diagnosis_case`)。
|
|
281
|
+
*
|
|
282
|
+
* 它们与 `SEED_CASES` 一一对应,但**不是同一份东西**:这里是 Agent 跑出来的原始记录
|
|
283
|
+
* (每条检查点真跑了什么、看到什么、这个结果算不算数),`SEED_CASES` 是之后归纳出来的
|
|
284
|
+
* 案例卡片(要经人确认才生效)。一个回答「当时怎么走的」,一个回答「结论是什么」。
|
|
285
|
+
*
|
|
286
|
+
* `E7` 是 CASE-001 里那次**贵的否定**:T7.2 直连明细对账推翻了 H7。它不在案例的
|
|
287
|
+
* 主路径上(主路径早就确认了 H1),但它是这次排查最贵的一条知识 —— 40 分钟的误导段
|
|
288
|
+
* 正是靠它收尾的。
|
|
289
|
+
*/
|
|
290
|
+
export const SEED_RUNS: DiagnosisRunRecord[] = [
|
|
291
|
+
{
|
|
292
|
+
runId: 'RUN-20260811-1',
|
|
293
|
+
symptomId: 'S1',
|
|
294
|
+
startedAt: '2026-08-11T02:55:00+08:00',
|
|
295
|
+
durationMinutes: 65,
|
|
296
|
+
path: SEED_CASES[0]!.path,
|
|
297
|
+
evidence: [
|
|
298
|
+
{
|
|
299
|
+
id: 'E1', checkPointId: 'T1.1',
|
|
300
|
+
query: "select count(*) from dwd_ord_di where dt = '2026-08-10'",
|
|
301
|
+
result: '分区不存在', verdict: 'supports', hypothesisId: 'H1',
|
|
302
|
+
why: '与调度系统日志一致:ods_order_sync 02:40 实例 failed 且未启用重试,下游无输入',
|
|
303
|
+
at: '2026-08-11T02:58:00+08:00', by: '@duty', rawRef: 'scheduler://ods_order_sync/instance/20260811',
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: 'E7', checkPointId: 'T7.2',
|
|
307
|
+
query: "select sum(gmv) from dwd_ord_di_detail where dt = '2026-08-10'",
|
|
308
|
+
result: '明细与报表一致', verdict: 'refutes', hypothesisId: 'H7',
|
|
309
|
+
why: '明细对账一致,缓存不影响明细 —— 这一条花了 35 分钟,是唯一能否定 H7 的检查',
|
|
310
|
+
at: '2026-08-11T03:40:00+08:00', by: '@analyst',
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
rootCause: {
|
|
314
|
+
hypothesisId: 'H1', id: 'C1',
|
|
315
|
+
text: 'ODS 任务 ods_order_sync 02:40 失败且未启用重试,dwd_ord_di/dt 分区未产出。',
|
|
316
|
+
fixAction: '补 dwd_ord_di 分区;给 ods_order_sync 加失败告警与自动重试;分区存在性检查加入日报前置校验。',
|
|
317
|
+
confirmedAt: '2026-08-11T04:00:00+08:00',
|
|
318
|
+
},
|
|
319
|
+
misleading: SEED_CASES[0]!.misleading ? [SEED_CASES[0]!.misleading] : [],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
runId: 'RUN-20260812-1',
|
|
323
|
+
symptomId: 'S2',
|
|
324
|
+
startedAt: '2026-08-12T09:10:00+08:00',
|
|
325
|
+
durationMinutes: 22,
|
|
326
|
+
path: SEED_CASES[1]!.path,
|
|
327
|
+
evidence: [
|
|
328
|
+
{
|
|
329
|
+
id: 'E2a', checkPointId: 'T1.1',
|
|
330
|
+
query: "select count(*) from dwd_ord_di where dt = '2026-08-11'",
|
|
331
|
+
result: '分区存在且有数据', verdict: 'refutes', hypothesisId: 'H1',
|
|
332
|
+
why: '分区有数据,H1 不成立 —— 1 分钟就砍掉了一条先验最高的假设',
|
|
333
|
+
at: '2026-08-12T09:12:00+08:00', by: '@duty',
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
id: 'E2b', checkPointId: 'T4.1',
|
|
337
|
+
query: "select order_id, count(*) c from dwd_ord_di where dt = '2026-08-11' group by order_id having c > 1 limit 10",
|
|
338
|
+
result: '主键唯一,无重复', verdict: 'refutes', hypothesisId: 'H4',
|
|
339
|
+
why: '主键唯一性检查通过,无重复行 —— H4 被否定',
|
|
340
|
+
at: '2026-08-12T09:16:00+08:00', by: '@duty',
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
id: 'E2c', checkPointId: 'T3.1',
|
|
344
|
+
query: "select channel, count(*) from dwd_ord_di where dt = '2026-08-11' group by channel order by 2 desc",
|
|
345
|
+
result: 'unknown 占比 88%', verdict: 'supports', hypothesisId: 'H3',
|
|
346
|
+
why: 'unknown 占比 88%,且缺口集中在新增的两个渠道 —— 与维表未补录一致',
|
|
347
|
+
at: '2026-08-12T09:24:00+08:00', by: '@duty',
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
rootCause: {
|
|
351
|
+
hypothesisId: 'H3', id: 'C2',
|
|
352
|
+
text: '新增渠道未补录维表,dim_channel_df join 落 unknown 后被 where channel is not null 过滤。',
|
|
353
|
+
fixAction: '补录渠道维表;把 unknown 占比纳入日常巡检;下游过滤改为「先报警再过滤」。',
|
|
354
|
+
confirmedAt: '2026-08-12T09:32:00+08:00',
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
runId: 'RUN-20260813-1',
|
|
359
|
+
symptomId: 'S3',
|
|
360
|
+
startedAt: '2026-08-13T14:05:00+08:00',
|
|
361
|
+
durationMinutes: 35,
|
|
362
|
+
path: SEED_CASES[2]!.path,
|
|
363
|
+
evidence: [
|
|
364
|
+
{
|
|
365
|
+
id: 'E3a', checkPointId: 'T4.1',
|
|
366
|
+
query: "select user_id, count(*) c from dwd_dau_di where dt = '2026-08-12' group by user_id having c > 1 limit 10",
|
|
367
|
+
result: '主键唯一,无重复', verdict: 'refutes', hypothesisId: 'H4',
|
|
368
|
+
why: '主键唯一性通过 —— 放大不是重复计数造成的',
|
|
369
|
+
at: '2026-08-13T14:10:00+08:00', by: '@duty',
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
id: 'E3b', checkPointId: 'T7.1',
|
|
373
|
+
query: 'select max(refresh_at) from bi_daily_dashboard_meta',
|
|
374
|
+
result: '缓存时间正常', verdict: 'inconclusive', hypothesisId: 'H7',
|
|
375
|
+
why: '缓存时间正常并不能否定 H7(T7.1 的 verdict_false 已经写明);要否定它必须做 35 分钟的直连明细对账 —— 这一条给不出结论',
|
|
376
|
+
at: '2026-08-13T14:18:00+08:00', by: '@duty',
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
id: 'E3c', checkPointId: 'T5.1',
|
|
380
|
+
query: "select event_time, count(*) from dwd_dau_di where dt = '2026-08-12' group by 1 order by 1 limit 5",
|
|
381
|
+
result: '分区内事件时间跨天', verdict: 'supports', hypothesisId: 'H5',
|
|
382
|
+
why: '事件时间跨出 T-1 单日窗口,且只有这一天异常 —— 与上游重跑补写一致',
|
|
383
|
+
at: '2026-08-13T14:34:00+08:00', by: '@duty',
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
rootCause: {
|
|
387
|
+
hypothesisId: 'H5', id: 'C3',
|
|
388
|
+
text: '上游重跑把跨天事件补写进 T-1 分区,事件时间与处理时间边界被跨越。',
|
|
389
|
+
fixAction: '重跑加事件时间边界校验;分区写入前检查事件时间下界。',
|
|
390
|
+
confirmedAt: '2026-08-13T14:40:00+08:00',
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
]
|