Files
Jyotisha/PROGRESS-report-skill-parity-20260901.md
T
Jesse_Chen addb94af9b docs(report): record the skill-parity round, BUG-467 and what stayed blocked
PROGRESS carries the engine contract snapshot (including the fields the
task brief assumed exist but the consultation API does not return), the
claim card before/after text, the per-section prompt growth table, the
knowledge pack inventory, and the actual quality-gate output.

BLOCKED records four things: no model credentials and no PostgreSQL here,
so the live writer comparison could not be produced; the per-section
prompt p50 landing at 2.83x raw (2.28x cost-weighted), which is over the
brief's 2x line and needs a decision rather than an evidence cut; and the
fact that /api/consultation_workflow serves the reduced prompt pack, so
the server narrative seeds the brief pointed at do not exist yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr
2026-09-01 20:35:02 +00:00

27 KiB
Raw Blame History

PROGRESS · 个人报告内容对齐 skill 解读深度(2026-09-01

任务书:TASK-report-skill-parity-20260901.md 分支:codex/report-skill-parity-20260901(基线 8b7eda9f,未 push 提交:7714b5e5(任务 0+1+2)、deabcd8b(任务 3+4 离线部分)、本文件所在提交(收尾)

开工前置:docs/research/pre_work_error_ledger.md 已读;scripts/pre_work_check.py 全绿(python_runtime_ok/fragment_scan_ok/external_engine_adapters_ok/focused_tests_ok 均为 trueremote_visibility_status=verified);frontend/AGENTS.md 已读;docs/BUG_HISTORY.md 已检索 bundle / claim card / evidence 同类记录(最近相关为 BUG-457 报告分章生成)。

偏差说明(经委托方授权):未建 worktree,直接在主检出上从 HEAD 建分支(node_modules / .venv 都在主检出)。任务 4 中依赖 staging 部署的部分跳过,只做不依赖部署的 telemetry 补记。


任务 0 · 引擎响应契约快照

做法

用虚构 smoke 出生数据(1990-05-15 10:30lat 31.23 / lon 121.47 / tz +8city "Smoke City",非真人)通过 frontend/src/mastra/consultation-workflow.tsrunConsultationWorkflow 真实调用本地 scripts/jyotish_api_server.py--port 5200)的 /api/consultation_workflowcareer / marriage / wealth / education / migration / family / health / timing / general 各一次,9 次全部 OK。只记录 key 路径与类型,不记录值。

字段存在性清单(9 个主题响应一致)

任务书假定的路径 实际 类型 / 说明
chart.ai_prompt_pack.evidence_snapshot.functional_benefic_malefic 存在 object,键 status/ascendant/functional_benefics/functional_malefics/functional_neutrals/yogakarakas/owned_houses/effect_on_confidence/source;本盘 status="used"
chart.ai_prompt_pack.evidence_snapshot.strength.shadbala_ranking 存在 array(7),元素 {planet: string, rupas: number, level: string}——不是任务书写的 {planet, rank, total_rupas, min_required, strength_level}
chart.ai_prompt_pack.evidence_snapshot.strength.sav_scores 缺失 该路径不存在
chart.ai_prompt_pack.evidence_snapshot.timing.vimshottari 缺失 timing 只有 {current_mahadasha, remaining_years, start_date},没有 vimshottari 子对象,也没有 antardasha
chart.ai_prompt_pack.evidence_snapshot.timing.convergence_top_domains 缺失 该路径不存在
chart.ai_prompt_pack.evidence_snapshot.career_narrative 缺失
chart.ai_prompt_pack.evidence_snapshot.relationship_narrative 缺失
chart.ai_prompt_pack.evidence_snapshot.finance_narrative 缺失
chart.modules.yoga.yogas 缺失 键名是 yogas 不是 yoga
chart.modules.guided_topics 存在 array(4),元素键 id/title/reality_value/why_worth_exploring/evidence/confidence/vedastro/strict_adjudication_bundle/strict_audit_gate/monthly_adjudication_summary/official_day_signal_summary/suggested_questions/answer_mode/priorityid 为 birth_time_rectificationrelationship_partnershipcareer_directionwealth_risk

为什么缺/api/consultation_workflow 返回的 chart.ai_prompt_pack 来自 scripts/jyotish_api_server.py:6975_build_chart_prompt_pack不是任务书引用的 scripts/jyotish_engine.py:1592_build_ai_prompt_pack。前者是精简版,没有叙事种子、没有 dasa convergence、没有 SAV。这不是本轮能改的(任务书把"引擎侧新增计算模块或改动既有模块输出"列为不在范围内,止损分支只允许新增字段,本轮未走该分支)。

同一响应里实际可用、任务书未列出的等价路径(已改用)

路径 类型 用途
chart.modules.ashtakavarga.sav.scores object,按星座名计分(12 键) SAV:按 D1 上升整宫投影成 1–12 宫
chart.modules.ashtakavarga.sav.total number(本盘 337 savTotal
chart.modules.dasha_sub_periods.current.mahadasha / .antardasha {lord, start, end} currentDasha(含 antardasha
chart.yogas array,元素 {name, planets, category|cat, desc?} 已成盘 yoga
chart.modules.yogas.yogas array,元素 {name, rule_id, hit: bool, ...} 候选规则表,本盘 hit=true 数为 0

重要发现(防复发已写进 BUG-467)chart.modules.yogas.yogas 是规则候选表,绝大多数 hit=false,把它当成"本盘的 yoga 名单"就是编造。提取层只收 chart.yogashit === true 的行。

缺失字段的处置

按验收条款"缺失即标记不可提取并跳过,不得伪造":

  • convergenceDomains:本响应无来源 → 恒为空数组(schema 允许),代码保留 evidence_snapshot.timing.convergence_top_domainsmodules.dasa_convergence.top_convergent_domains 两条读取路径,引擎哪天补上就自动生效。
  • 三个 *_narrative:本响应无来源 → 叙事种子改由 guided_topics 文案 + 服务器确定性投影组成;readEngineNarratives 仍保留 evidence_snapshot.*_narrativemodules.*_strict_evidence.user_narrative 两条读取路径,且优先级高于 guided topic。
  • strength.sav_scores:改读 modules.ashtakavarga.sav.scores,两条路径都在代码里。
  • timing.vimshottari:改读 modules.dasha_sub_periods.current,两条路径都在代码里。

契约 fixture 测试

frontend/tests/report-interpretive-facts.test.ts(合成数据,文件头部把上表逐条写成注释)。10 条用例,锁住上述每条路径的读取行为、缺失路径的空值行为、以及 hit=false 不算成盘。


任务 1 · Bundle 承载解读性事实

schemafrontend/src/lib/report-evidence-bundle-v2.ts

schemaVersion 仍是 report_evidence_bundle.v2,两组新字段必填、允许空、.strict() 保持:

interpretiveFacts: {
  yogas: { name(≤80, 净化 pattern), category(17 项闭合枚举), planets(celestial 枚举 ≤9), evidenceRef }[]  // ≤40
  functionalRoles: { planet(celestial), role(benefic|malefic|neutral|yogakaraka), ownedHouses(1-12, ≤12), evidenceRef }[]  // ≤12
  shadbalaRanking: { planet(celestial), rank(int 1-9), rupa(0-100|null) }[]  // ≤9
  savScores: { house(1-12), score(0-100) }[]  // ≤12
  savTotal: number(0-1000) | null
  currentDasha: { mahadasha(celestial), antardasha(celestial|null), start, end } | null   // 沿用既有 dashaPeriod 日期校验
  convergenceDomains: string[]  // ≤6 × ≤80,净化
}
themeNarrativeSeeds: { theme, headline(≤300), strengths(≤8×≤400), risks(≤8×≤400), boundaries(≤8×≤400), evidenceRefs(≤24) }[]  // ≤12

ownedHouses 是相对任务书的加法(宫主分工是功能吉凶最有解读价值的一半,且是闭合的 1–12 整数数组),不是放宽。

确定性与 hash

sortedBundleContent 扩展:yogas 按 name:category 排序且 planets 去重排序;functionalRoles 按 planet 排序、ownedHouses 去重升序;shadbalaRanking 按 rank, planetsavScores 按 houseconvergenceDomains 去重排序;seeds 按 theme 排序、evidenceRefs 去重排序。computeReportEvidenceBundleHash 因此覆盖新字段。测试 bundle hash is stable under interpretive field ordering 把五个数组全部 reverse() 后 hash 不变。

shadbalaRanking.rank 不采信引擎给的 rank,而是按 rupa 降序、同分按行星名字典序重新推导,保证同一份输入永远得到同一份排名(本盘 Sun 与 Moon 都是 6.42 rupa,固定为 Moon(5) → Sun(6))。

净化与 fail closed

  • 行星走既有 safeCelestialName;yoga 分类走 17 项闭合枚举,未知归 otheryoga 名走 ^[\p{L}\p{N} ()/·,.'’++-]{1,80}$
  • safeSeedText 逐行清洗:控制字符 → 空格、折叠空白、超长截断,并对 21 个违禁子串(vedastro / mevg / workflow / references/ / scripts/ / modules. / skill / prompt / oracle / engine / fallback / blocked / not_found / not_available / api …)整行丢弃。这是相对任务书的收紧:引擎自产叙事里确实含外部供应商名与内部路由词,写作端红线不允许它们进 prompt。
  • validateReportEvidenceBundleV2 新增 fail-closedreport_bundle_invalid_interpretive_refreport_bundle_duplicate_functional_rolereport_bundle_duplicate_shadbala_rank / _planetreport_bundle_duplicate_sav_housereport_bundle_current_dasha_invalidreport_bundle_duplicate_seed_themereport_bundle_seed_theme_not_requestedreport_bundle_invalid_seed_ref。consensus ≥2 verified 防升级校验一字未改。

提取结果(真实 smoke 盘)

条数 样例(值不敏感,为虚构盘)
yogas 1 Amala Yoga / extendedchart.yogas 两行同名合并为一行)
functionalRoles 7 Mars=yogakaraka(5,10)Jupiter/Moon=beneficMercury/Saturn/Venus=maleficSun=neutral
shadbalaRanking 7 Venus(1,8.35) → Saturn(2) → Mercury(3) → Jupiter(4) → Moon(5) → Sun(6) → Mars(7)
savScores 12 上升 Cancer → 第 1 宫 24、第 10 宫 30、第 2 宫 27、第 11 宫 28 …
savTotal 1 337
currentDasha 1 Rahu / Sun2011-11-11 2029-11-11
convergenceDomains 0 源缺失,空
themeNarrativeSeeds 6 6 个非 blocked 主题各一条

任务 2 · Claim card 从回执升级为结论

改前 / 改后对照(同一份真实 smoke 盘,9 主题请求;career / marriage / timing 因缺 AmK / Transit / DK 仍是 blocked section,逻辑未动)

改前(8b7eda9f)——所有主题只有主题名不同:

[education] parameter_sensitive
conclusion : 服务器已闭合教育学习所需的最低证据组;本节只能在所列事实与确定性级别内解释。
supporting : D1=D1 上升为 Cancer,本次基础盘已建立
             D24=D24 已执行并纳入本主题证据计划
             Vimshottari=Vimshottari 已执行并纳入本主题证据计划
counterFacts: []

[wealth] parameter_sensitive
conclusion : 服务器已闭合财富结构所需的最低证据组;本节只能在所列事实与确定性级别内解释。
supporting : D1=… / D2=D2 已执行并纳入本主题证据计划 / D11=… / Yoga=… / Ashtakavarga=… / Vimshottari=…

改后:

[education] parameter_sensitive          ← 级别未变
conclusion : 本命上升为 Cancer;按宫主判定的功能吉星为 Jupiter、Moon,功能凶星为 Mercury、Saturn、Venus。
             本主题相关宫位的八分力总分:第 4 宫 25 分,第 5 宫 35 分(全盘合计 337 分)。
             当前处于 Rahu 主运、副运 Sun,主运区间 2011-11-11 至 2029-11-11。
supporting : D1=本命上升 Cancer;功能吉星 Jupiter、Moon,功能凶星 Mercury、Saturn、Venus
             D24=D24 已执行并纳入本主题证据计划
             Vimshottari=当前 Rahu 主运、副运 Sun2011-11-11 至 2029-11-11
             Ashtakavarga=八分力:第 4 宫 25 分,第 5 宫 35 分,全盘合计 337 分
             Functional Benefic/Malefic=功能吉凶已判定,Mars 为 yogakaraka
             Yoga=已成立组合:Amala Yoga

[wealth] parameter_sensitive             ← 级别未变
conclusion : 本命上升为 Cancer;按宫主判定的功能吉星为 …。
             本主题相关宫位的八分力总分:第 2 宫 27 分,第 11 宫 28 分(全盘合计 337 分)。
             当前处于 Rahu 主运、副运 Sun,主运区间 2011-11-11 至 2029-11-11。

[general] single_system_inference        ← 级别未变
conclusion : …本主题相关宫位的八分力总分:第 1 宫 24 分,第 10 宫 30 分(全盘合计 337 分)。…

六个可写主题的 conclusion 现在逐主题不同(主题相关宫位的 SAV 行不同),且不含任何模板回执句。

拼装规则

  • conclusion = seed.headline + 最多 2 条 seed.strengths,按句号补全后拼接,截断 1200。
  • seed 的 headline 优先取引擎叙事 headline(结论式);无叙事时取第一条服务器确定性投影行;再无则取 guided topic 标题。主题相关行(SAV 宫位)排在前面,保证每章 conclusion 不同。
  • supportingFacts:每条 matched receipt 一条,值改为该技法的真实解读语句;此外把通用解读层(Functional Benefic/Malefic、Yoga、Ashtakavarga、Vimshottari)作为额外事实条目挂在它们自己的 receipt 上,不冒名给别的技法。
  • counterFacts ← seed.risks(本盘引擎叙事缺失,为空;合成夹具用例 engine risk lines become counter facts on the matching claim card 覆盖了有 risks 的路径)。
  • boundaries 留在种子里由 writer 引用(任务书允许的第二种处置),verificationQuestions 未动。
  • assertionLevel 推导一字未改;只有"完全没有种子"时把 multi_system_consensus 压到 single_system_inference(用例 a theme without any narrative seed keeps the receipt wording and loses consensus 覆盖)。

端到端抽查(叙事内容可回溯到 bundle,3 处)

无模型凭据、无数据库,本地无法真跑 writer(见 BLOCKED.md)。改为对服务器确定性产出的 conclusion 做逐句回溯,这是 writer 唯一被允许复述的结论层:

# conclusion 中的表述 回溯到 bundle 的哪一行
1 "本命上升为 Cancer" charts[D1].ascendant.sign = "Cancer";同时 supportingFacts 该条 evidenceRef = ev-tech-d1executionLedger[ev-tech-d1].status = verified
2 "Mars 同时主管第 5、10 宫,在本盘属 yogakaraka" interpretiveFacts.functionalRoles[{planet:"Mars", role:"yogakaraka", ownedHouses:[5,10], evidenceRef:"ev-tech-functional_benefic_malefic"}];该 ref 在 evidenceRefs 中 status=partial,事实条目 status 同为 partial(未升级)
3 "当前处于 Rahu 主运、副运 Sun,主运区间 2011-11-11 至 2029-11-11" interpretiveFacts.currentDasha = {mahadasha:"Rahu", antardasha:"Sun", start:"2011-11-11", end:"2029-11-11"},绑 ev-tech-vimshottari
4 "本盘已成立的组合:Amala Yoga" interpretiveFacts.yogas[0] = {name:"Amala Yoga", category:"extended", evidenceRef:"ev-tech-yoga"}modules.yogas.yogas 里 6 条 hit=false 的候选规则没有出现在这里
5 "第 2 宫 27 分,第 11 宫 28 分(全盘合计 337 分)" interpretiveFacts.savScores[{house:2,score:27},{house:11,score:28}] + savTotal=337,绑 ev-tech-ashtakavarga

每章 prompt 增量(红线 6:必须摆数据)

同一份真实 smoke 盘、depth=standard、6 个可写主题。测量对象是 sectionPrompt 的 JSON 载荷 {bundle, plan, completedSectionTitles}filterReportEvidenceBundleForSection 之后)。改前数据是把三个改动文件 checkout 回 8b7eda9f 后用同一份 workflow 快照重跑得到的,不是估算。

token 数是离线估算(无 tokenizerCJK 字符按 1 token、其余按 1/4 token)。真实 inputTokens 必须来自部署后的一次真实生成。

章节 改前 chars 改后 chars 改前 est.tok 改后 est.tok 倍数
theme-general 3459 6993 928 1999 2.15
theme-family 3774 7298 1044 2112 2.02
theme-health_pressure 3845 7354 1065 2121 1.99
theme-education 4169 7361 1162 2127 1.83
theme-migration_home 4511 7726 1270 2240 1.76
theme-wealth 5129 7711 1465 2262 1.54
p50 4004 7357 1113.5 2124 1.91

改后载荷构成(以 general 章为例,chars):interpretiveFacts 1365、themeNarrativeSeeds 500、claimCards 1262(改前约 500)、executionLedger 576、evidenceRefs 372、charts 1731(未变)、calculationProfile 232(未变)。

再加上任务 3 的静态系统内容(改前只有 24 字符的缓存边界句):

改前 est.tok 改后 est.tok 是否吃 prompt cache
缓存前缀内的静态内容(通用包 + 边界句) 22 877 cachedSystemMessage,前缀逐字节稳定,有测试锁)
本章主题包(缓存边界之后) 0 203313p50 214
bundle 载荷 1113.5 2124
每章合计(原始 token 1135.5 3215
  • 原始 token p50 倍数 = 2.83×,超过改前 2 倍。
  • 计费加权后(缓存写 1.25×、缓存读 0.1×,6 章摊到每章约 256 token):改后 ≈ 2594 token约 2.28×,仍超 2 倍。

按红线 6 与任务 3 止损条款处置cachedSystemMessage 已确认生效且缓存前缀逐字节稳定(writer system content caches the general pack and appends only the chapter pack 用例锁定),不属于"cache 未命中"的止损分支;止损条款明确禁止"砍证据来凑成本",因此未削减任何证据,数据原样摆出,是否接受这个成本请委托方裁决。可选的降本项(未做,逐条列出以便决策):

  1. 主题包不下发,只留通用包:每章省约 214 token(→ 约 2.64×)。代价是丢掉主题级措辞纪律。
  2. themeNarrativeSeeds 与 conclusion 前两句重复,去重可省约 150 token(→ 约 2.70×)。代价是 writer 看不到种子原始层与 claim 的差别。
  3. shadbalaRanking 每章只留前 3 + 最弱 1:省约 90 token。代价是丢掉完整发力顺序。
  4. charts1731 chars ≈ 450 token)是改前就有的开销,与本轮无关;真要压成本,这里比砍新证据划算。

任务 3 · 写作端静态解读知识包

目录与清单

frontend/src/lib/report-interpretation-packs/general.ts / themes.ts / index.ts),纯静态 TS 常量。蒸馏来源:references/modern-language-guide.mdreferences/common-misconceptions.mdreferences/house-domain-planet-mapping.md 及各主题判读要点。

字符数 est.tok 内容
general_method(通用) 961 855 表达顺序、术语现代化映射、强弱与分值怎么说、多层验证、必须避免的推理错误、语气与禁语
career 366 313 主指标、10/6 宫怎么说、yogakaraka 怎么落地、禁止承诺升职/薪资/时点
marriage 330 296 7 宫=一切长期对等关系、D9 与本命的分工、土星不写成"晚婚"、禁止预测结婚年份与忠诚判断
wealth 298 261 赚到 vs 留住必须分开、低分不写成"破财"、禁止推荐任何标的/收益率/借贷建议
education 248 214 学得快 vs 学得深、困难写成方法不匹配、禁止预测通过与录取
migration_home 244 208 12 宫不写成"损失"、安定与离开并存、禁止指定国家城市方位与日期
family 231 203 关系模式而非人品、5 宫不是生育能力、禁止预测生育与亲属健康
health_pressure 243 214 只谈负荷与恢复、禁止任何诊断/点名疾病/用药建议
timing 281 256 时间层只能激活本命已有结构、主运/副运分工、未获准时不写年月日
general(综合基础章) 273 243 建框架不抢主题章结论、功能吉凶是角色分工不是性格好坏

单包上限 3000 字符(PACK_CHARACTER_LIMIT),最大的通用包用了 32%。

注入方式

buildWriterSystemContents(theme)frontend/src/mastra/personal-report.ts)返回:

  • [0] = 通用包 + 【上下文缓存边界】…,作为 cachedSystemMessage 的内容 → 在缓存断点之内,且逐字节稳定,第 2 章起是 cache read
  • [1] = 本章主题包,放在缓存边界之后(每章不同,不能进前缀)。
  • 摘要调用 themePack=null,只带通用包。
  • 非 Anthropic 供应商 cachedSystemMessage 返回 null,此时降级为普通 system message(内容不变,只是不缓存)。

合同同步

  • writer 指令新增:interpretiveFacts / themeNarrativeSeeds 是"可引用的事实层,但不授权 claimCard 之外的结论";知识包"只管怎么解释和怎么措辞,不是事实来源,不能提高确定性"。Use its claimCards exclusively for narrative conclusions 原句保留。
  • skills/jyotish-personal-report/SKILL.md 升到 1.1.0skills/jyotish-personal-report/versions/1.1.0/ 为不可变副本,registry 中 1.0.0 转 deprecated、1.1.0 为 activesha256 6be2279b…10e9)。

端到端改前改后同盘同主题章节全文对照

未做,无法在本地做:执行环境没有任何模型凭据(ANTHROPIC_* / OPENAI_* 等全部未设置,仓内只有 .env.*.example),也没有 PostgresDocker 不可用),generateSectionedPersonalReport 需要 PersonalReportSectionService。见 BLOCKED.md。可离线给出的替代物是上面的"每章 prompt 增量"表与 claim card 全文对照。


任务 4 · 观测(只做不依赖部署的部分)

PersonalReportAgentTelemetry 新增两个数值字段,沿用既有隐私边界(只记指标名与数值):

  • interpretiveFactCount:本次调用收到的 bundle 里解读事实的条数(yogas + functionalRoles + shadbalaRanking + savScores + convergenceDomains + currentDasha + savTotal)。本盘各章为 211 + 7 + 7 + 2~3 + 0 + 1 + 1,随该章 SAV 宫位裁剪略有差异)。
  • knowledgePackCharacters:本次调用随 prompt 下发的静态知识包字符数 = 缓存前缀内容 + 本章主题包。章节调用为 12181353987 + 231~366),摘要调用为 987

countInterpretiveFacts 对缺字段/畸形输入返回 0 而不抛错——telemetry 不得让生成失败。测试 telemetry carries interpretive and knowledge-pack sizes as numbers only 断言两个字段是数字,且序列化后不含任何事实文本。

部署后测量(章节数、每章 in/out tokens、总墙钟、与 PROGRESS-report-sectioned-20260830.md 对照)按授权跳过,由委托方在 staging 部署后补。


修改既有测试断言的逐条说明(红线 9

文件 断言 原值 原因
frontend/tests/personal-report-generation.test.ts bundleV2Fixture() interpretiveFacts / themeNarrativeSeeds 两个字段按任务书要求为必填;夹具没有引擎快照,声明为 emptyReportInterpretiveFacts() + []。断言语义未变。
frontend/tests/personal-report-generation-v2.test.ts 同上 同上 同上
frontend/tests/personal-report-plan.test.ts 同上 同上 同上
frontend/tests/personal-report-generation.test.ts:814 snapshot.version "1.0.0" Skill 合同变更,版本 +1;已在断言上方注明原值与原因
frontend/tests/skill-registry.test.ts:92 jyotish-personal-report 的 version / sha256 1.0.0 / 23149b9e…f982 同上;已在断言上方注明原值与原因
tests/test_jyotish_personal_report_skill_package.py VERSION_ROOT 与 registry 期望行 versions/1.0.0 同上;改为 ACTIVE_VERSION 常量并注明原值与原因,同时新增四条断言锁住 1.1.0 的新合同措辞(只加不减)

没有任何断言被放松:report-evidence-bundle-v2.strict()、consensus ≥2 verified 防升级、assertionLevel 推导、章节串行、writer 输出 schema 全部原样。


质量门实际结果

$ ./node_modules/.bin/tsc --noEmit          # frontend
(无输出,通过)

$ ./node_modules/.bin/eslint src tests      # frontend
✖ 28 problems (0 errors, 28 warnings)
28 条全部是既有的 no-unused-vars warning,与本轮无关)

$ npm run build                             # frontend
✓ Compiled successfully in 5.6s
✓ Generating static pages using 7 workers (62/62) in 447ms
Turbopack build encountered 5 warnings:
Warning: Dynamic filesystem access causes tracing of the whole project   ×5
(该 5 条为既有告警,已记录在 BLOCKED.md 2026-08-17 条目)

$ ./node_modules/.bin/tsx --test tests/*.test.ts     # 基线 8b7eda9f
# tests 2427   # pass 2393   # fail 24   # skipped 10   # todo 0

$ ./node_modules/.bin/tsx --test tests/*.test.ts     # 本分支
# tests 2444   # pass 2410   # fail 24   # skipped 10   # todo 0

失败集逐条 diff:完全一致(SAME_FAILURE_SET),24 条全部是本机缺 Docker / PostgreSQL 的
数据库与部署夹具,以及 staging workflow YAML 校验,与 BLOCKED.md 既有记录一致:
  admin code functions … / admin customer reset … / service and restricted admin database identities …
  Owner recovery … / staging backups … / billing order adjustments … / billing, subscriptions, …
  saving a published product … / database env validator … / migration runner … / foundation grants …
  local PostgreSQL … / personal report job migration … / personal report sections enforce owner-read RLS …
  redeem security … / self-hosted identity migration … / database roles have no cluster privileges
  server compose defaults … / staging env validator … / Better Auth supports shared user OTP/password …
  database drops secret refs … / changed staging workflows are syntactically valid YAML
  live staging sync preserves env … / live staging sync repairs nested deploy-tree drift …
新增 17 个通过用例,0 个新增失败。

$ .venv/bin/python -m pytest tests/test_jyotish_personal_report_skill_package.py -q
..                                                                       [100%]

$ .venv/bin/python scripts/pre_work_check.py
checks 全 trueremote_visibility_status = verified

npm run test:db 未跑:Docker 不可用,且本轮红线禁止数据库结构改动与新增迁移,本轮确实没有改任何库结构或迁移。


交付物清单核对

# 交付物 状态
1 任务 0 契约快照(字段存在性清单 + fixture 测试) 完成
2 bundle 新字段 schema + 提取 + 净化 + hash 覆盖 + fail-closed 测试 完成
3 filterReportEvidenceBundleForSection 主题裁剪 + 每章 prompt 增量数据 完成(增量数据超 2×,已摆出待裁决)
4 实质化 claim cards + 回退与级别压制 + consensus 回归测试 完成
5 端到端抽查记录:叙事可回溯到 bundle(≥3 处) 部分完成:对服务器确定性 conclusion 做了 5 处逐行回溯;真实 writer 输出因无模型凭据未跑(BLOCKED.md)
6 知识包目录 + 违禁词扫描测试 + SKILL.md 更新 完成
7 改前改后同盘同主题章节全文对照 + tokens/墙钟对照 未做:无模型凭据与数据库(BLOCKED.md);已给出 prompt 载荷与 claim card 全文对照作为离线替代
8 docs/BUG_HISTORY.md 条目 完成:BUG-467(远端 origin/staging 最大号为 BUG-466,已确认)
9 BLOCKED.md 完成
10 PROGRESS-report-skill-parity-20260901.md 本文件
11 tsc / eslint / tsx --test / next build 实际输出 完成(见上)