feat(consult): career list reads field and public/behind-the-scenes from chart evidence (BUG-1176); opener keeps the affliction rule (BUG-1177)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c74bfcc06b
commit
dd817c8eb8
@@ -251,7 +251,8 @@ Jyotisha 的可见文案是产品的一部分。正确性红线(真实性、
|
||||
4. **同一约束换着说。** 边界句必须在交付/采用轮完整出现一次;中间轮不要逐字复读法务稿。
|
||||
5. **口语化但不轻佻。** 短句、具体事实、少套话。
|
||||
6. **希望纪律。** 占星结果是客观的,表达是主观的。不顺就说不顺,但每次都要说清这段时间能做什么。盘上确有转机、且 `answer_policy.can_answer_precise_timing` 允许精确应期时,把转机说到月份(哪颗星换宫、哪段大运交接);不允许精确应期、或这一段确实没有转机时,说清这段时间是拿来干什么的(攒、守、清账、练手),不编月份。不是每个人都有转机,但每个人这段时间都有能做的事。不写「一切都会好」「相信自己」「加油」「你值得更好的」「宇宙自有安排」。(2026-10-01 起不再用「扮演哪个象」的说法,TASK-consult-plain-answer-20261001 D5。)
|
||||
7. **回答形状:先答,再按对象分段(2026-10-01,BUG-1132,推翻 2026-09-17 的四步开场形状)。** 三种模式(本命 / 无出生分钟 / 申报时段)共用,**不设字数上限,讲清楚为准**,同一件事只说一遍。① **先答**——开场一到三句人话,第一句就是结论,不写标题、不写行动,不给这件事起名字;② **按对象分段**——问题里点到几个人或几个子问题(妈妈、爸爸、他们怎么对我、什么时候),开场之后每个各写一段,二级标题用问题里的词(`## 你和妈妈`、`## 你和爸爸`、`## 他们怎么对你`);问父母时妈妈和爸爸分开写;只问一个人或一件事时不拆段;③ **每段先说最强的信号、后依据**(2026-10-01 BUG-1164 改,取代「这个人是什么样、你们怎么相处、事情会怎么走」)——先说盘上最强的一两个信号说明了什么,包括这个人在不在你身边、近不近;盘上没有依据的方面不写,不用日常场景凑段落;受冲信号两个及以上时(2026-10-02 产品改口径,盘分不出父母在不在身边、几段感情、有没有病):先说这条线有压力或距离的迹象,括号里给依据,再给现实里可能的范围(「现实里可能是分开、离得远,也可能只是关系紧、话少」),不替用户断定他自己更清楚的事实,也不反过来写「有分量」「站得住」「不是缺位」「底子不差」「关系稳」「能走下去」;段末一句请用户说说实际情况(「实际是哪一种,告诉我一句,我按真实情况再看。」),全篇最多一处;婚姻写「感情这条线上有波折的迹象」而不是「可能不止一段」,健康写「身体这条线有压力的迹象」而不是「底子不差」;**不预设处境**:有没有伴侣、是否已婚、是否在上班、做哪类工作、孩子性别、父母是否在身边都不预设,性别未知时不用「他」「她」称伴侣和孩子;再在括号里给撑住这段判断的盘上依据(宫、宫主、代表星、分盘、大运);问的是别人时写那个人在你盘上对应的宫位与代表星说明了什么,不写那个人的心思(BUG-1070 的目的保留);④ **行动**——一到三条破折号短句,本命解读里只在最后一节出现一次。<br>**人话自检**:把每句话括号里的内容删掉,一个完全不懂占星的人仍能看懂。禁止自造格局名或四字概括(「外X内Y」一类);禁止把大运、行运写成拟人的角色(「推这一段的是……」「修形式的是……」「交给……收尾」)和「去当某颗星的某种样子」的角色修辞;禁止把星名当形容词的主人(「土星的冷」);括号外每段最多一个占星术语,第一次出现时用白话套住(「现在这十年(月亮大运)」)。**推断边界**:空宫不单独下结论,要说它的宫主落在哪、什么状态(BUG-1134)。<br>降级路线(形状照给,只换依据):**申报时段**依据只取窗口内稳定的那一层(行星落座、公开日历),上升、宫位、大运、分盘不作依据,不写月份;**无出生分钟**时间只讲公开日历这一天的大势,不点个人大运、不写月份。<br>为什么推翻:09-17 的四步形状(反差格局名 → 动力层 / 形式层 → 应哪个象 → 行动)来自一段单对象、单时段的流年范文;强制用在所有问题上后,模型逐格填空写出术语叠术语的谜语,问父母时爸妈被揉成一段。
|
||||
7. **回答形状:先答,再按对象分段(2026-10-01,BUG-1132,推翻 2026-09-17 的四步开场形状)。** 三种模式(本命 / 无出生分钟 / 申报时段)共用,**不设字数上限,讲清楚为准**,同一件事只说一遍。① **先答**——开场一到三句人话,第一句就是结论,不写标题、不写行动,不给这件事起名字;**开场同样守受冲规则**(2026-10-02,BUG-1177):不替用户断定在不在身边、几段感情、有没有病,不写「距离感明显」「不是能硬扛的类型」这类程度结论,只说哪条线顺、哪条线有压力迹象;② **按对象分段**——问题里点到几个人或几个子问题(妈妈、爸爸、他们怎么对我、什么时候),开场之后每个各写一段,二级标题用问题里的词(`## 你和妈妈`、`## 你和爸爸`、`## 他们怎么对你`);问父母时妈妈和爸爸分开写;只问一个人或一件事时不拆段;③ **每段先说最强的信号、后依据**(2026-10-01 BUG-1164 改,取代「这个人是什么样、你们怎么相处、事情会怎么走」)——先说盘上最强的一两个信号说明了什么,包括这个人在不在你身边、近不近;盘上没有依据的方面不写,不用日常场景凑段落;受冲信号两个及以上时(2026-10-02 产品改口径,盘分不出父母在不在身边、几段感情、有没有病):先说这条线有压力或距离的迹象,括号里给依据,再给现实里可能的范围(「现实里可能是分开、离得远,也可能只是关系紧、话少」),不替用户断定他自己更清楚的事实,也不反过来写「有分量」「站得住」「不是缺位」「底子不差」「关系稳」「能走下去」;段末一句请用户说说实际情况(「实际是哪一种,告诉我一句,我按真实情况再看。」),全篇最多一处;婚姻写「感情这条线上有波折的迹象」而不是「可能不止一段」,健康写「身体这条线有压力的迹象」而不是「底子不差」;**不预设处境**:有没有伴侣、是否已婚、是否在上班、做哪类工作、孩子性别、父母是否在身边都不预设,性别未知时不用「他」「她」称伴侣和孩子;再在括号里给撑住这段判断的盘上依据(宫、宫主、代表星、分盘、大运);问的是别人时写那个人在你盘上对应的宫位与代表星说明了什么,不写那个人的心思(BUG-1070 的目的保留);④ **行动**——一到三条破折号短句,本命解读里只在最后一节出现一次。<br>**人话自检**:把每句话括号里的内容删掉,一个完全不懂占星的人仍能看懂。禁止自造格局名或四字概括(「外X内Y」一类);禁止把大运、行运写成拟人的角色(「推这一段的是……」「修形式的是……」「交给……收尾」)和「去当某颗星的某种样子」的角色修辞;禁止把星名当形容词的主人(「土星的冷」);括号外每段最多一个占星术语,第一次出现时用白话套住(「现在这十年(月亮大运)」)。**推断边界**:空宫不单独下结论,要说它的宫主落在哪、什么状态(BUG-1134)。<br>降级路线(形状照给,只换依据):**申报时段**依据只取窗口内稳定的那一层(行星落座、公开日历),上升、宫位、大运、分盘不作依据,不写月份;**无出生分钟**时间只讲公开日历这一天的大势,不点个人大运、不写月份。<br>为什么推翻:09-17 的四步形状(反差格局名 → 动力层 / 形式层 → 应哪个象 → 行动)来自一段单对象、单时段的流年范文;强制用在所有问题上后,模型逐格填空写出术语叠术语的谜语,问父母时爸妈被揉成一段。
|
||||
8. **事业题看行业与名声,要有盘面依据(2026-10-02,BUG-1176)。** 行业看星的本性(10 宫里的星、10 宫主、AmK、10 宫主在 D9 的定位星;太阳权力公职、月亮公众照护、火星体力竞技工程、水星沟通商业、木星教育法律、金星艺术表演、土星劳动组织、罗睺新技术跨界),先说最强的一两颗;公众型 / 幕后型只在有依据时写(太阳或 10 宫主强在角宫、AL / A10 落角宫、入旺入庙星、`traditional_yogas`;10 宫主落 12 宫且无这些信号才偏幕后)。不写「出头慢、越往后越稳、靠专业交付」这类人人适用的话。卡上的「传统格局,本站未验证,只作参考」只用来说明某颗星有力量,不单独下结论,不算受冲,也不抵消受冲(BUG-1175)。
|
||||
|
||||
## 好 / 坏对照
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ export const CONDENSED_SHARED_READING_LINES: readonly string[] = [
|
||||
"不写没有区分度的推论:逆行不等于「反复、打回来」;宫主不在本宫不等于「往外跑」;某星不在某宫不等于「离得远」;空宫不单独下结论。",
|
||||
"不断言死亡、离婚、疾病诊断、流产、不孕。",
|
||||
"瑜伽只认 yogas.hits:hits 里的才是这张盘成立的格局;只在 names 里、没进 hits 的是待检规则,不得说成本人的格局。",
|
||||
"`traditional_yogas` 只用来说明力量,不单独下结论,不算受冲,也不抵消受冲。",
|
||||
];
|
||||
|
||||
/** The shared reading as one numbered block. */
|
||||
@@ -81,6 +82,8 @@ export const CONSULT_BRIEF_CHECKLIST_SOURCE = "consultation checklist (TASK-cons
|
||||
export const CONSULTATION_CONDENSED_CHECKLISTS: Readonly<Partial<Record<ConsultationDomain, readonly string[]>>> = {
|
||||
career: [
|
||||
"先讲这张盘一生的事业形态:公众型还是幕后型、靠什么出头(AL 落宫、10 宫与 10 宫主、太阳、入旺入庙星坐角宫);受冲只说阻力和代价,不改写事业形态。",
|
||||
"行业看星的本性:10 宫里的星、10 宫主、AmK,以及 10 宫主在 D9 的定位星。太阳 = 权力、公职、管理;月亮 = 公众、照护、流动;火星 = 体力、竞技、工程、军警;水星 = 沟通、写作、商业、分析;木星 = 教育、法律、顾问、宗教;金星 = 艺术、表演、娱乐、美;土星 = 劳动、组织、长期工程;罗睺 = 新技术、跨界、海外、大众传播。先说最强的一两颗,不平均罗列。",
|
||||
"公众型还是幕后型要有依据:太阳或 10 宫主强且在角宫、AL 或 A10 落角宫、10 宫或命宫有入旺入庙星、`traditional_yogas` 有大格局,偏公众;10 宫主落 12 宫且无上述信号,才偏幕后。没有依据就不写这一句。不写「出头慢、越往后越稳、靠专业交付」这类人人适用的话,除非能指出具体盘面。",
|
||||
"必看:D1 10 宫与 10 宫主、AmK;卡上 d9 段确认 10 宫主与 AmK 的旺弱、Vargottama、D1/D9 反转;D10 上升与 10 宫;AL 与 A10;10 宫 SAV 与木星、土星所在宫的 SAV。",
|
||||
"时间:Vimshottari(MD/AD/PD)与 Narayana 双轨同向才谈应期,看大运主与 10 宫、10 宫主、D10 的关系;每颗星先按功能吉凶定性。",
|
||||
"分三层说,不得合成一句「事业机会」:①机会出现(消息、邀约、初步接洽)②成形(合同、合作、长期项目)③公开落地(发布、到账、被看见、名声)。",
|
||||
|
||||
@@ -401,7 +401,7 @@ export const NATAL_SECTION_RULE = `每段先说盘上最强的一两个信号说
|
||||
*/
|
||||
export function natalAnswerShapeBody(): string {
|
||||
return [
|
||||
"开场不要标题,先用一到三句人话回答问题,第一句就是结论;不给这件事起名字,开场不写行动清单。",
|
||||
"开场不要标题,先用一到三句人话回答问题;开场同样守受冲规则:不替用户断定在不在身边、几段感情、有没有病,不写程度结论,只说哪条线顺、哪条线有压力迹象。不给这件事起名字,开场不写行动清单。",
|
||||
"问题里点到几个人或几个子问题(比如妈妈、爸爸、他们怎么对我),开场之后每个各写一段,二级标题用问题里的词(例:## 你和妈妈、## 你和爸爸、## 他们怎么对你);问父母时妈妈和爸爸分开写。只问一个人或一件事时不拆段。",
|
||||
`${NATAL_SECTION_RULE}每段的判断后在括号里给撑住它的盘上依据。`,
|
||||
`然后依次写:## ${REPORT_HEADING.support}(只写上面没引过、判断又需要的依据,表格与正文二选一;没有新依据就省掉这一节)、## ${REPORT_HEADING.timing}(卡里没有相关大运或行运就省掉)、## ${REPORT_HEADING.action}(一到三条行动,只在这里出现一次)。`,
|
||||
|
||||
@@ -23,7 +23,7 @@ Never write 一切都会好, 相信自己, 加油, 你值得更好的, or 宇宙
|
||||
|
||||
ANSWER SHAPE (natal / general / declared-window 三种模式共用)
|
||||
不设字数上限,讲清楚为准。同一件事只说一遍;不为显得周全写问题用不到的盘面事实。
|
||||
1. 先答:开场一到三句人话,第一句就是结论,回答用户问的那句话。开场不写标题、不写行动,不给这件事起名字。
|
||||
1. 先答:开场一到三句人话,第一句就是结论,回答用户问的那句话;开场的结论只说哪条线顺、哪条线有压力迹象,不替用户断定在不在身边、几段感情、有没有病,不写程度结论。开场不写标题、不写行动,不给这件事起名字。
|
||||
2. 按对象分段:问题里点到几个对象(妈妈、爸爸、伴侣、老板、孩子……)或几个子问题(关系如何、他们怎么对我、什么时候),开场之后每个各写一段,二级标题用问题里的词(例:## 你和妈妈、## 你和爸爸、## 他们怎么对你)。问「父母」时妈妈和爸爸分开写,不揉成一段。只有一个对象、一个子问题时不拆段。
|
||||
3. ${NATAL_SECTION_RULE}写到讲清楚为止;然后在括号里给出撑住这段判断的盘上依据(宫、宫主、代表星、分盘、大运),够用就停。问的是别人时,写那个人在你盘上对应的宫位与代表星说明了什么,不写那个人的心思。
|
||||
4. 行动:一到三条破折号短句,做完就能看到改变。本命解读里只写在最后一节「这周可以做的一件事」,出现一次;无出生分钟与申报时段没有正文骨架,行动就写在回答结尾。
|
||||
|
||||
@@ -59,7 +59,10 @@ test("T1: the shared reading is the first section, once per turn, whatever the p
|
||||
assert.match(text, /逆行不等于「反复、打回来」/);
|
||||
// The line added on top of the brief's six: only hits are yogas this chart has.
|
||||
assert.match(text, /瑜伽只认 yogas\.hits/);
|
||||
assert.equal(CONDENSED_SHARED_READING_LINES.length, 7);
|
||||
// 原值: 7 行
|
||||
// 新值: 8 行(第 8 行:traditional_yogas 只说明力量,不单独下结论,不算受冲也不抵消受冲)
|
||||
// 原因: TASK-consult-career-yoga-functional-20261002 T3 / D3 定稿,通用读法加一行(BUG-1175)
|
||||
assert.equal(CONDENSED_SHARED_READING_LINES.length, 8);
|
||||
});
|
||||
|
||||
// 原值: test "T1/T2 budget blocker is pinned: a single annual or timing turn keeps its pre-brief method"
|
||||
@@ -126,9 +129,13 @@ test("T3: career, marriage and wealth each carry their affliction line", () => {
|
||||
assert.ok(CONSULTATION_CONDENSED_CHECKLISTS.marriage!.some((line) => line.includes("感情这条线上有波折的迹象") && line.includes("不断定有几段") && line.includes("不预设用户现在有伴侣或单身")));
|
||||
assert.ok(!CONSULTATION_CONDENSED_CHECKLISTS.marriage!.join("\n").includes("可能不止一段"));
|
||||
assert.ok(CONSULTATION_CONDENSED_CHECKLISTS.wealth!.some((line) => line.startsWith("8 宫也管版税、继承、意外之财")));
|
||||
// 原值: career / marriage / wealth 都是 5–8 行
|
||||
// 新值: marriage / wealth 仍 5–8 行;career 5–9 行
|
||||
// 原因: TASK-consult-career-yoga-functional-20261002 T4 定稿给事业清单加两行(行业、公众 / 幕后的依据,BUG-1176),定稿文本不得改意思
|
||||
for (const domain of ["career", "marriage", "wealth"] as const) {
|
||||
const lines = CONSULTATION_CONDENSED_CHECKLISTS[domain]!;
|
||||
assert.ok(lines.length >= 5 && lines.length <= 8, domain);
|
||||
const max = domain === "career" ? 9 : 8;
|
||||
assert.ok(lines.length >= 5 && lines.length <= max, domain);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// TASK-consult-career-yoga-functional-20261002 T3–T5 (BUG-1175~1177): the
|
||||
// closed-list traditional yogas reach the general / career / wealth cards with
|
||||
// a fixed label, the shared reading says how to use them, the career list
|
||||
// reads field and public/behind-the-scenes from chart evidence, and the opener
|
||||
// keeps the affliction rule. Expected yoga names are the real engine's own
|
||||
// layer in the golden (scripts/research/capture_consult_evidence_card_golden.py).
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
buildEvidenceCard,
|
||||
EVIDENCE_CARD_LABELS,
|
||||
EVIDENCE_CARD_SPECS,
|
||||
} from "../src/lib/consultation-evidence-card.ts";
|
||||
import type { ConsultationDomain } from "../src/lib/consultation-domain-registry.ts";
|
||||
import { createConsultationPlan } from "../src/lib/consultation-plan.ts";
|
||||
import {
|
||||
CONDENSED_SHARED_READING_LINES,
|
||||
CONSULTATION_CONDENSED_CHECKLISTS,
|
||||
} from "../src/lib/consultation-condensed-checklist.ts";
|
||||
import { natalAnswerShapeBody } from "../src/lib/consultation-thinking-plan.ts";
|
||||
import {
|
||||
consultationWorkflowResponseSchema,
|
||||
toAgentConsultationContext,
|
||||
toModelOutput,
|
||||
} from "../src/mastra/consultation-workflow.ts";
|
||||
|
||||
type Json = Record<string, unknown>;
|
||||
type GoldenChart = { id: string; workflow: Json; annual_workflow: Json; timing_workflow: Json };
|
||||
const golden = JSON.parse(readFileSync(
|
||||
new URL("./fixtures/consult-evidence-card-golden.json", import.meta.url),
|
||||
"utf8",
|
||||
)) as { charts: GoldenChart[] };
|
||||
const chartById = (id: string) => golden.charts.find((chart) => chart.id === id)!;
|
||||
|
||||
function card(workflow: Json, domain: ConsultationDomain) {
|
||||
const context = toAgentConsultationContext(consultationWorkflowResponseSchema.parse(structuredClone(workflow)));
|
||||
const packet = toModelOutput(context, createConsultationPlan({ userIntent: "q", theme: domain }), domain);
|
||||
return buildEvidenceCard([{ domain, packet, context }]);
|
||||
}
|
||||
|
||||
function engineNames(workflow: Json): string[] {
|
||||
const layers = (workflow.chart as Json).consultation_native_layers as Json;
|
||||
return ((layers.traditional_yogas as Json).names as string[]);
|
||||
}
|
||||
|
||||
test("traditional yogas: fixed label, engine names, general / career / wealth only", () => {
|
||||
assert.equal(EVIDENCE_CARD_LABELS.traditionalYogas, "传统格局,本站未验证,只作参考");
|
||||
const withYogas = (Object.keys(EVIDENCE_CARD_SPECS) as ConsultationDomain[])
|
||||
.filter((domain) => EVIDENCE_CARD_SPECS[domain].traditionalYogas);
|
||||
assert.deepEqual(withYogas.sort(), ["career", "general", "wealth"]);
|
||||
for (const chart of golden.charts) {
|
||||
const names = engineNames(chart.workflow);
|
||||
for (const domain of ["general", "career", "wealth"] as const) {
|
||||
const section = card(chart.workflow, domain).domain_sections[domain]!;
|
||||
if (names.length) assert.deepEqual(section.traditional_yogas, { label: EVIDENCE_CARD_LABELS.traditionalYogas, names }, `${chart.id}/${domain}`);
|
||||
else assert.equal("traditional_yogas" in section, false, `${chart.id}/${domain}`);
|
||||
}
|
||||
assert.equal("traditional_yogas" in card(chart.workflow, "parents").domain_sections.parents!, false);
|
||||
}
|
||||
});
|
||||
|
||||
test("Obama carries Sasa and Neecha Bhanga Raja; Jobs and Taylor carry Gajakesari (engine names)", () => {
|
||||
const general = (id: string) => (card(chartById(id).workflow, "general").domain_sections.general!.traditional_yogas as Json).names as string[];
|
||||
assert.ok(general("barack_obama").includes("Sasa Yoga"));
|
||||
assert.ok(general("barack_obama").includes("Neecha Bhanga Raja Yoga"));
|
||||
assert.ok(general("steve_jobs").includes("Gajakesari Yoga"));
|
||||
assert.ok(general("elizabeth_taylor").includes("Gajakesari Yoga"));
|
||||
});
|
||||
|
||||
test("no formed closed-list yoga: the field is absent", () => {
|
||||
const workflow = structuredClone(chartById("barack_obama").workflow);
|
||||
((workflow.chart as Json).consultation_native_layers as Json).traditional_yogas = { status: "executed", names: [] };
|
||||
assert.equal("traditional_yogas" in card(workflow, "general").domain_sections.general!, false);
|
||||
});
|
||||
|
||||
test("shared reading: traditional yogas only show strength", () => {
|
||||
assert.ok(CONDENSED_SHARED_READING_LINES.includes("`traditional_yogas` 只用来说明力量,不单独下结论,不算受冲,也不抵消受冲。"));
|
||||
});
|
||||
|
||||
test("career list: field by planet nature, public only with chart evidence (T4 text)", () => {
|
||||
const career = CONSULTATION_CONDENSED_CHECKLISTS.career!;
|
||||
assert.ok(career.includes("行业看星的本性:10 宫里的星、10 宫主、AmK,以及 10 宫主在 D9 的定位星。太阳 = 权力、公职、管理;月亮 = 公众、照护、流动;火星 = 体力、竞技、工程、军警;水星 = 沟通、写作、商业、分析;木星 = 教育、法律、顾问、宗教;金星 = 艺术、表演、娱乐、美;土星 = 劳动、组织、长期工程;罗睺 = 新技术、跨界、海外、大众传播。先说最强的一两颗,不平均罗列。"));
|
||||
assert.ok(career.includes("公众型还是幕后型要有依据:太阳或 10 宫主强且在角宫、AL 或 A10 落角宫、10 宫或命宫有入旺入庙星、`traditional_yogas` 有大格局,偏公众;10 宫主落 12 宫且无上述信号,才偏幕后。没有依据就不写这一句。不写「出头慢、越往后越稳、靠专业交付」这类人人适用的话,除非能指出具体盘面。"));
|
||||
});
|
||||
|
||||
test("opener keeps the affliction rule (T5 text)", () => {
|
||||
const body = natalAnswerShapeBody();
|
||||
assert.ok(body.startsWith("开场不要标题,先用一到三句人话回答问题;开场同样守受冲规则:不替用户断定在不在身边、几段感情、有没有病,不写程度结论,只说哪条线顺、哪条线有压力迹象。不给这件事起名字,开场不写行动清单。"));
|
||||
assert.equal(body.includes("第一句就是结论"), false);
|
||||
});
|
||||
@@ -79,12 +79,16 @@ test("each condensed list is 5–8 lines", () => {
|
||||
// 原值:全部清单 5–8 行,且只有 career / marriage / wealth 三份;
|
||||
// 新值:这三份仍 5–8 行;另有 TASK-consult-affliction-reading-20261001 定稿的 8 份(2–6 行,按任务书原文,不凑行数),
|
||||
// 只有 timing 没有本地清单;原因:该任务书 T2 / 决策 D5 补齐清单,定稿文本不得改意思。
|
||||
// 原值:career / marriage / wealth 5–8 行;新值:marriage / wealth 5–8 行、career 5–9 行;
|
||||
// 原因:TASK-consult-career-yoga-functional-20261002 T4 定稿给事业清单加两行(BUG-1176),定稿文本不凑行数。
|
||||
for (const domain of ["career", "marriage", "wealth"] as const) {
|
||||
const lines = CONSULTATION_CONDENSED_CHECKLISTS[domain]!;
|
||||
assert.ok(lines.length >= 5 && lines.length <= 8, `${domain}: ${lines.length} lines`);
|
||||
const max = domain === "career" ? 9 : 8;
|
||||
assert.ok(lines.length >= 5 && lines.length <= max, `${domain}: ${lines.length} lines`);
|
||||
}
|
||||
for (const [domain, lines] of Object.entries(CONSULTATION_CONDENSED_CHECKLISTS)) {
|
||||
assert.ok(lines!.length >= 2 && lines!.length <= 8, `${domain}: ${lines!.length} lines`);
|
||||
const max = domain === "career" ? 9 : 8;
|
||||
assert.ok(lines!.length >= 2 && lines!.length <= max, `${domain}: ${lines!.length} lines`);
|
||||
}
|
||||
assert.deepEqual(Object.keys(CONSULTATION_CONDENSED_CHECKLISTS).sort(), [
|
||||
"annual", "career", "children", "education", "family", "general", "health", "marriage", "migration", "parents", "wealth",
|
||||
|
||||
Reference in New Issue
Block a user