Files
digital-me-history/digital-me-backend/src/biannian-design.md
T
admin 0593ff7e62
nginx serve /uploads direct (audio speed) / patch-nginx (push) Failing after 1m34s
数字我 Digital Me:全量入库(大文件走 Git LFS)
2026-10-10 16:24:43 +08:00

16 KiB
Raw Blame History

编年 · 层 · 影响 —— 建模设计(biannian-design.md)

第一步只交设计,不改一条数据、不建前端。全部数字都是 node 实跑 src/tianxia.js 打印出来的,不是手数(脚本见文末「审计口径」)。基线:npm test = 601 通过(本步未动)。


0. 结论速览

事 数 状态
大事件(shi)总数 932 25 朝
层 layer 已标 932 / 932(100%) ✅ ①「每事标层」实际上已经做完
层分布 事 830 / 制 92 / 道 10 道极吝啬(两千年才 10 个),符合判据
impact 已标 0 / 102 制道事件 ❌ ②「制/道连下游影响」= 本产品线真正的空白,全部待做
层值编码分裂 23 朝 pinyin,2 朝(qin/beisong) 用汉字 ⚠ 需归一(见 §2.1)
zaichang 形状分裂 array 7 朝 / string 12 朝 / 无 6 朝 ⚠ 前端必须两种都吃(见 §2.4)

一句话:layer 已铺满,不用重做;产品线的正主功能是 impact(影响链),102 个制/道 事件一个都没连下游。补编年(③)是第三优先,且受「双证原文」红线约束,只补真查得实的。


1. 事件(shi)字段现状 —— 实测

1.1 读取路径(不用改)

src/chao/<code>.js 各 export const CHAO_SHI → src/tianxia.js 第 290 行原样挂到 CHAO[code].shi(passthrough,一个字段都不删)→ shiAt() / chenShiByReign() 按年过滤后 原样带出。⇒ 你在 chao 文件里给事件加的 layer/impact,tianxia 自动带出,无需改 tianxia (唯一可选的小改:§2.3 的防御性 normalizer)。 KG:src/kg.js 第 306–310 行为每条 shi 建 event 节点,且 raw: s 挂整条原始对象 ⇒ node.raw.layer / node.raw.impact 自动可用,别碰 kg.js(它派生)。

1.2 字段清单(当前两种 shape,都要向后兼容)

共有字段(所有朝)

字段 类型 说明
year number 公元年(负=公元前)。KG 按 ${code}:${year} 建索引
shi string 本纪原文逐字(层/影响之外,这是唯一的"原文"栏)
juan string 卷次,如 《漢書》卷五
layer 'shi'|'zhi'|'dao' 见 §2.1。推演(我们的读法)
kind 'yuanwen' shi 栏的性质;全部 yuanwen(逐字原文)
layerWhy / layerNote string 强制:每条层判据给理由,不许空标
zaichang array | string 「那年什么位阶被卷进去」,推演(kind:'tuiyan' / zaichangKind:'tuiyan')

可选字段(部分朝已有):yue(月) gz(干支) jinian(纪年) source(默认benji) witnesses(见证数,xin/wu/xixia 有) crossWitness zhengwu biaoCross shuangzheng yearOpen/yearNote(系年存疑) weiFa(从未生效的制)。—— 新 schema 一律叠加,不动这些。

1.3 layer 现状:100% 已标,但编码分裂(⚠ 待归一)

  • 23 朝用 pinyin 'shi'/'zhi'/'dao'(xihan/ming/xixia/shuhan/… 及 xin 的工厂函数 S(...) 第 5 参,实测 s.layer==='shi')。
  • 2 朝用汉字 '事'/'制'/'道':qin.js(22 条) 与 beisong.js(46 条)。
  • 语义(各朝文件头一致,判据同一把尺):
    • 事 shi(1–50 年):一场仗、一次废立、一个人的死、一次亡国。绝大多数。
    • 制 zhi(50–500 年):一个制度的确立/废除(官制、律、铸钱、学校、科举定式、田制…)。
    • 道 dao(500+ / 硬测「到公元 1500 年还在起作用吗」):改变了此后千年且今仍运转。极吝啬。

1.4 zaichang 形状分裂(⚠ 前端契约)

  • array [{wei, shuo}](7 朝):xihan xin shuhan wu liusong beiqi liao —— 每项另标 kind:'tuiyan'。
  • string(12 朝):dongjin beiwei liang sui tang wudai beisong xixia jin nansong ming +chen(部分) —— 另有 zaichangKind:'tuiyan'。
  • 无 zaichang(6 朝):qin donghan wei xijin nanqi beizhou +chen(部分)。
  • ⇒ 这是既有的历史遗留,不在本产品线强行迁移(与 layer/impact 正交)。前端 Biannian.vue 必须同时处理 array / string / 缺三态(§2.4)。

1.5 impact 现状:0,且有一个命名撞车(无害,但要说清)

  • 没有任何一条 事件带下游影响字段。102 个制/道候选全空。
  • ⚠ 全库 grep impact: 有 7 处命中(xin.js 1 + xixia.js 6)—— 那是 字形/异文审计表 (WITNESS 行)里的 impact,意思是「这个异体字涉不涉文义」(如 不涉文义), 挂在 WITNESS 行对象上,不在 CHAO_SHI 事件上。⇒ 两个不同对象命名空间,运行时不冲突。 但为免人读混,本设计的事件级 impact 语义在 §2.2 写死;老板已点名字段叫 impact,沿用。

2. Schema 设计(向后兼容,只叠加不破坏)

2.1 layer(已存在,本步只做归一决策)

规范值 = pinyin 'shi' | 'zhi' | 'dao'(取 23:2 的多数派 + 与 kind:'yuanwen'/'tuiyan' 的罗马化惯例一致 + xin 已用 s.layer==='shi' 过滤)。汉字 事/制/道 只作显示 label。

⚠ 这一条推翻老板任务书草案里写的 layer:'事'|'制'|'道'(汉字)—— 草案是示意 label,不是存储值规约;把 23 个文件改成汉字,风险远大于把 2 个改成 pinyin。 建议:qin.js / beisong.js 的第二步 agent 把本文件层值 事→shi 制→zhi 道→dao 归一; 并在 tianxia 加一行防御性 normalizer(§2.3)兜底,保证前端永远只见 pinyin。

  • 层是推演:layer 值本身就是「我们的读法」,无须再标 kind;layerWhy 强制给理由。

2.2 impact(新字段,只加在制/道事件上,这是产品线正主)

impact: {
  reach: 'dangchao' | 'houshi' | 'qiannian',   // 影响半径。label:当朝/后世/千年
  kind:  'yuanwen'  | 'tuiyan',                // 与事件级 kind 同词表:原文明引 vs 推演
  reason: string,                              // 【强制】史学通说 / 制度史依据,说人话
  to?: [                                       // 【可选】下游落点,可多个
    { code?: string, year?: number, label: string }
  ],
  cite?: string,                               // 仅 kind:'yuanwen' 时【强制】:原文明引句
  witnesses?: number,                          // kind:'yuanwen' 时建议≥2(双证)
  reachWhy?: string                            // 可选:半径判据(仿 layerWhy)
}

字段规约(照史学红线,逐条硬性)

  1. 只给 layer==='zhi'|'dao' 的事件加 impact;layer==='shi' 不加(事没有下游影响链, 有的话它就不是"事")。⇒ impact 天生是 102 个候选的子集。
  2. reach 与 layer 有对应但不强绑:制→常 houshi,道→常 qiannian;用独立的下游年代判, 在 reachWhy 写清(如「至 1905 科举废,凡 2041 年 ⇒ qiannian」)。
  3. kind:'tuiyan'(推演,绝大多数):reason 强制,必须是制度史通说 / 后世明引, ✗ 不许编造「A 导致 B」的因果;拿不准、无据 ⇒ 不写那条 impact,别硬连(红线)。
  4. kind:'yuanwen'(原文明引后世征引,如「漢承秦制」):cite 强制、逐字、 curl -sk 双证(witnesses>=2),字形照录(爲/為)。
  5. to[].label 强制(人读的落点描述,如「至今农历正月仍为岁首」);code/year 可选 —— 落点若在本库 25 朝之内就填(KG 可 code→chaoId、code:year→evt:code:year:idx 连边); 落点在库外(清/民国/今)只填 label。⇒ 既支持「千年后 X 朝仍在用」,也支持「至今仍运转」。
  6. 影响链可级联:如 jin 1153 改燕京为中都 → to:[{code:'ming',year:1420,label:'永樂定北京为京师'}] → 千年(元明清至今为都)。级联在数据里天然成图,KG/前端各自渲染。

2.3 兼容与迁移

  • 不破坏:impact 是新可选字段;老事件无 impact,前端/ KG 判 if (e.impact) 即可。
  • 归一 qin/beisong:第二步各自 agent 把 layer 汉字→pinyin(并行改不同文件,不冲突)。
  • tianxia 可选小改(唯一允许动 tianxia 的地方):在 shi passthrough 处加一行 layer normalizer(事→shi 制→zhi 道→dao)兜底,防某朝漏改。非必须,归一到位就不用。
  • KG:零改动。node.raw.impact 自动可用;将来若要 impact 边(制→后世事),那是 KG 线 自己的 kg.js 改动,不属于本产品线。

2.4 前端 Biannian.vue 契约(第二步建,这里先定契约)

  • 主视图:编年轴(按 year 排)+ 层筛选(事/制/道,pinyin→汉字 label)。
  • 影响视图:点一个制/道事件 → 展开 impact(reach 徽标、reason、to 落点、cite/推演标注); to.code/year 命中本库则可跳转到下游事件(级联链)。
  • 必须两种 zaichang 都吃:array [{wei,shuo}] 渲染成列表;string 直接渲染;缺则不显。
  • 诚实标注(照本仓铁律):层与影响都要显式标「推演」;kind:'yuanwen' 的 impact 显示 cite; 西夏等源限朝的"薄"要说清是史料所限(§3.4),不许长成和"我们没做"同一句话。

3. 编年覆盖审计 + 补缺清单

3.1 全表覆盖(实测,按起年排)

朝 起讫 跨年 帝 事件n 事/制/道 每百年密度 判定
秦 qin -221~-207 14 2 22 17/2/3 157 充足(超密)
西汉 xihan -202~8 210 12 18 10/6/2 8.6 ★最薄(密度全表最低)
新 xin 9~23 14 1 25 16/9/0 179 充足(制富)
东汉 donghan 25~220 195 12 42 36/6/0 21.5 偏薄
曹魏 wei 220~265 45 5 22 16/6/0 48.9 充足
蜀汉 shuhan 221~263 42 2 53 52/1/0 126 充足(超密)
孙吴 wu 222~280 58 4 26 23/3/0 44.8 充足
西晋 xijin 265~316 51 4 21 17/3/1 41.2 充足
东晋 dongjin 317~420 103 11 23 18/5/0 22.3 偏薄
北魏 beiwei 386~534 148 12 127 120/7/0 85.8 充足(超密)
刘宋 liusong 420~479 59 8 128 126/2/0 217 充足(超密)
南齐 nanqi 479~502 23 7 21 21/0/0 91 充足;制/道=0
梁 liang 502~557 55 4 24 23/1/0 43.6 充足
北齐 beiqi 550~577 27 6 17 16/1/0 63 充足
北周 beizhou 557~581 24 5 28 27/1/0 117 充足
陈 chen 557~589 32 5 30 30/0/0 94 充足;制/道=0
隋 sui 581~618 37 3 37 26/9/2 100 充足(制/道极富,最佳 impact 锚朝)
唐 tang 618~907 289 21 46 45/1/0 15.9 ★薄(289 年只 46 事,且制仅 1)
五代 wudai 907~960 53 14 42 40/2/0 79 充足
辽 liao 916~1125 209 9 43 39/4/0 20.6 偏薄
北宋 beisong 960~1127 167 9 46 42/4/0 27.5 尚可
西夏 xixia 1038~1227 189 10 20 9/11/0 10.6 源限(无正史,别硬补,见 §3.4)
金 jin 1115~1234 119 10 21 15/5/1 17.6 偏薄
南宋 nansong 1127~1279 152 10 22 21/1/0 14.5 ★薄(且制仅 1)
明 ming 1368~1644 276 16 28 25/2/1 10.1 ★薄(受"抠本纪"纪律约束,见 §3.3)

世界观地板建议(每朝至少要撑得起的):(a) 每位在位皇帝 ≥1 件;(b) 该朝所有制/道转折点在场; (c) 重大战/乱/亡国节点在场。密度目标只对下面的"薄"朝加压,其余充足朝优先做 impact,不硬加事。

3.2 impact 优先锚点(②的正主活,102 个候选,先做这批)

10 个「道」事件 —— 千年影响链,最高优先(impact 必做,reach 多为 qiannian):

朝 年 事 建议下游落点(推演,需据)
qin -221 定「皇帝」号 → 帝制沿用至 1912(label)
qin -221 罢分封·置郡县 → 中国地方行政骨架至今;原文可引「漢承秦制」(yuanwen)
qin -221 一法度衡石丈尺·车同轨·书同文 → 文字/度量统一至今
xihan -136 置五经博士 → 经学官学至 1905 科举废,2041 年(层已析,直接抬成 impact)
xihan -104 正历·以正月为岁首 → 农历正月至今 2130 年
xijin 268 泰始律令成 → 律典体例下沿(→隋开皇律→唐律)
sui 581 行新律(开皇律) → 唐律之母本(houshi/qiannian)
sui 605 开通济渠(大运河) → 南北经济动脉至今
jin 1153 改燕京为中都 → 级联 ming 1420 定北京→元明清至今为都
ming 1380 罢中书·废丞相 → 无相皇权独揽至 1912(清亦不设);层已析

92 个「制」事件里的高价值链(示例,非穷举,均推演·需制度史通说据): beiwei 485 均田 → sui 609 均田 → tang 租庸调 → tang 780 两税法(均田制的建立→鼎盛→瓦解, 一条可级联的赋税史主线);xijin 265 中正六条 → 九品中正→门阀;beiwei 486 三长 → 隋唐乡里; sui 583 罢郡(州县二级)→ 后世地方两级制。⇒ 建议第二步优先把这几条主线连成级联链, 最能体现「一步制度变革,千年后还在起作用吗」。

3.3 补事件清单(③,第三优先,逐条双证原文,查不实宁可不补)

  • TIER A(薄 + 高权重 + 正史充足,建议多补)
    • 西汉 xihan(+10~14 事):其自身 CHAO_COVERAGE.shi 已自认「事層遠遠不全」—— 高帝/惠帝/高后/文帝/昭帝/宣帝/元帝/哀帝 编年事几乎没取。补:文景削藩·推恩、武帝征匈奴/张骞、 昭宣中兴、霍光废立、王莽代汉铺垫。双证《汉书》本纪 + 卷十九表。
    • 唐 tang(+15~20 事):289 年仅 46 事、制仅 1,最不撑世界观。补:玄武门、贞观、永徽律(制)、 武周代唐、开元、安史之乱、元和中兴、甘露之变、会昌灭佛、黄巢、朱温代唐。双证新旧唐书。
    • 明 ming(+6~10,受约束):⚠ 本朝守「抠本纪」纪律,一条鞭法/隆庆开关等在志不在纪—— 按红线不硬塞进 CHAO_SHI,或另标 source 单列。可补本纪确有的:土木/夺门已在; 可加 郑和(已)、大礼议(已)。补量有限,别为凑数破纪律。
  • TIER B(薄,补制 + 关键事)
    • 南宋 nansong(+6~10):绍兴和议、秦桧擅政、隆兴/开禧北伐、端平入洛、崖山亡国;制层补科举/文官制。
    • 金 jin(+4~8):大定之治、贞祐南迁、蒙金战争(海陵迁都已在)。
    • 辽 liao(+4~6):承天太后摄政、头下军州制(澶渊已在)。
    • 东汉 donghan(+4~8):党锢、外戚宦官更替、黄巾。
    • 北宋 beisong:46 尚可;优先 impact 而非加事(庆历新政/靖康可补)。
  • TIER C(充足 / 源限,不加或少加)
    • 隋、秦、蜀汉、刘宋、北魏、新 及南北朝诸短朝:充足,优先做 impact。
    • 南齐 / 陈:制道=0 —— 若逐卷本纪确有制度条(如删定律科),可补 1~2 条制;无则不硬造。

3.4 ★ 西夏特别说明(防止有人去"补薄")

西夏 20 事 / 189 年看着最薄,但这是源限不是缺工:二十四史无《夏史》,只能取 《宋史·夏国传》《辽史》《金史》外国传的转述。照红线:查不实宁可不补。 它的"薄"是诚实的, 与本仓「三种没有」(②我们瞎 / ③史官没记)同理——前端必须把它标成"源限",不许和"我们没做完" 长成同一句"暂无"。且西夏 11 制 / 0 道也是老实话(西夏之制随国亡而死,无一活到 1500 年)。


审计口径(实跑,不手数)

  • node src/tianxia.js 的 count() = {chao:25, di:202, shi:932};层分布、密度、道/制清单由 scratchpad 脚本 biannian_audit.mjs / dao_zhi_dump.mjs 实跑 allChao() 打印。
  • 层值 pinyin/hanzi 分裂由逐文件 grep -oE "layer: ?'(shi|zhi|dao)'" vs '(事|制|道)' 计数得: 仅 qin(22 汉字)、beisong(46 汉字),余 23 朝 pinyin。
  • 基线:npm test = 601 pass(本步只写本 .md,未动数据/代码)。