Files
Jyotisha/docs/tasks/PROGRESS-consult-evidence-card-20260927.md
T
Jesse_ChenandClaude Opus 5.5 cd4dde9dfc
Independent Staging Quality Gate / validate (push) Successful in 12m11s
Independent Staging Quality Gate / publish (push) Successful in 3m18s
docs(tasks): consult evidence-card acceptance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 03:02:06 +08:00

179 lines
23 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.
# PROGRESS · 普通对话改用「数据卡」· 2026-09-27
- 执行方式:直接执行(产品负责人授权子代理执行;Claude 事后独立验收)
- 基线:`origin/staging` `599fe7a9`(任务书提交)。开工时核对 `eef0cb74`(BUG-1053)与 `560d4fc2`(数据卡调研门禁补修)都是它的祖先(`base-ok`);`d8d03b5a` 同样在内。
- 分支:`codex/consult-evidence-card-20260927`,工作树 `.worktrees/consult-evidence-card-20260927`(本地提交,未推送)
- BUG 编号:修 BUG-1054;新缺陷 BUG-1059(BUG-1055~1058 由并行的校正任务预留,开工与提交时核对 `docs/BUG_HISTORY.md` 最大号为 1054)
- Skill:`jyotish-vedic-astrology` 6.9.16 → 6.9.17
## 提交
| 阶段 | 提交 | 内容 |
| --- | --- | --- |
| T1 | `128f67d6` | BUG-1054:`timingKeys` 放行 Narayana `md/ad/pd` 与 `pratyantar_dasha_timeline`;真实引擎 golden(3 张公开 AA 盘)+ 回归 |
| T2 | `4651f8bc` | 新领域 `parents` / `children`(引擎仍走 `family`) |
| T3 | `ffa107a5` | 数据卡构建器 + 模型可见视图(答题契约 + 卡),去掉单领域 `consultations` 整包复制 |
| T4 | `53b69498` | 系统提示与 Skill 对齐,Skill 6.9.17 |
| T5 | `dabc9652` | 只读补取工具(每轮一次、请求级缓存);回答中途补取的防截断 / 防重复;BUG-1059 |
| T6 | `b3f84fc8` | 6 项反馈记录(只写日志) |
| T7 | 本提交 | BUG 历史、CHANGELOG、DESIGN / VOICE、本记录、真机清单、任务索引 |
## 结论
| 项 | 结果 |
| --- | --- |
| T1 BUG-1054 | 完成。golden 回归逐盘断言 Narayana 当前 md/ad/pd(星座、主星、年数、起止年龄)与 `remaining_years`、PD 当前段与下一段起止原样出现在 timing 卡;修复前 2/4 失败。状态 resolved(部署后补 run 号) |
| T2 父母 / 子女 | 完成。注册表(中文名 父母 / 子女,别名按任务书)、方法学(无命名清单,如实上报)、`DOMAIN_MUST_USE_LAYERS`(family / parents / children)、zod 枚举与工具说明、回执与思考计划中文名。引擎请求发的是 `family` 的整套路由合同(Python `consultation_plan_contract.py` 逐项校验),不改 Python;会话主题写入口只收原十个(`chat_sessions.theme` CHECK 不动,不改数据库) |
| T3 数据卡 | 完成。`frontend/src/lib/consultation-evidence-card.ts`(纯函数);模型只看答题契约 + 卡;30 次单领域测量 7,278–15,550 字(改前 132,782–143,603),不含方法学 5,241–7,239;超 12,000 的 9 次全是事业 / 婚恋 / 财富的方法学清单(见「体量」);「本轮技法」逐行一致 |
| T4 提示与 Skill | 完成。「用尽每个已执行层」「must_use_layers 是清单」「technique_audit_table 是调用记录」三句改写为「以数据卡为准,卡外可补取一次」;SKILL.md 与 router 0.7 同步,版本 6.9.17 |
| T5 补取 | 完成(未降级)。见「补取设计与双钟」 |
| T6 反馈 | 只做日志(让步项):赞踩现在只在浏览器状态里,没有落库;`feedback` 恒为 `none`,建表与后台汇总另开单 |
| T7 记录 | 完成 |
## 最终领域 → 技法对照(数据卡)
每张卡都有**基础段**:上升(原始度数)、十二宫星座、行星落宫(星座 / 宫 / 度数 / 星宿 / 逆行 / 庙旺)、功能吉凶(吉 / 凶 / 中性 / Yogakaraka / 宫主归属)、Vimshottari 当前大运 / 子运 / 子子运起止与下一段、大运内全部子运起止、Narayana 当前 md/ad/pd(星座、主星、年数、起止年龄)与剩余年数。**领域段**如下(单一来源:`EVIDENCE_CARD_SPECS`,移植自调研草案 `CARD_SPECS`):
| 领域 | 引擎路由 | 分盘 | 宫(星座 / 宫内星 / 宫主) | 重点行星 | Arudha | Karaka | 其他层 | 与调研草案 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 事业 career | career | D10 | 10 | — | A10 | AmK | 格局、行运、Shadbala | 同 |
| 婚恋 marriage | marriage | D9 | 7 | Venus、Jupiter | UL、A7 | DK | 行运 | 同 |
| 财富 wealth | wealth | D2、D11 | 2、11、9、5 | — | — | — | 格局、Ashtakavarga(这几宫 SAV + 最强 / 最弱星座)、Shadbala | 同 |
| 健康 health | health | D6、D8、D30 | 6、8 | — | — | — | 行运、Shadbala | 同(D30 按 Python 焦点纳入) |
| 学习 education | education | D5、D24 | 5、9 | Mercury、Jupiter | — | — | — | 同(D5 按 Python 焦点纳入) |
| 迁居 migration | migration | D4、D12 | 4、12 | — | — | — | — | 同 |
| 家庭 family | family | D7、D12 | 4、5、9 | — | — | — | — | 同(仅兜底泛问) |
| 父母 parents | **family** | D12 | 4、9 | Sun、Moon | — | — | — | 同 |
| 子女 children | **family** | D7 | 5 | Jupiter | — | PK | — | 同 |
| 年运 annual | annual | D1 | 1 | — | — | — | 行运、Chara 大运 | **新增**(草案没有) |
| 时运 timing | timing | D1、D9 | — | Saturn、Jupiter | — | — | 行运、Chara 大运 | **新增**(草案没有) |
| 综合 general | general | D9、D10、D2 | 1、10、7、2 | — | A10 | — | 格局、行运、Ashtakavarga、Shadbala | 同 |
年运 / 时运草案没有卡,本单按注册表与必用层补了一版(双轨大运已在基础段;D1 / D9 作分盘核对、行运、Chara 大运),请产品与懂印占的人确认。
## 模型可见内容:前后对比(3 张公开 AA 盘 × 10 问法,均值)
改前 = 调研投影脚本在 `599fe7a9` 上对同一批引擎输出的实测;改后 = `scripts/research/measure_consult_evidence_card.ts` 跑生产计算工具(引擎输出取调研缓存)。字符数 = `JSON.stringify` 长度;token 估计 = 字符 / 3.5(调研口径,不是供应商分词器)。
| 问法 | 改前 | 改后 | 其中数据卡 | 答题契约等 | 方法学清单 | 不含方法学 | 改后 / 改前 | 3 盘最大 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 事业 | 142,487 | 13,416 | 5,312 | 777 | 7,313 | 6,088 | 9.4% | 13,494 |
| 婚恋 | 142,766 | 15,476 | 4,980 | 775 | 9,708 | 5,753 | 10.8% | 15,550 |
| 财富 | 139,332 | 13,103 | 5,471 | 777 | 6,841 | 6,247 | 9.4% | 13,125 |
| 健康 | 138,816 | 10,048 | 5,449 | 813 | 3,772 | 6,261 | 7.2% | 10,135 |
| 学习 | 135,229 | 7,473 | 4,651 | 785 | 2,024 | 5,434 | 5.5% | 7,479 |
| 迁居 | 135,309 | 7,459 | 4,596 | 825 | 2,024 | 5,420 | 5.5% | 7,473 |
| 家庭 | 133,114 | 7,519 | 4,666 | 818 | 2,021 | 5,483 | 5.6% | 7,535 |
| 综合 | 135,207 | 9,213 | 6,397 | 780 | 2,022 | 7,176 | 6.8% | 9,276 |
| 父母 | 133,096 | 7,298 | 4,452 | 810 | 2,022 | 5,261 | 5.5% | 7,312 |
| 子女 | 133,098 | 7,313 | 4,465 | 812 | 2,023 | 5,275 | 5.5% | 7,329 |
- 改后约 2,100–4,400 token(改前约 3.8–4.1 万)。
- **超 12,000 的说明**:事业、婚恋、财富 3 × 3 = 9 次超出,原因全部是方法学清单(`methodology`:共用基线 + `career/relationship/finance-timing-strict` + `event_judgment_*.md`,从 live Skill 原文引用,6,841–9,708 字)。它是系统提示点名的顶层键(红线 1),也是 BUG-284 / BUG-287 以来随结果送达的领域检查清单,本单没有截短或拿掉;不含方法学时 30 次全部 ≤ 7,239。若要压到 12,000 以下,只能动 Skill 清单的送达方式,需产品另定。
- 两领域一轮(同一盘):子女 + 学习 9,117(不含方法学 7,067);事业 + 财富 23,921(不含方法学 11,765,方法学 12,141);婚恋 + 事业 26,148(不含方法学 11,125)。基础段只放一份;两个领域段各自带自己的格局 / Shadbala 等层。
- 数据卡本身 4,452–6,461 字,比调研草案(3,169–5,750)多约 700–1,300 字:基础段行星加了度数、星宿、逆行、庙旺(红线 3「原始度数」),大运加了子子运与大运内子运序列(草案时被 BUG-1054 裁空)。
## 答题契约(红线 1):保留与去掉
| 键 | 模型可见 | 说明 |
| --- | --- | --- |
| `status` | 保留 | 值与完整结果一致(测试逐项比) |
| `evidence_contract.answer_policy`(`can_answer_direction` / `can_answer_precise_timing` / `should_lead_with_limitations`,多领域时的合并字段) | 保留 | 原样;多领域仍是最严合并 |
| `evidence_contract.hard_blockers` / `missing_route_layers` / `available_layers` / `user_facing_limitation` | 保留 | 提示里「只有 hard_blockers 非空才说计算失败」「available_layers 里有就不许说没算」照旧 |
| `claim_cards` | 保留 | 内容换成数据卡:`natal_foundation`(基础段本命)、`timing`(基础段时间)、`domain`(领域段) |
| `rectification.boundary` | 保留 | 原样 |
| `methodology` / `domains` / `omitted_domains` / `success` / `question` / `route` | 保留 | 原样 |
| `consultations` | 仅多领域 | 每个领域自己的答题契约(`domain / route / status / evidence_contract / rectification`),不再带整包;单领域的整包复制去掉 |
| `evidence_card`(新) | 新增 | 卡版本、领域、D4 那一行、卡外可补取段名、`gaps` |
| `evidence_contract.technique_audit_table` / `varga_spectrum` / `western_spectrum` / `must_use_layers`、`validation` 卡、`presentation` | 去掉(D3) | 照旧计算并留在服务端:回执与「本轮技法」面板、思考计划、补取工具、报告都用服务端完整结果。`presentation.required_blocks` 里写着 `technique_audit_table`,与「正文不写审计表」矛盾,一并留在服务端 |
| `reference_transparency`、`chart`、`local_layers` | 本来就不是工具结果的顶层键 | 提示里的相关条款是条件句或已改指向卡 |
## 红线测试清单
| 红线 | 测试 |
| --- | --- |
| 1 答题契约 | `consult-evidence-card-20260927`「the model sees the answer contract and the card…」「a two-domain turn…」;`consultation-agentic-runtime`「the merged contract exposes every policy field…」(原测试,不改) |
| 2 事实逐字(golden) | `consult-evidence-card-20260927`「the card copies the engine's own facts verbatim」(上升星座 / 度数、月亮星座 / 宫 / 度数、MD/AD/PD 主星与起止、Narayana 星座与起始年龄、功能吉凶、D12 / D7 / D9 / D10 上升与全部行星落点,3 盘)、「every card value is a value the projection or the engine already holds」(卡上每个标量都能在投影或引擎值里找到,12 领域 × 3 盘,gaps 为空);`consult-projection-timing-20260927`(T1) |
| 3 Part B 覆盖 | `consult-evidence-card-20260927`「every domain's card covers Part B…」(12 领域 × 3 盘:双轨大运、规格里每张分盘、功能吉凶 + 宫主、原始度数与日期) |
| 4 BUG-1053 不回退 | `consult-evidence-lookup-20260927`:写答案那次调用的提示里有卡(`evidence-card-v1`、引擎 PD 起始、Narayana 星座、答题契约,且无审计表 / 西洋 / 研究分盘键);工具前文字不进回答;`content-filter` → `answer_truncated` 不扣点;续写提示带卡;补取在答题阶段的 5 条(见下)。`consult-single-pass-answer-20260927` 15 条原样通过 |
| 「本轮技法」一致 | `consult-evidence-card-20260927`「the 「本轮技法」 rows are exactly the rows the full result produced before the card」(3 盘 × 单领域 / 两领域,43 行) |
| 7 隐私 | `consult-evidence-card-telemetry-20260927`(字段白名单、严格 schema、虚构姓名 / 邮箱 / 生日 / 问题与匹配到的日期都不进日志) |
| 体量 | `consult-evidence-card-20260927`「model-visible size falls to card scale…」(golden 3 盘 × 12 领域:不含方法学 ≤ 12,000;除事业 / 婚恋 / 财富外整体 ≤ 12,000;全部 ≤ 18,000) |
## 补取设计与双钟(T5,红线 4)
- 工具 `read-consultation-evidence`,参数 `section` 是封闭枚举:20 张正式分盘(`varga:D1`…`varga:D60`)、`varga:research_dn`、`varga:extended`、`western:natal` 与 10 个西洋技法、`yogas`、`ashtakavarga`、`shadbala`、`transits`、`chara_dasha`、`arudha_padas`、`chara_karakas`、`kp_cusps`、`gulika`、`kakshya`、`vimshottari_mahadashas`、`domain_thematic_evidence`。卡上已有的段不列进 `evidence_card.supplementable_sections`。
- 只读请求级缓存:计算工具完成时把本轮各领域的投影与引擎上下文放进同一个 `createConsultationTools` 闭包;未命中返回 `{status: "unavailable", reason: "calculation_not_in_request_cache"}`,引擎没算出这一段返回 `section_not_computed`,都不重算。每轮第二次起返回 `refused / lookup_limit_reached`。回执记一条 `kind: tool, name: read-consultation-evidence`(成功 completed;未命中、未算、超次 failed + 机器码);活动行写「正在多看一眼:D60 分盘…」(复用写作行,见 DESIGN.md / VOICE.md)。
- 第 0 步仍只开放计算工具(`activeTools`),补取只可能发生在计算结果到手之后,也就是答题阶段。
- **双钟**:补取不开新钟、不重置钟。计算结果到手时循环已交给 70 秒答案钟(`onAnswerPhase` → `answerSignal()`,只起算一次);补取那一步与之后写回答的步都在这只钟里,110 秒工具钟过期也不掐它(测试:答案钟 300 ms 时补取 + 慢写 → `answer_truncated` 且答案钟只起算一次;工具钟 150 ms 过期后补取 + 写完 → 正常完成)。补取本身只读内存,不用信号。
- **已放出正文不截断、不重复**:
- 补取前的过程说明按 BUG-1053 规则随那一步丢掉;
- 若模型先写了已放出的正文(过了第一个标题或 160 字)再补取:这一步没写完的半句照样放出(BUG-1059 的修法,保证不截半句);下一步若把已放出的开头原样重写,从头逐字比对,连续 40 字(`LOOKUP_RESTART_MATCH_CHARS`)相同即认定为重写,重复部分边到边丢,记 `answer-restart-dropped` 校验步;不足 40 字就分叉的照常放出;接着写的正常放出;
- 结算仍看「最后一个写出正文的步」:接着写完 → `stop` → 完成扣点;补取后一个字不写就结束 → 以写正文那一步的 `tool-calls` 收尾 → `answer_truncated`、不扣点、已放出正文保留(回答确实停在一次工具调用上,按未完成处理)。
- 限制:模型换了措辞重写(不是逐字)无法识别为重复;系统提示与工具说明都要求「写正文之前调用」,工具结果里也带一句「若已开始写,就从停下处接着写,不要重复」。
- 续写:`length` 续写的证据 = 卡(计算结果);本轮用过补取时并上 `evidence_lookup`。
## 反馈记录(T6)
每轮本命回答结算后,另记一条 `[agent-observability]`:`{runId, agentVersion: "consultation-evidence-card-v1", evidenceCard: {domains, cardVersion, cardChars, cardTokenEstimate, citedFieldIds, feedback}}`。
- 存在哪:只在服务端日志(console),不落库;`runId` 是本次请求 id,这条记录里没有会话 id、用户 id。
- 引用判定按调研 R5:字段值是 ISO 日期、带小数的度数、或 ≥ 8 字符的「行星 in 星座」短语,原样出现在**已完成**的回答里才算;匹配到的原文丢掉,只留字段名(如 `base.timing.vimshottari.pratyantardasha.start`、`domain.vargas.D12.lagna`,领域名不进字段名)。失败 / 截断的回答不数引用(`onError` 形状不变,`consultation-stream-recovery` 合同照旧)。
- 赞踩:前端赞踩只在页面状态里(`page.tsx` 的 `messageFeedback`),没有接口也没有表,所以 `feedback` 恒为 `none`;要按轮关联需新表与接口,另开单。
## Skill 版本
- `SKILL.md`「关联技法完整调取」:「信息密度不受成本削减」后补上完整结果留在回执 / 「本轮技法」 / 报告,网页普通对话写答案读数据卡(基础段 + 领域段),卡外只读补取一次;口语回答改为先用卡上的原始结构。「0.0.1 全谱系真实调用」同步一句。`references/strict-workflow-router.md` 0.7 第 1、6 条补网页对话的落法。**计算口径(BUG-287 全谱系)不变**,`consultation-spectrum-parity` 钉的 SKILL.md 三句原样保留。
- 版本:`SKILL.md` frontmatter 与版本行 6.9.17、`jyotish_vedic/__init__.py` `__version__`(包版本常量,不是引擎逻辑;`tests/run_all.py`「Package version is consistent」三栏更新)。该 Skill 是 live 包,不在 `skills/skill-package-registry.json` 里,registry 未改;旧版快照目录早在 `5cbc2d00` 隐私清理时删除,没有可保留的 deprecated 目录。
## 改动的既有断言(原值 / 新值 / 原因)
| 文件 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `tests/test_consultation_domain_registry.py` | TS 领域 id == Python 十个;别名表完全相等 | TS 引擎领域 == Python 十个;`parents/children` 引擎路由为 family;Python 每个别名在 TS 里落到的领域,其引擎路由等于 Python 归一结果;TS 独有别名只落在 parents/children | D2,不改 Python |
| `tests/test_consult_evidence_card_research.py` | `"family" not in must_use`;单领域整包复制字面量存在 | family/parents/children 有必用层、父母子女无命名清单;复制字面量不存在、`toModelEvidenceView` 存在 | 调研快照的缺口已按任务修掉 |
| `frontend/tests/consultation-domain-registry.test.ts` | 10 个领域;遍历全部领域都能落库 | 12 个领域(+两条无出生分钟问法);会话主题 10 个能落库、parents/children 不能 | D2;会话主题 CHECK 不动 |
| `frontend/tests/consultation-domain-migration.test.ts` | CHECK 值 == `consultationDomainIds` | CHECK 值 == `consultationEngineDomainIds`;差集正好是 parents/children | 同上 |
| `frontend/tests/consultation-workflow-contract.test.ts` | `toModelOutput(agentContext, domainPlan)`;`continueAfterLength(pendingAnswer(), calculationEvidence)`;`return { "run-jyotish-consultation": consultationTool }` | 多传 `domain`;续写带 `evidence`(卡 + 可选补取结果);工厂同时返回补取工具 | T2 / T5 |
| `frontend/tests/consultation-agentic-runtime.test.ts`「identical natal projection is carried once」 | 顶层只剩 natal 卡,各领域在 consultations 里带 timing / domain;本命不一致时顶层为空 | 顶层固定三张卡(基础段一次)、consultations 只留契约;本命不一致的领域段自带 `base` 并记 `base_differs` | D1 |
| `frontend/tests/consultation-voice-contract.test.ts` | `Skip an executed layer…`;`must_use_layers is the executed shortlist` | `Skip a card fact…`;「The evidence card is the shortlist」+「call read-consultation-evidence once…」,并反向锁旧句 | T4 推翻「用尽每个已执行层」 |
| `frontend/tests/consultation-spectrum-parity.test.ts` | `must_use_layers is the executed shortlist` | 「The evidence card is the shortlist for this answer」 | 同上;计算口径断言不变 |
| `frontend/tests/consultation-context.test.ts` | 提示里有 `evidence_contract.technique_audit_table` | 提示里没有它,改为「full invocation record … stays with the server」 | D3 / T4 |
| `tests/run_all.py` | `__version__ == '6.9.16'` | `'6.9.17'` | Skill 文本同步 |
## 测试与构建
(Node 22.14;无 Docker,DB / 部署套件按基线逐条比对)
| 项 | 基线 `599fe7a9` | 交付 `b3f84fc8` | 结论 |
| --- | --- | --- | --- |
| `tsc --noEmit` | — | 0 错 | 通过 |
| `npm run lint` | 0 error / 127 warning | 0 error / 127 warning | 通过(触及文件里唯一的 warning `sliceAddedVisibleText` 是基线已有) |
| `npm test`(全量,Node 22) | 4093 条:4041 过 / 24 败 / 28 跳 | 4136 条:4084 过 / 24 败 / 28 跳 | 失败名单与基线逐条相同(24 条全是需要 Docker / PostgreSQL 的数据库与部署套件);按名单比对 0 条消失、新增 43 条 |
| 中间阶段 | — | T2:4108 条、失败同基线;T3:4117 条、失败同基线 | 逐段 0 新增失败、0 消失 |
| Python 门禁集(`gate-pytest-args` + `test_consult_evidence_card_research.py` + `test_consultation_domain_registry.py`) | 953 过 / 1 跳(门禁集 + 调研);`test_consultation_domain_registry.py` 基线 15 过 | 968 过 / 1 跳 | 通过(含 `test_api_server_growth_contract.py`:未改 `jyotish_api_server.py`,新增 Python 文件只复用既有 handler,未新增伪造点,注释里也没有该字面量) |
| 读 SKILL.md 的 Python 测试(skill_hard_constraints 等 12 个文件) | 6 条失败(`test_character_level_inventory_manifest` 5 条、`test_research_governance_docs` 1 条,均为本机缺外部资料目录) | 同样 6 条 | 与基线一致 |
| `tests/run_all.py` | — | 102/102 | 通过 |
| `npm run build -- --webpack` | `/`、`/chart`、`/ephemeris`、`/people` ○ Static | 同 | 通过 |
| 首屏 gzip(level 9) | rootMainFiles 4 个 131,011 B;index.html 引用 36 个 662,657 B | 131,011 B(0.00%);662,898 B(+0.04%) | 通过 |
| `frontend/frontend/` 残留 | — | 无 | — |
## 偏离与未做
- 让步:T6 只做日志(赞踩未落库,`feedback` 恒 `none`)。T5 未降级。
- 年运 / 时运的领域段是本单补的(草案无),见对照表。
- 「追问未点领域时沿用上一轮领域」:现有行为保持(模型从会话历史选领域;不填 `domains` 时服务端用会话主题)。本单没有加服务端推断,真机清单 B 组验证。
- `/admin` 里没有显示咨询领域的地方(检索 `src/app/admin`、`src/components/admin` 无命中),中文名只出现在回执 / 思考计划 / 时间线,均取自注册表。
- 两领域一轮的模型可见内容 9,117–26,148 字,其中方法学最多 15,008 字;单领域 12,000 的目标未覆盖两领域,这里如实记数。
- 失败 / 截断的回答不数引用字段(保持 `onError` 合同不变)。
- 调研脚本 `scripts/research/project_consult_model_context.ts` 仍按改前形状复现基线,作为「改前」快照保留;「改后」用新脚本 `measure_consult_evidence_card.ts`。
## 验收(Claude,2026-09-27)
rebase 到 `origin/staging` 后独立复跑(Node 22.14):tsc 0;lint 0 error;`npm test` 4136 / 24 fail / 28 skip,失败名单与上一轮基线逐条一致,无消失测试名;Python 门禁集退出 0(含 growth contract,无新增伪造点),调研 + 领域注册表测试通过,读 Skill 的 Python 测试 69 条通过;`/`、`/chart`、`/ephemeris`、`/people` ○ Static;rootMainFiles gzip(level 9)130933 B,±0%。未碰 `.gitea/`、`vendor/`、`deploy/`、迁移、`jyotish_api_server.py`;`jyotish_vedic/__init__.py` 只改版本常量。系统提示改写与卡结构一致(模型读卡、技法审计表不进正文、卡外补取一次、D4 一行)。
交产品的遗留决定:
1. 年运(annual)、时运(timing)两张卡是执行方补的(调研草案没有),需产品/懂印占的人确认。
2. 事业、婚恋、财富三类仍 13.1K–15.6K 字符,超出 1.2 万目标的部分全是 Skill 领域检查清单(methodology,系统提示把它当方法依据);是否精简需产品定。
3. 点赞/点踩目前只在页面状态里、没落库,反馈记录里 `feedback` 恒为 none;要按轮存需新表,另开单。