fix(consult): read the live skill tree instead of a hash-pinned snapshot
Manual SKILL.md updates were blocked by registry sha256 and a byte-equal versions/ gate. Consult now loads the operator-maintained tree; rectification and personal-report stay hashed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import test from "node:test";
|
||||
import { Agent } from "@mastra/core/agent";
|
||||
import {
|
||||
@@ -17,9 +17,9 @@ function probeAgent(options: Record<string, unknown>) {
|
||||
return new Agent({ id: "skill-binding-probe", name: "Probe", model, instructions: "x", ...options } as never);
|
||||
}
|
||||
|
||||
function publishedSkillBody() {
|
||||
const published = readFileSync(resolve(jyotishSkillPackage.resolvedPath, "SKILL.md"), "utf8");
|
||||
return published.slice(published.indexOf("---", 3) + 4).trim();
|
||||
function liveSkillBody() {
|
||||
const live = readFileSync(resolve(jyotishSkillPackage.resolvedPath, "SKILL.md"), "utf8");
|
||||
return live.slice(live.indexOf("---", 3) + 4).trim();
|
||||
}
|
||||
|
||||
function boundMethodText() {
|
||||
@@ -29,20 +29,23 @@ function boundMethodText() {
|
||||
return jyotishSkillMethodBlock.slice(jyotishSkillMethodBlock.indexOf("\n", opened) + 1, closed).trim();
|
||||
}
|
||||
|
||||
test("the method the model follows is the published one, not the working tree's", () => {
|
||||
const body = publishedSkillBody();
|
||||
test("the method the model follows is the live skill, not a hashed snapshot", () => {
|
||||
const body = liveSkillBody();
|
||||
const bound = boundMethodText();
|
||||
|
||||
assert.match(jyotishSkillMethodBlock, new RegExp(`version="${jyotishSkillPackage.version}"`));
|
||||
// Every bound line still comes from the hash-checked package. The route into
|
||||
// the loader is that same package, so skill_read can only reach what the
|
||||
// registry hash covers.
|
||||
assert.match(jyotishSkillMethodBlock, new RegExp(`name="${jyotishSkillPackage.name}"`));
|
||||
assert.doesNotMatch(jyotishSkillMethodBlock, /<jyotish-skill name="[^"]+" version="/);
|
||||
for (const line of bound.split("\n")) {
|
||||
if (line.length === 0) continue;
|
||||
assert.ok(body.includes(line), line.slice(0, 80));
|
||||
}
|
||||
assert.ok(jyotishSkillRuntimePath.includes(jyotishSkillPackage.sha256));
|
||||
assert.ok(jyotishSkillRuntimePath.endsWith(jyotishSkillPackage.name));
|
||||
assert.equal(jyotishSkillRuntimePath.includes("/versions/"), false);
|
||||
assert.equal(existsSync(join(jyotishSkillRuntimePath, "versions")), false);
|
||||
assert.equal(
|
||||
realpathSync(join(jyotishSkillRuntimePath, "SKILL.md")),
|
||||
realpathSync(join(jyotishSkillPackage.resolvedPath, "SKILL.md")),
|
||||
);
|
||||
});
|
||||
|
||||
test("the bound method is the runtime excerpt, not the maintainer manual", () => {
|
||||
@@ -50,7 +53,7 @@ test("the bound method is the runtime excerpt, not the maintainer manual", () =>
|
||||
// answering contract and the repo-construction notes. Binding the whole
|
||||
// file is what pushed Mastra past its 500-line warning; the excerpt keeps
|
||||
// the contract and drops the notes.
|
||||
const body = publishedSkillBody();
|
||||
const body = liveSkillBody();
|
||||
const bound = boundMethodText();
|
||||
|
||||
for (const heading of ["商业运行时路由", "关联技法完整调取", "强制工作流", "五层硬约束", "核心方法论", "注意事项", "commercial_skill_truth_overlay"]) {
|
||||
|
||||
Reference in New Issue
Block a user