refactor(consult): chat binds the method's truth boundaries, not the engine manual (BUG-1256 step 2)
The method block bound into every chat turn quoted most of SKILL.md (benchmark scores, CLI flags, oracle queues, file paths) plus the shared method, whose output contract asks for JSON verdicts, A/B/C/D confidence, audit tables, raw data and web verification - the opposite of the chat shape. Chat now quotes only the truth-boundary sections and adds CHAT_METHOD_BOUNDARIES for the limits from the dropped sections it still has to keep. SKILL.md and the shared method file are unchanged for reports and skill_read. Natal system prompt 55,242 -> 26,591 characters. DeepSeek A/B on public golden charts (flash 10 questions): input 24,560 -> 14,025 tokens, 37.8 -> 30.3 s, no regression in automatic checks or reading; a high-rigor request still says plainly that no external check was done. Full suite 4970 / fail 24, identical to b8385adb; build keeps / Static. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6a372bc3a8
commit
c76fdda7ab
@@ -5,7 +5,6 @@ import {
|
||||
resolveLiveJyotishSkill,
|
||||
resolveLiveJyotishSkillRuntimePath,
|
||||
} from "../lib/skill-package-registry.ts";
|
||||
import { sharedConsultationMethodMarkdown } from "../lib/consultation-methodology.ts";
|
||||
|
||||
const skill = resolveLiveJyotishSkill();
|
||||
|
||||
@@ -18,24 +17,41 @@ export const jyotishSkillPackage = skill;
|
||||
export const jyotishSkillRuntimePath = resolveLiveJyotishSkillRuntimePath(skill);
|
||||
|
||||
/**
|
||||
* Headings from the commercial SKILL.md that govern answering a natal chart.
|
||||
* The rest of that file is a local-agent / maintainer manual (CLI indexes,
|
||||
* construction rules, celebrity case catalogs) and stays in the package for
|
||||
* skill_read rather than being stuffed into every consultation prompt.
|
||||
* What a chat answer takes from the commercial SKILL.md (BUG-1256). The file is
|
||||
* mostly the engine and report manual: benchmark scores, CLI flags, oracle
|
||||
* queues, file paths, and output contracts written for reports ("only output
|
||||
* verdict + confidence + audit + raw evidence", "every transit prediction gives
|
||||
* a period + action + [A]/[B]/[C]", "every reading must be web-verified").
|
||||
* Bound into every chat turn, those contradicted the chat shape and made up
|
||||
* most of a 55k-character system prompt. Chat keeps the truth-boundary
|
||||
* sections only; the full file stays in the package for skill_read.
|
||||
* `body: true` keeps the section's own text (blockquotes and file-reading
|
||||
* lists dropped); `subsections` are the `###` parts kept under it.
|
||||
*/
|
||||
const RUNTIME_METHOD_HEADINGS = [
|
||||
"商业运行时路由",
|
||||
"关联技法完整调取",
|
||||
"强制工作流",
|
||||
"五层硬约束",
|
||||
"强制规则",
|
||||
"当前最硬的未闭环点",
|
||||
"核心方法论",
|
||||
"强制规范速查",
|
||||
"注意事项",
|
||||
const CHAT_METHOD_SELECTION = [
|
||||
{ section: "商业运行时路由", body: true, subsections: ["Skill truth overlay 硬边界", "Ashtottari"] },
|
||||
{ section: "关联技法完整调取", body: false, subsections: ["P0/P1 观察层"] },
|
||||
{ section: "核心方法论", body: false, subsections: ["三层验证法"] },
|
||||
] as const;
|
||||
|
||||
const DROPPED_RUNTIME_SUBHEADINGS = ["开源复用边界冻结"] as const;
|
||||
/** Lines of a kept section body that only tell an agent which files to open. */
|
||||
function isFilePointerLine(line: string): boolean {
|
||||
return line.startsWith(">") || /^\d+\.\s/.test(line) || line.includes("渐进读取");
|
||||
}
|
||||
|
||||
/**
|
||||
* The boundaries from the dropped sections that a chat answer still has to
|
||||
* keep, in the product's own words (BUG-1256). Outside the verbatim skill
|
||||
* block, so the excerpt stays a faithful quote of the live file.
|
||||
*/
|
||||
export const CHAT_METHOD_BOUNDARIES = `<chat-method-boundaries>
|
||||
以下是方法书里没有摘进来的章节中,对话回答仍要守的边界(全文仍在技能目录里):
|
||||
- 判断顺序:先看本命有没有这件事的底子,再看大运有没有把它激活,再看够不够落到现实,最后才谈时间;不从一段大运或一次行运直接跳到「会发生」。
|
||||
- 谈应期至少要 Vimshottari 与 Narayana 两套大运同向;两套冲突时降低把握,不给确定说法。
|
||||
- 大运起止日期只引用卡上给出的,不自己推算;大运精细边界和 Shadbala 绝对值并未全部完成外部校准,说日期和力量时不说「已校准」「精确到」。
|
||||
- 不宣称全球第一、所有技法已封顶或完美精度。
|
||||
- 用户要求「高严谨、拉满三大引擎、联网核验、拿真实案例验证」时:这次对话里没有做外部引擎比对、全网资料核验和真实案例校准,照实说明,结论降一级,不假装做过。
|
||||
</chat-method-boundaries>`;
|
||||
|
||||
function publishedSkillBody(): string {
|
||||
const raw = readFileSync(resolve(skill.resolvedPath, "SKILL.md"), "utf8");
|
||||
@@ -43,21 +59,6 @@ function publishedSkillBody(): string {
|
||||
return (frontmatter ? raw.slice(frontmatter[0].length) : raw).trim();
|
||||
}
|
||||
|
||||
function dropSubheadings(section: string, dropped: readonly string[]): string {
|
||||
const lines = section.split("\n");
|
||||
const kept: string[] = [];
|
||||
let skipping = false;
|
||||
for (const line of lines) {
|
||||
if (line.startsWith("### ")) {
|
||||
skipping = dropped.some((heading) => line.includes(heading));
|
||||
} else if (line.startsWith("## ")) {
|
||||
skipping = false;
|
||||
}
|
||||
if (!skipping) kept.push(line);
|
||||
}
|
||||
return kept.join("\n").trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mastra answers a skill activation with the entrypoint *and* a flat listing of
|
||||
* every file in the package, which for this package measured 129,651 bytes: the
|
||||
@@ -97,8 +98,17 @@ function boundMethod(): string {
|
||||
|
||||
const kept = sections.flatMap((section) => {
|
||||
const heading = section[0] ?? "";
|
||||
if (!RUNTIME_METHOD_HEADINGS.some((wanted) => heading.includes(wanted))) return [];
|
||||
const text = dropSubheadings(section.join("\n"), DROPPED_RUNTIME_SUBHEADINGS);
|
||||
const wanted = CHAT_METHOD_SELECTION.find((entry) => heading.includes(entry.section));
|
||||
if (!wanted) return [];
|
||||
const parts: string[][] = [[]];
|
||||
for (const line of section) {
|
||||
if (line.startsWith("### ")) parts.push([line]);
|
||||
else parts[parts.length - 1]!.push(line);
|
||||
}
|
||||
const [own = [], ...subsections] = parts;
|
||||
const body = wanted.body ? own.filter((line) => !isFilePointerLine(line)) : own.slice(0, 1);
|
||||
const keptSubsections = subsections.filter((part) => wanted.subsections.some((name) => (part[0] ?? "").includes(name)));
|
||||
const text = [...body, ...keptSubsections.flat()].join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
||||
return text.length > 0 ? [text] : [];
|
||||
});
|
||||
|
||||
@@ -118,9 +128,7 @@ function methodBlock(reportSkeleton: string) {
|
||||
${BOUND_METHOD_MARKER}
|
||||
${boundMethod()}
|
||||
</jyotish-skill>
|
||||
<jyotish-shared-method>
|
||||
${sharedConsultationMethodMarkdown()}
|
||||
</jyotish-shared-method>`;
|
||||
${CHAT_METHOD_BOUNDARIES}`;
|
||||
}
|
||||
|
||||
/** Method body + marker, without the natal Level 2 report skeleton. Window agents use this. */
|
||||
|
||||
Reference in New Issue
Block a user