Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
23 KiB
PROGRESS · 普通对话改用「数据卡」· 2026-09-27
- 执行方式:直接执行(产品负责人授权子代理执行;Claude 事后独立验收)
- 基线:
origin/staging599fe7a9(任务书提交)。开工时核对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-astrology6.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.md0.7 第 1、6 条补网页对话的落法。计算口径(BUG-287 全谱系)不变,consultation-spectrum-parity钉的 SKILL.md 三句原样保留。- 版本:
SKILL.mdfrontmatter 与版本行 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 一行)。
交产品的遗留决定:
- 年运(annual)、时运(timing)两张卡是执行方补的(调研草案没有),需产品/懂印占的人确认。
- 事业、婚恋、财富三类仍 13.1K–15.6K 字符,超出 1.2 万目标的部分全是 Skill 领域检查清单(methodology,系统提示把它当方法依据);是否精简需产品定。
- 点赞/点踩目前只在页面状态里、没落库,反馈记录里
feedback恒为 none;要按轮存需新表,另开单。