mirror of
https://github.com/merlinhu1/truthmark.git
synced 2026-08-25 07:53:25 +02:00
docs: align Truthmark workflow docs and skill guidance
This commit is contained in:
@@ -14,7 +14,7 @@ describe("renderTruthSyncInstructions", () => {
|
||||
expect(instructions).toContain("Automatic finish-time trigger");
|
||||
expect(instructions).toContain("use the truthmark-sync skill before finishing");
|
||||
expect(instructions).toContain(
|
||||
"OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Gemini CLI /truthmark:sync",
|
||||
"OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Gemini CLI /truthmark:sync",
|
||||
);
|
||||
expect(instructions).toContain("staged, unstaged, and untracked functional code files");
|
||||
expect(instructions).toContain("Run relevant tests before finishing");
|
||||
|
||||
@@ -658,6 +658,76 @@ Update truth when:
|
||||
}
|
||||
});
|
||||
|
||||
it("reports stale Claude Code generated skill surfaces", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
try {
|
||||
await initializeRepo(repo.rootDir);
|
||||
await repo.writeFile(
|
||||
".claude/skills/truthmark-sync/SKILL.md",
|
||||
`${await repo.readFile(".claude/skills/truthmark-sync/SKILL.md")}\nmanual drift\n`,
|
||||
);
|
||||
|
||||
const result = await runCheck(repo.rootDir);
|
||||
|
||||
expect(result.diagnostics).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
category: "generated-surface",
|
||||
severity: "review",
|
||||
file: ".claude/skills/truthmark-sync/SKILL.md",
|
||||
message: expect.stringContaining("stale"),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
} finally {
|
||||
await repo.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it("reports stale GitHub Copilot generated prompt surfaces", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
try {
|
||||
await repo.writeFile(
|
||||
".truthmark/config.yml",
|
||||
`version: 1
|
||||
platforms:
|
||||
- github-copilot
|
||||
authority:
|
||||
- TRUTHMARK.md
|
||||
- docs/truthmark/areas.md
|
||||
frontmatter:
|
||||
required: []
|
||||
recommended: []
|
||||
ignore: []
|
||||
realization:
|
||||
enabled: true
|
||||
`,
|
||||
);
|
||||
await initializeRepo(repo.rootDir);
|
||||
await repo.writeFile(
|
||||
".github/prompts/truthmark-sync.prompt.md",
|
||||
`${await repo.readFile(".github/prompts/truthmark-sync.prompt.md")}\nmanual drift\n`,
|
||||
);
|
||||
|
||||
const result = await runCheck(repo.rootDir);
|
||||
|
||||
expect(result.diagnostics).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
category: "generated-surface",
|
||||
severity: "review",
|
||||
file: ".github/prompts/truthmark-sync.prompt.md",
|
||||
message: expect.stringContaining("stale"),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
} finally {
|
||||
await repo.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it("ignores manual version notes outside managed instruction blocks", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ describe("runConfig", () => {
|
||||
"area_files_root: docs/truthmark/areas",
|
||||
);
|
||||
const config = await repo.readFile(".truthmark/config.yml");
|
||||
expect(config).toContain(" - github-copilot");
|
||||
expect(config).toContain(" - gemini-cli");
|
||||
expect(config).toContain("features: docs/features");
|
||||
expect(config).toContain("docs/features/**/*.md");
|
||||
expect(config).not.toContain("features_current");
|
||||
|
||||
@@ -24,7 +24,7 @@ realization:
|
||||
expect(result.diagnostics).toEqual([]);
|
||||
expect(result.config).toMatchObject({
|
||||
version: 1,
|
||||
platforms: ["codex", "opencode", "claude-code"],
|
||||
platforms: ["codex", "opencode", "claude-code", "github-copilot", "gemini-cli"],
|
||||
authority: ["TRUTHMARK.md"],
|
||||
docs: {
|
||||
layout: "hierarchical",
|
||||
@@ -64,7 +64,7 @@ instruction_targets:
|
||||
- AGENTS.md
|
||||
platforms:
|
||||
- codex
|
||||
- cursor
|
||||
- github-copilot
|
||||
frontmatter:
|
||||
required: []
|
||||
recommended:
|
||||
@@ -79,7 +79,7 @@ realization:
|
||||
const result = await loadConfig(repo.rootDir);
|
||||
|
||||
expect(result.diagnostics).toEqual([]);
|
||||
expect(result.config?.platforms).toEqual(["codex", "cursor"]);
|
||||
expect(result.config?.platforms).toEqual(["codex", "github-copilot"]);
|
||||
expect(result.config?.instructionTargets).toEqual(["AGENTS.md"]);
|
||||
expect(result.config?.frontmatter.recommended).toEqual(["status"]);
|
||||
expect(result.config?.ignore).toEqual(["dist/**"]);
|
||||
|
||||
@@ -100,11 +100,16 @@ describe("classifyPath", () => {
|
||||
expect(classifyPath("vendor/lib/index.rb", ["vendor/**"])).toBe("ignored");
|
||||
expect(classifyPath(".truthmark/cache/state.json", [])).toBe("derived");
|
||||
expect(classifyPath(".truthmark/sync/report.md", [])).toBe("derived");
|
||||
expect(classifyPath(".claude/skills/truthmark-sync/SKILL.md", [])).toBe(
|
||||
"derived",
|
||||
);
|
||||
expect(classifyPath(".codex/skills/truthmark-sync/SKILL.md", [])).toBe("derived");
|
||||
expect(classifyPath(".opencode/skills/truthmark-sync/SKILL.md", [])).toBe("derived");
|
||||
expect(classifyPath("skills/truthmark-sync/SKILL.md", [])).toBe("markdown");
|
||||
expect(classifyPath(".cursor/rules/truthmark.mdc", [])).toBe("derived");
|
||||
expect(classifyPath(".github/copilot-instructions.md", [])).toBe("derived");
|
||||
expect(classifyPath(".github/prompts/truthmark-sync.prompt.md", [])).toBe(
|
||||
"derived",
|
||||
);
|
||||
expect(classifyPath("CLAUDE.md", [])).toBe("derived");
|
||||
expect(classifyPath("GEMINI.md", [])).toBe("derived");
|
||||
expect(classifyPath(".gemini/commands/truthmark/sync.toml", [])).toBe("derived");
|
||||
|
||||
@@ -19,13 +19,19 @@ describe("runInit instruction integration", () => {
|
||||
|
||||
expect(agents.match(/<!-- truthmark:start -->/g)).toHaveLength(1);
|
||||
expect(agents.match(/<!-- truthmark:end -->/g)).toHaveLength(1);
|
||||
expect(agents.split("\n").length).toBeLessThanOrEqual(65);
|
||||
expect(agents.split("\n").length).toBeLessThanOrEqual(25);
|
||||
expect(agents.slice(0, 220)).toContain("Truthmark Workflow");
|
||||
expect(agents).toContain("/skill truthmark-structure");
|
||||
expect(agents).toContain("/skill truthmark-sync");
|
||||
expect(agents).toContain("/skill truthmark-check");
|
||||
expect(agents).toContain(`Generated by Truthmark ${TRUTHMARK_VERSION}`);
|
||||
expect(agents).toContain("Automatic finish-time trigger");
|
||||
expect(agents).toContain("Sync: finish-time when functional code changed");
|
||||
expect(agents).toContain("code changed -> tests -> Sync -> report");
|
||||
expect(agents).toContain("Delegation is host-owned");
|
||||
expect(agents).toContain(
|
||||
"Explicit workflows: Truth Structure, Truth Realize, Truth Check",
|
||||
);
|
||||
expect(agents).toContain("load the installed skill for details");
|
||||
expect(agents).not.toContain("/skill truthmark-structure");
|
||||
expect(agents).not.toContain("/skill truthmark-check");
|
||||
expect(agents).not.toContain(
|
||||
"truthmark check --json --workflow truth-sync",
|
||||
);
|
||||
@@ -33,8 +39,8 @@ describe("runInit instruction integration", () => {
|
||||
expect(agents).not.toContain("Truth Sync: completed");
|
||||
expect(agents).not.toContain("Truth Sync: skipped");
|
||||
expect(agents).not.toContain("Truth Realize: completed");
|
||||
expect(agents).toContain("Truth Check");
|
||||
expect(agents).toContain("Inspect the current checkout directly");
|
||||
expect(agents).not.toContain("### Truth Check");
|
||||
expect(agents).toContain("inspect checkout directly");
|
||||
expect(agents).not.toContain("truthmark packet --changed");
|
||||
|
||||
await expect(fs.stat(`${repo.rootDir}/OPENCODE.md`)).rejects.toThrow();
|
||||
@@ -73,12 +79,10 @@ realization:
|
||||
const agents = await repo.readFile("AGENTS.md");
|
||||
|
||||
expect(agents.match(/<!-- truthmark:start -->/g)).toHaveLength(1);
|
||||
expect(agents).toContain("host supports subagent dispatch");
|
||||
expect(agents).toContain("Delegation is host-owned");
|
||||
expect(agents).not.toContain(".truthmark/local.yml");
|
||||
expect(agents).not.toContain("truth_sync.sync_agent");
|
||||
expect(agents).toContain(
|
||||
"Later functional-code changes reopen the finish-time requirement",
|
||||
);
|
||||
expect(agents).toContain("later functional changes reopen the gate");
|
||||
} finally {
|
||||
await repo.cleanup();
|
||||
}
|
||||
|
||||
+130
-14
@@ -143,17 +143,24 @@ describe("runInit", () => {
|
||||
".opencode/skills/truthmark-check/SKILL.md",
|
||||
);
|
||||
const claudeInstructions = await repo.readFile("CLAUDE.md");
|
||||
const syncClaudeSkill = await repo.readFile(
|
||||
".claude/skills/truthmark-sync/SKILL.md",
|
||||
);
|
||||
|
||||
expect(agents.match(/<!-- truthmark:start -->/g)).toHaveLength(1);
|
||||
expect(claudeInstructions).toContain("Truthmark Workflow");
|
||||
expect(claudeInstructions.split("\n").length).toBeLessThanOrEqual(65);
|
||||
expect(agents).toContain("### Truth Structure");
|
||||
expect(claudeInstructions.split("\n").length).toBeLessThanOrEqual(25);
|
||||
expect(agents).not.toContain("### Truth Structure");
|
||||
expect(agents).toContain(`Generated by Truthmark ${TRUTHMARK_VERSION}`);
|
||||
expect(agents).toContain("Automatic finish-time trigger");
|
||||
expect(agents).toContain("Sync: finish-time when functional code changed");
|
||||
expect(agents).toContain("use the truthmark-sync skill before finishing");
|
||||
expect(agents).toContain("/skill truthmark-sync");
|
||||
expect(agents).toContain("/skill truthmark-structure");
|
||||
expect(agents).toContain("/skill truthmark-check");
|
||||
expect(agents).not.toContain("/skill truthmark-structure");
|
||||
expect(agents).not.toContain("/skill truthmark-check");
|
||||
expect(agents).toContain(
|
||||
"Explicit workflows: Truth Structure, Truth Realize, Truth Check",
|
||||
);
|
||||
expect(agents).toContain("load the installed skill for details");
|
||||
expect(agents).toContain("Truthmark hierarchy:");
|
||||
expect(agents).toContain("Root route index: docs/truthmark/areas.md");
|
||||
expect(agents).toContain(
|
||||
@@ -166,15 +173,14 @@ describe("runInit", () => {
|
||||
expect(agents).not.toContain(
|
||||
"truthmark check --json --workflow truth-sync",
|
||||
);
|
||||
expect(agents).toContain("### Manual Truth Realize");
|
||||
expect(agents).toContain("### Truth Check");
|
||||
expect(agents).toContain("Only run when the user explicitly asks");
|
||||
expect(agents).toContain("host supports subagent dispatch");
|
||||
expect(agents).not.toContain("### Manual Truth Realize");
|
||||
expect(agents).not.toContain("### Truth Check");
|
||||
expect(agents).toContain("Delegation is host-owned");
|
||||
expect(agents).not.toContain(".truthmark/local.yml");
|
||||
expect(agents).not.toContain("truth_sync.sync_agent");
|
||||
expect(agents).toContain("must not rewrite functional code");
|
||||
expect(agents).toContain("do not edit truth docs or truth routing");
|
||||
expect(agents).toContain("documentation-only change");
|
||||
expect(agents).toContain("code changed -> tests -> Sync -> report");
|
||||
expect(agents).not.toContain("Truth Sync: completed");
|
||||
expect(agents).not.toContain("Truth Realize: completed");
|
||||
expect(agents.match(/Truthmark hierarchy:/g)).toHaveLength(1);
|
||||
@@ -212,6 +218,10 @@ describe("runInit", () => {
|
||||
expect(syncOpenCodeSkill).toContain(
|
||||
"Use this skill automatically before finishing",
|
||||
);
|
||||
expect(syncClaudeSkill).toContain("name: truthmark-sync");
|
||||
expect(syncClaudeSkill).toContain(
|
||||
"Use this skill automatically before finishing",
|
||||
);
|
||||
expect(realizeSkill).toContain("name: truthmark-realize");
|
||||
expect(realizeSkill).toContain("user-invocable: true");
|
||||
expect(realizeSkill).toContain("may write functional code only");
|
||||
@@ -257,6 +267,13 @@ describe("runInit", () => {
|
||||
diagnostic.file === ".codex/skills/truthmark-sync/SKILL.md",
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
result.diagnostics.some(
|
||||
(diagnostic) =>
|
||||
diagnostic.category === "truth-sync" &&
|
||||
diagnostic.file === ".claude/skills/truthmark-sync/SKILL.md",
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
result.diagnostics.some(
|
||||
(diagnostic) =>
|
||||
@@ -290,7 +307,6 @@ describe("runInit", () => {
|
||||
`version: 1
|
||||
platforms:
|
||||
- codex
|
||||
- cursor
|
||||
- github-copilot
|
||||
- gemini-cli
|
||||
authority:
|
||||
@@ -312,12 +328,15 @@ realization:
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.codex/skills/truthmark-sync/SKILL.md`),
|
||||
).resolves.toBeTruthy();
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.cursor/rules/truthmark.mdc`),
|
||||
).resolves.toBeTruthy();
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.github/copilot-instructions.md`),
|
||||
).resolves.toBeTruthy();
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.github/prompts/truthmark-sync.prompt.md`),
|
||||
).resolves.toBeTruthy();
|
||||
expect(
|
||||
await repo.readFile(".github/prompts/truthmark-sync.prompt.md"),
|
||||
).toContain("GitHub Copilot /truthmark-sync");
|
||||
await expect(fs.stat(`${repo.rootDir}/GEMINI.md`)).resolves.toBeTruthy();
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.gemini/commands/truthmark/structure.toml`),
|
||||
@@ -356,6 +375,103 @@ realization:
|
||||
}
|
||||
});
|
||||
|
||||
it("installs Claude Code project skills when only claude-code is configured", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
try {
|
||||
await repo.writeFile(
|
||||
".truthmark/config.yml",
|
||||
`version: 1
|
||||
platforms:
|
||||
- claude-code
|
||||
authority:
|
||||
- TRUTHMARK.md
|
||||
- docs/truthmark/areas.md
|
||||
instruction_targets:
|
||||
- AGENTS.md
|
||||
frontmatter:
|
||||
required: []
|
||||
recommended: []
|
||||
ignore: []
|
||||
realization:
|
||||
enabled: true
|
||||
`,
|
||||
);
|
||||
|
||||
await runInit(repo.rootDir);
|
||||
|
||||
expect(await repo.readFile("CLAUDE.md")).toContain("Truthmark Workflow");
|
||||
expect(await repo.readFile("CLAUDE.md")).toContain(
|
||||
"Claude Code /truthmark-sync",
|
||||
);
|
||||
expect(
|
||||
await repo.readFile(".claude/skills/truthmark-sync/SKILL.md"),
|
||||
).toContain("Claude Code /truthmark-sync");
|
||||
expect(
|
||||
await repo.readFile(".claude/skills/truthmark-structure/SKILL.md"),
|
||||
).toContain("name: truthmark-structure");
|
||||
expect(
|
||||
await repo.readFile(".claude/skills/truthmark-check/SKILL.md"),
|
||||
).toContain("name: truthmark-check");
|
||||
expect(
|
||||
await repo.readFile(".claude/skills/truthmark-realize/SKILL.md"),
|
||||
).toContain("Claude Code /truthmark-realize");
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.codex/skills/truthmark-sync/SKILL.md`),
|
||||
).rejects.toThrow();
|
||||
} finally {
|
||||
await repo.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it("installs GitHub Copilot prompt files when only github-copilot is configured", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
try {
|
||||
await repo.writeFile(
|
||||
".truthmark/config.yml",
|
||||
`version: 1
|
||||
platforms:
|
||||
- github-copilot
|
||||
authority:
|
||||
- TRUTHMARK.md
|
||||
- docs/truthmark/areas.md
|
||||
instruction_targets:
|
||||
- AGENTS.md
|
||||
frontmatter:
|
||||
required: []
|
||||
recommended: []
|
||||
ignore: []
|
||||
realization:
|
||||
enabled: true
|
||||
`,
|
||||
);
|
||||
|
||||
await runInit(repo.rootDir);
|
||||
|
||||
expect(await repo.readFile(".github/copilot-instructions.md")).toContain(
|
||||
"Truthmark Workflow",
|
||||
);
|
||||
expect(
|
||||
await repo.readFile(".github/prompts/truthmark-sync.prompt.md"),
|
||||
).toContain("GitHub Copilot /truthmark-sync");
|
||||
expect(
|
||||
await repo.readFile(".github/prompts/truthmark-structure.prompt.md"),
|
||||
).toContain("name: truthmark-structure");
|
||||
expect(
|
||||
await repo.readFile(".github/prompts/truthmark-check.prompt.md"),
|
||||
).toContain("name: truthmark-check");
|
||||
expect(
|
||||
await repo.readFile(".github/prompts/truthmark-realize.prompt.md"),
|
||||
).toContain("GitHub Copilot /truthmark-realize");
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.codex/skills/truthmark-sync/SKILL.md`),
|
||||
).rejects.toThrow();
|
||||
} finally {
|
||||
await repo.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves existing docs and authored AGENTS content while scaffolding hierarchy", async () => {
|
||||
const repo = await createTempRepo();
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ describe("installed workflow contract", () => {
|
||||
const syncOpenCodeSkill = await repo.readFile(
|
||||
".opencode/skills/truthmark-sync/SKILL.md",
|
||||
);
|
||||
const syncClaudeSkill = await repo.readFile(
|
||||
".claude/skills/truthmark-sync/SKILL.md",
|
||||
);
|
||||
const realizeSkill = await repo.readFile(
|
||||
".codex/skills/truthmark-realize/SKILL.md",
|
||||
);
|
||||
@@ -39,23 +42,23 @@ describe("installed workflow contract", () => {
|
||||
".codex/skills/truthmark-check/SKILL.md",
|
||||
);
|
||||
|
||||
expect(agents.split("\n").length).toBeLessThanOrEqual(65);
|
||||
expect(agents).toContain("### Truth Structure");
|
||||
expect(agents.split("\n").length).toBeLessThanOrEqual(25);
|
||||
expect(agents).not.toContain("### Truth Structure");
|
||||
expect(agents).toContain("### Truth Sync");
|
||||
expect(agents).toContain("### Truth Check");
|
||||
expect(agents).not.toContain("### Truth Check");
|
||||
expect(agents).toContain(`Generated by Truthmark ${TRUTHMARK_VERSION}`);
|
||||
expect(agents).toContain("use the truthmark-sync skill before finishing");
|
||||
expect(agents).toContain("/skill truthmark-structure");
|
||||
expect(agents).toContain("/skill truthmark-sync");
|
||||
expect(agents).toContain("/skill truthmark-check");
|
||||
expect(agents).not.toContain("/skill truthmark-structure");
|
||||
expect(agents).not.toContain("/skill truthmark-check");
|
||||
expect(agents).toContain(
|
||||
"Explicit workflows: Truth Structure, Truth Realize, Truth Check",
|
||||
);
|
||||
expect(agents).not.toContain(
|
||||
"truthmark check --json --workflow truth-sync",
|
||||
);
|
||||
expect(agents).toContain("Inspect the current checkout directly");
|
||||
expect(agents).toContain("### Manual Truth Realize");
|
||||
expect(agents).toContain(
|
||||
"This is a manual installed instruction or skill, not a dedicated CLI command.",
|
||||
);
|
||||
expect(agents).toContain("inspect checkout directly");
|
||||
expect(agents).not.toContain("### Manual Truth Realize");
|
||||
expect(agents).not.toContain("Truth Sync: completed");
|
||||
expect(agents).not.toContain("Truth Realize: completed");
|
||||
expect(structureSkill).toContain("name: truthmark-structure");
|
||||
@@ -72,6 +75,10 @@ describe("installed workflow contract", () => {
|
||||
"direct checkout inspection is the canonical path",
|
||||
);
|
||||
expect(syncOpenCodeSkill).toContain("name: truthmark-sync");
|
||||
expect(syncClaudeSkill).toContain("name: truthmark-sync");
|
||||
expect(syncClaudeSkill).toContain(
|
||||
"Use this skill automatically before finishing",
|
||||
);
|
||||
expect(realizeSkill).toContain("name: truthmark-realize");
|
||||
expect(realizeSkill).toContain(
|
||||
"Use this skill only when the user explicitly asks",
|
||||
|
||||
@@ -39,6 +39,9 @@ describe("init and check workflow acceptance", () => {
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.codex/skills/truthmark-check/SKILL.md`),
|
||||
).resolves.toBeTruthy();
|
||||
await expect(
|
||||
fs.stat(`${repo.rootDir}/.claude/skills/truthmark-sync/SKILL.md`),
|
||||
).resolves.toBeTruthy();
|
||||
|
||||
const checkResult = await runCli(["check", "--json"], { cwd: repo.rootDir });
|
||||
|
||||
|
||||
@@ -50,8 +50,15 @@ describe("discoverMarkdownDocuments", () => {
|
||||
".opencode/skills/truthmark-sync/SKILL.md",
|
||||
"# Ignore me\n",
|
||||
);
|
||||
await repo.writeFile(".cursor/rules/truthmark.mdc", "# Ignore me\n");
|
||||
await repo.writeFile(
|
||||
".claude/skills/truthmark-sync/SKILL.md",
|
||||
"# Ignore me\n",
|
||||
);
|
||||
await repo.writeFile(".github/copilot-instructions.md", "# Ignore me\n");
|
||||
await repo.writeFile(
|
||||
".github/prompts/truthmark-sync.prompt.md",
|
||||
"# Ignore me\n",
|
||||
);
|
||||
await repo.writeFile("CLAUDE.md", "# Ignore me\n");
|
||||
await repo.writeFile("GEMINI.md", "# Ignore me\n");
|
||||
await repo.writeFile(
|
||||
@@ -100,7 +107,13 @@ describe("init templates", () => {
|
||||
|
||||
expect(config).toMatchObject({
|
||||
version: 1,
|
||||
platforms: ["codex", "opencode", "claude-code"],
|
||||
platforms: [
|
||||
"codex",
|
||||
"opencode",
|
||||
"claude-code",
|
||||
"github-copilot",
|
||||
"gemini-cli",
|
||||
],
|
||||
authority: expect.any(Array),
|
||||
instruction_targets: expect.any(Array),
|
||||
frontmatter: expect.any(Object),
|
||||
@@ -114,7 +127,7 @@ describe("init templates", () => {
|
||||
expect(config.docs.roots).not.toHaveProperty("specs_draft");
|
||||
});
|
||||
|
||||
it("renders TRUTHMARK.md with branch-local truth, automatic sync, and manual realize guidance", () => {
|
||||
it("renders TRUTHMARK.md as a compact branch-local truth contract", () => {
|
||||
const truthmark = renderTruthmarkTemplate();
|
||||
|
||||
expect(truthmark).toContain(
|
||||
@@ -125,11 +138,14 @@ describe("init templates", () => {
|
||||
);
|
||||
expect(truthmark).toContain("rerun `truthmark init`");
|
||||
expect(truthmark).toContain(
|
||||
"Truth Sync runs automatically before finishing when functional code changes exist",
|
||||
"Workflow runtime lives in installed skills and managed instruction blocks.",
|
||||
);
|
||||
expect(truthmark).toContain(
|
||||
"Truth Realize is manual and updates code to match truth docs.",
|
||||
"Truth Sync follows code; Truth Realize follows docs.",
|
||||
);
|
||||
expect(truthmark.split("\n").length).toBeLessThanOrEqual(18);
|
||||
expect(truthmark).not.toContain("Truth Structure");
|
||||
expect(truthmark).not.toContain("Truth Check");
|
||||
});
|
||||
|
||||
it("seeds docs/truthmark/areas.md from discovered docs without moving them", () => {
|
||||
@@ -158,11 +174,19 @@ describe("init templates", () => {
|
||||
|
||||
expect(agentsBlock).toContain("<!-- truthmark:start -->");
|
||||
expect(agentsBlock).toContain("<!-- truthmark:end -->");
|
||||
expect(agentsBlock).toContain("### Manual Truth Realize");
|
||||
expect(agentsBlock).toContain("May write truth docs");
|
||||
expect(agentsBlock.split("\n").length).toBeLessThanOrEqual(25);
|
||||
expect(agentsBlock).not.toContain("### Manual Truth Realize");
|
||||
expect(agentsBlock).not.toContain("### Truth Structure");
|
||||
expect(agentsBlock).not.toContain("### Truth Check");
|
||||
expect(agentsBlock).toContain(
|
||||
"Explicit workflows: Truth Structure, Truth Realize, Truth Check",
|
||||
);
|
||||
expect(agentsBlock).toContain(
|
||||
"may write truth docs and docs/truthmark/areas.md only",
|
||||
);
|
||||
expect(agentsBlock).toContain("must not rewrite functional code");
|
||||
expect(agentsBlock).toContain("write functional code only");
|
||||
expect(agentsBlock).toContain("do not edit truth docs or truth routing");
|
||||
expect(agentsBlock).not.toContain("write functional code only");
|
||||
expect(agentsBlock).not.toContain("do not edit truth docs or truth routing");
|
||||
});
|
||||
|
||||
it("renders default standards only when comparable standards are missing", () => {
|
||||
|
||||
Reference in New Issue
Block a user