feat(consult): deliver the route's strict method with the evidence instead of listing 1592 filenames

Activating the skill returned 129,651 bytes, of which 99KB was a flat list of
1,592 undifferentiated file paths against 30KB of actual method. The one line
telling the model to open the strict-workflow router sat inside that method,
so no reference was ever opened and every answer was composed from the model's
own background knowledge over server evidence.

The route is already decided server-side and the skill already states which
checklist each route requires, so the selection needs no model turn: read the
mandated sections from the hash-pinned package and hand them to the model with
the evidence they apply to. A route the router declares no checklist for is
reported as such rather than filled in with another route's.

The receipt now reports delivered sections separately from model-initiated
reads, because only one of those is under the model's control.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-18 20:49:49 +08:00
parent 9d8b91ac02
commit ff70ba87b0
10 changed files with 365 additions and 12 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ test("chat session schema preserves the safe agent execution receipt", () => {
const receipt = {
runId: "run-1",
runtime: "mastra-agentic" as const,
skill: { name: "jyotish-vedic-astrology" as const, loaded: true, referenceReads: 0 },
skill: { name: "jyotish-vedic-astrology" as const, loaded: true, referenceReads: 0, methodologySections: 0 },
steps: [{ sequence: 1, kind: "skill" as const, name: "jyotish-vedic-astrology", status: "completed" as const }],
workflow: { route: "multi-domain", status: "ready", preciseTiming: "allowed", missingLayers: [], domains: ["general", "timing"] },
techniqueTruth: "verified",
@@ -738,14 +738,14 @@ test("the public receipt never carries the internal failure classification", ()
// guards the run from failing while building a successful response.
const receipt = agentExecutionReceiptSchema.parse({
runId: "run", runtime: "mastra-agentic",
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps,
workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [] },
});
assert.equal(receipt.steps.length, 2);
assert.throws(() => agentExecutionReceiptSchema.parse({
runId: "run", runtime: "mastra-agentic",
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps: state.steps,
workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [] },
}));
@@ -759,18 +759,18 @@ test("the public receipt never carries the model step budget diagnostics", () =>
assert.deepEqual(
consultationModelStepTelemetry(state),
{ modelStepCount: 8, skillReferenceReads: 0, modelFinishReason: "tool-calls" },
{ modelStepCount: 8, skillReferenceReads: 0, methodologySections: 0, modelFinishReason: "tool-calls" },
);
assert.deepEqual(
consultationModelStepTelemetry(createConsultationRuntimeState()),
{ modelStepCount: 0, skillReferenceReads: 0 },
{ modelStepCount: 0, skillReferenceReads: 0, methodologySections: 0 },
);
// The client receipt schema is strict, so leaking either field would make a
// successful run fail while serializing its own answer.
const receipt = agentExecutionReceiptSchema.parse({
runId: "run", runtime: "mastra-agentic",
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps: publicConsultationRuntimeSteps(state),
stepBudget: consultationStepBudgetReceipt(state),
workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [] },
@@ -778,7 +778,7 @@ test("the public receipt never carries the model step budget diagnostics", () =>
assert.doesNotMatch(JSON.stringify(receipt), /modelStepCount|modelFinishReason|tool-calls/);
assert.throws(() => agentExecutionReceiptSchema.parse({
runId: "run", runtime: "mastra-agentic",
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps: publicConsultationRuntimeSteps(state),
workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [] },
...consultationModelStepTelemetry(state),
@@ -807,6 +807,17 @@ test("the receipt reports how many reference documents the model opened", () =>
assert.equal(agentExecutionReceiptSchema.parse(receipt(state)).skill.referenceReads, 2);
});
test("the receipt separates method the server delivered from method the model went looking for", () => {
const state = createConsultationRuntimeState();
// A run where the model opened nothing is no longer a run composed without method: the strict
// checklist for the route travels with the evidence, so the two counts have to be readable apart.
state.methodologySectionCount = 3;
const parsed = agentExecutionReceiptSchema.parse(receipt(state));
assert.equal(parsed.skill.referenceReads, 0);
assert.equal(parsed.skill.methodologySections, 3);
assert.equal(consultationModelStepTelemetry(state).methodologySections, 3);
});
test("personal Agent exposes the Jyotish Skill and named server tool", async () => {
const state = createConsultationRuntimeState();
const agent = getJyotishAgent({
@@ -837,7 +848,7 @@ test("public stream filters private chunks and completes once", async () => {
const events = await collectAgentPublicEvents(chunks as never, {
runId: "run", requestId: "req", toolStatus: () => "ready",
receipt: () => ({
runId: "run", runtime: "mastra-agentic", skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
runId: "run", runtime: "mastra-agentic", skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps: [], workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [], domains: ["career"] },
}),
});
@@ -857,7 +868,7 @@ test("model answer text cannot forge a public Activity event", async () => {
], {
runId: "run", requestId: "req", toolStatus: () => "ready",
receipt: () => ({
runId: "run", runtime: "mastra-agentic", skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0 },
runId: "run", runtime: "mastra-agentic", skill: { name: "jyotish-vedic-astrology", loaded: true, referenceReads: 0, methodologySections: 0 },
steps: [], workflow: { route: "career", status: "ready", preciseTiming: "blocked", missingLayers: [], domains: ["career"] },
}),
});
@@ -897,6 +908,7 @@ function receipt(state: ReturnType<typeof createConsultationRuntimeState>) {
name: "jyotish-vedic-astrology" as const,
loaded: state.jyotishSkillLoaded,
referenceReads: state.skillReferenceReadCount,
methodologySections: state.methodologySectionCount,
},
steps: state.steps,
stepBudget: consultationStepBudgetReceipt(state),
@@ -0,0 +1,109 @@
import assert from "node:assert/strict";
import test from "node:test";
import {
consultationMethodologyForDomains,
markdownSection,
METHODOLOGY_SECTION_MAX_CHARS,
METHODOLOGY_TOTAL_MAX_CHARS,
} from "../src/lib/consultation-methodology.ts";
import { consultationDomainIds } from "../src/lib/consultation-domain-registry.ts";
test("the route's own strict checklist reaches the answer, not just the package listing", () => {
const methodology = consultationMethodologyForDomains(["career"]);
assert.ok(methodology, "career must resolve a methodology");
const career = methodology.sections.find((section) => section.title.includes("career-timing-strict"));
assert.ok(career, "the career strict route must be delivered as its own section");
assert.match(career.source, /strict-workflow-router\.md$/);
// The checklist is only useful if the specific instructions arrive with it.
assert.match(career.text, /D10/);
assert.match(career.text, /Opportunity contact/);
assert.ok(
methodology.sections.some((section) => section.title.includes("Shared mandatory baseline")),
"every route is read against the shared baseline",
);
assert.deepEqual(methodology.domains_without_strict_checklist, []);
});
test("a route the skill declares no checklist for is reported, not filled in with another route's", () => {
const methodology = consultationMethodologyForDomains(["health"]);
assert.ok(methodology);
assert.deepEqual(methodology.domains_without_strict_checklist, ["health"]);
assert.ok(
!methodology.sections.some((section) => section.title.includes("strict")),
"no strict section may be substituted for a route that has none",
);
assert.ok(
methodology.sections.some((section) => section.title.includes("Shared mandatory baseline")),
"the baseline still applies",
);
});
test("a multi-domain plan carries every executed route's checklist once", () => {
const methodology = consultationMethodologyForDomains(["career", "timing", "career"]);
assert.ok(methodology);
const titles = methodology.sections.map((section) => section.title);
assert.equal(titles.filter((title) => title.includes("career-timing-strict")).length, 1);
assert.equal(titles.filter((title) => title.includes("event-timing-strict")).length, 1);
});
test("no plan can spend the answer's context on method", () => {
for (const domain of consultationDomainIds) {
const methodology = consultationMethodologyForDomains([domain]);
assert.ok(methodology, `${domain} must resolve`);
const total = methodology.sections.reduce((sum, section) => sum + section.text.length, 0);
assert.ok(
total <= METHODOLOGY_TOTAL_MAX_CHARS,
`${domain} delivered ${total} chars, over the ${METHODOLOGY_TOTAL_MAX_CHARS} budget`,
);
for (const section of methodology.sections) {
assert.ok(section.text.length <= METHODOLOGY_SECTION_MAX_CHARS);
}
}
});
test("the widest legal plan still fits the budget", () => {
const methodology = consultationMethodologyForDomains(["career", "marriage", "wealth", "timing"]);
assert.ok(methodology);
const total = methodology.sections.reduce((sum, section) => sum + section.text.length, 0);
assert.ok(total <= METHODOLOGY_TOTAL_MAX_CHARS, `delivered ${total} chars`);
});
test("further reading offers the references the skill names, and only ones that exist", () => {
const methodology = consultationMethodologyForDomains(["career"]);
assert.ok(methodology);
assert.ok(methodology.further_reading.length > 0, "the skill names references worth reading");
assert.ok(
methodology.further_reading.includes("references/strict-workflow-router.md"),
"the router the skill points at must be reachable on purpose",
);
for (const path of methodology.further_reading) {
assert.match(path, /^references\//);
assert.ok(!path.includes(".."), "no path may escape the package");
}
assert.ok(
methodology.further_reading.length < 100,
"the index exists to replace the package listing, not to reproduce it",
);
});
test("the delivered method is quoted from the pinned skill version", () => {
const methodology = consultationMethodologyForDomains(["career"]);
assert.ok(methodology);
assert.equal(methodology.skill, "jyotish-vedic-astrology");
assert.match(methodology.version, /^\d+\.\d+\.\d+$/);
});
test("a section is found by heading text so the router may be renumbered", () => {
const source = [
"# Doc",
"## 3. `career-timing-strict`",
"body one",
"## 4. next",
"body two",
].join("\n");
const section = markdownSection(source, "career-timing-strict");
assert.ok(section);
assert.match(section, /body one/);
assert.ok(!section.includes("body two"), "a section stops at the next heading");
assert.equal(markdownSection(source, "absent-route"), null);
});