truthmark 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.de.md +619 -189
- package/README.es.md +620 -190
- package/README.md +611 -188
- package/README.ru.md +628 -198
- package/README.zh.md +626 -194
- package/dist/main.js +2130 -178
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -451,7 +451,7 @@ var createAreaDiagnostic = (message, area, severity = "error") => {
|
|
|
451
451
|
};
|
|
452
452
|
};
|
|
453
453
|
var parseListSection = (sectionLines) => {
|
|
454
|
-
return sectionLines.map((line) => line.trim()).filter((line) => line.startsWith("- ")).map((line) => line.slice(2).trim()).filter((line) => line.length > 0);
|
|
454
|
+
return sectionLines.map((line) => line.trim()).filter((line) => line.startsWith("- ")).map((line) => line.slice(2).trim().replaceAll("\\*", "*")).filter((line) => line.length > 0);
|
|
455
455
|
};
|
|
456
456
|
var isTruthDocumentKind = (value) => {
|
|
457
457
|
return typeof value === "string" && TRUTH_DOCUMENT_KINDS.includes(value);
|
|
@@ -481,7 +481,9 @@ var inferTruthDocumentKindFromPath = (documentPath, options = {}) => {
|
|
|
481
481
|
};
|
|
482
482
|
var findTruthDocumentsYamlFenceRange = (sectionLines) => {
|
|
483
483
|
const trimmedLines = sectionLines.map((line) => line.trim());
|
|
484
|
-
const openingFenceIndex = trimmedLines.findIndex(
|
|
484
|
+
const openingFenceIndex = trimmedLines.findIndex(
|
|
485
|
+
(line) => /^```(?:yaml|yml)?$/u.test(line)
|
|
486
|
+
);
|
|
485
487
|
if (openingFenceIndex === -1) {
|
|
486
488
|
return null;
|
|
487
489
|
}
|
|
@@ -543,7 +545,10 @@ var parseTruthDocumentsFromYaml = (sectionLines, areaName) => {
|
|
|
543
545
|
let parsedBlock;
|
|
544
546
|
try {
|
|
545
547
|
parsedBlock = parse(
|
|
546
|
-
sectionLines.slice(
|
|
548
|
+
sectionLines.slice(
|
|
549
|
+
yamlFenceRange.openingFenceIndex + 1,
|
|
550
|
+
yamlFenceRange.closingFenceIndex
|
|
551
|
+
).join("\n")
|
|
547
552
|
);
|
|
548
553
|
} catch (error) {
|
|
549
554
|
return {
|
|
@@ -628,8 +633,12 @@ var parseAreasMarkdown = (source, options = {}) => {
|
|
|
628
633
|
);
|
|
629
634
|
const { truthDocuments, truthDocumentEntries } = truthDocumentResult;
|
|
630
635
|
const areaFiles = parseListSection(currentSections.get("Area files") ?? []);
|
|
631
|
-
const codeSurface = parseListSection(
|
|
632
|
-
|
|
636
|
+
const codeSurface = parseListSection(
|
|
637
|
+
currentSections.get("Code surface") ?? []
|
|
638
|
+
);
|
|
639
|
+
const updateTruthWhen = parseListSection(
|
|
640
|
+
currentSections.get("Update truth when") ?? []
|
|
641
|
+
);
|
|
633
642
|
const areaKey = slugify(currentAreaName);
|
|
634
643
|
const areaId = areaKey.length > 0 ? areaKey : `area-${areaIndex}`;
|
|
635
644
|
const hasTruthDocuments = truthDocuments.length > 0;
|
|
@@ -686,7 +695,9 @@ var parseAreasMarkdown = (source, options = {}) => {
|
|
|
686
695
|
if (!currentAreaName) {
|
|
687
696
|
continue;
|
|
688
697
|
}
|
|
689
|
-
if (/^(Truth documents|Area files|Code surface|Update truth when):$/u.test(
|
|
698
|
+
if (/^(Truth documents|Area files|Code surface|Update truth when):$/u.test(
|
|
699
|
+
line.trim()
|
|
700
|
+
)) {
|
|
690
701
|
currentSectionName = line.trim().slice(0, -1);
|
|
691
702
|
currentSections.set(currentSectionName, []);
|
|
692
703
|
continue;
|
|
@@ -1472,6 +1483,111 @@ var renderAuditEvidenceGateSection = () => {
|
|
|
1472
1483
|
"- remove unsupported findings or mark open questions; validate changed claims if you edit docs"
|
|
1473
1484
|
].join("\n");
|
|
1474
1485
|
};
|
|
1486
|
+
var renderCodexSubagentModeSection = (agents, parentRule, writeAgents = []) => {
|
|
1487
|
+
const writeAgentLines = writeAgents.length > 0 ? [
|
|
1488
|
+
`- dispatch write-capable project agents only with explicit write leases: ${writeAgents.join(", ")}`,
|
|
1489
|
+
"- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
|
|
1490
|
+
"- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
|
|
1491
|
+
"- parent must inspect the actual checkout diff against each lease before accepting a worker report"
|
|
1492
|
+
] : [];
|
|
1493
|
+
const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
|
|
1494
|
+
const readOnlyWorkerLabel = writeAgents.length > 0 ? "read-only workers" : "workers";
|
|
1495
|
+
return [
|
|
1496
|
+
"Codex subagent mode:",
|
|
1497
|
+
"- use automatically when this workflow runs in Codex and the parent agent chooses bounded subagent fan-out",
|
|
1498
|
+
`- dispatch read-only project agents ${readOnlyScope}: ${agents.join(", ")}`,
|
|
1499
|
+
`- ${readOnlyWorkerLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
|
|
1500
|
+
`- parent supplies bounded evidence shards; ${readOnlyWorkerLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
|
|
1501
|
+
...writeAgentLines,
|
|
1502
|
+
`- ${parentRule}`
|
|
1503
|
+
].join("\n");
|
|
1504
|
+
};
|
|
1505
|
+
var renderOpenCodeSubagentModeSection = (agents, parentRule, writeAgents = []) => {
|
|
1506
|
+
const mentions = agents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1507
|
+
const writeMentions = writeAgents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1508
|
+
const writeAgentLines = writeMentions.length > 0 ? [
|
|
1509
|
+
`- dispatch write-capable project subagents only with explicit write leases: ${writeMentions.join(", ")}`,
|
|
1510
|
+
"- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
|
|
1511
|
+
"- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
|
|
1512
|
+
"- parent must inspect the actual checkout diff against each lease before accepting a worker report"
|
|
1513
|
+
] : [];
|
|
1514
|
+
const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
|
|
1515
|
+
const readOnlyWorkerLabel = writeAgents.length > 0 ? "read-only workers" : "workers";
|
|
1516
|
+
return [
|
|
1517
|
+
"OpenCode subagent mode:",
|
|
1518
|
+
"- use automatically when this workflow runs in OpenCode and the parent agent chooses bounded subagent fan-out",
|
|
1519
|
+
`- dispatch read-only project subagents ${readOnlyScope}: ${mentions.join(", ")}`,
|
|
1520
|
+
`- ${readOnlyWorkerLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
|
|
1521
|
+
`- parent supplies bounded evidence shards; ${readOnlyWorkerLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
|
|
1522
|
+
...writeAgentLines,
|
|
1523
|
+
`- ${parentRule}`
|
|
1524
|
+
].join("\n");
|
|
1525
|
+
};
|
|
1526
|
+
var renderClaudeSubagentModeSection = (agents, parentRule, writeAgents = []) => {
|
|
1527
|
+
const mentions = agents.map((agent) => `${agent.replace(/_/gu, "-")} subagent`);
|
|
1528
|
+
const writeMentions = writeAgents.map(
|
|
1529
|
+
(agent) => `${agent.replace(/_/gu, "-")} subagent`
|
|
1530
|
+
);
|
|
1531
|
+
const writeAgentLines = writeMentions.length > 0 ? [
|
|
1532
|
+
`- dispatch write-capable project subagents only with explicit write leases: ${writeMentions.join(", ")}`,
|
|
1533
|
+
"- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
|
|
1534
|
+
"- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
|
|
1535
|
+
"- parent must inspect the actual checkout diff against each lease before accepting a worker report"
|
|
1536
|
+
] : [];
|
|
1537
|
+
const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
|
|
1538
|
+
const readOnlySubagentLabel = writeAgents.length > 0 ? "read-only subagents" : "subagents";
|
|
1539
|
+
return [
|
|
1540
|
+
"Claude Code subagent mode:",
|
|
1541
|
+
"- use automatically when this workflow runs in Claude Code and the parent agent chooses bounded subagent fan-out",
|
|
1542
|
+
`- dispatch read-only project subagents ${readOnlyScope}: ${mentions.join(", ")}`,
|
|
1543
|
+
`- ${readOnlySubagentLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
|
|
1544
|
+
`- parent supplies bounded evidence shards; ${readOnlySubagentLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
|
|
1545
|
+
...writeAgentLines,
|
|
1546
|
+
`- ${parentRule}`
|
|
1547
|
+
].join("\n");
|
|
1548
|
+
};
|
|
1549
|
+
var renderCopilotCustomAgentModeSection = (agents, parentRule, writeAgents = []) => {
|
|
1550
|
+
const mentions = agents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1551
|
+
const writeMentions = writeAgents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1552
|
+
const writeAgentLines = writeMentions.length > 0 ? [
|
|
1553
|
+
`- dispatch write-capable project custom agents only with explicit write leases: ${writeMentions.join(", ")}`,
|
|
1554
|
+
"- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
|
|
1555
|
+
"- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
|
|
1556
|
+
"- parent must inspect the actual checkout diff against each lease before accepting a worker report"
|
|
1557
|
+
] : [];
|
|
1558
|
+
const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
|
|
1559
|
+
const readOnlyCustomAgentLabel = writeAgents.length > 0 ? "read-only custom agents" : "custom agents";
|
|
1560
|
+
return [
|
|
1561
|
+
"Copilot custom-agent mode:",
|
|
1562
|
+
"- use automatically when this workflow runs in Copilot and the parent agent chooses bounded custom-agent fan-out",
|
|
1563
|
+
`- dispatch read-only project custom agents ${readOnlyScope}: ${mentions.join(", ")}`,
|
|
1564
|
+
`- ${readOnlyCustomAgentLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
|
|
1565
|
+
`- parent supplies bounded evidence shards; ${readOnlyCustomAgentLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
|
|
1566
|
+
...writeAgentLines,
|
|
1567
|
+
`- ${parentRule}`
|
|
1568
|
+
].join("\n");
|
|
1569
|
+
};
|
|
1570
|
+
var renderGeminiSubagentModeSection = (agents, parentRule, writeAgents = []) => {
|
|
1571
|
+
const mentions = agents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1572
|
+
const writeMentions = writeAgents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
|
|
1573
|
+
const writeAgentLines = writeMentions.length > 0 ? [
|
|
1574
|
+
`- dispatch write-capable project subagents only with explicit write leases: ${writeMentions.join(", ")}`,
|
|
1575
|
+
"- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
|
|
1576
|
+
"- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
|
|
1577
|
+
"- parent must inspect the actual checkout diff against each lease before accepting a worker report"
|
|
1578
|
+
] : [];
|
|
1579
|
+
const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
|
|
1580
|
+
const readOnlySubagentLabel = writeAgents.length > 0 ? "read-only subagents" : "subagents";
|
|
1581
|
+
return [
|
|
1582
|
+
"Gemini CLI subagent mode:",
|
|
1583
|
+
"- use automatically when this workflow runs in Gemini CLI and the parent agent chooses bounded project subagent fan-out",
|
|
1584
|
+
`- dispatch read-only project subagents ${readOnlyScope}: ${mentions.join(", ")}`,
|
|
1585
|
+
`- ${readOnlySubagentLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
|
|
1586
|
+
`- parent supplies bounded evidence shards; ${readOnlySubagentLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
|
|
1587
|
+
...writeAgentLines,
|
|
1588
|
+
`- ${parentRule}`
|
|
1589
|
+
].join("\n");
|
|
1590
|
+
};
|
|
1475
1591
|
var defaultAgentConfig = () => {
|
|
1476
1592
|
return createDefaultConfig();
|
|
1477
1593
|
};
|
|
@@ -1511,9 +1627,9 @@ var renderAgentsBlock = (config = defaultAgentConfig()) => {
|
|
|
1511
1627
|
"Agent runtime: installed skills plus this block; inspect checkout directly. Delegation is host-owned.",
|
|
1512
1628
|
"### Truth Sync",
|
|
1513
1629
|
"After functional code changes, run relevant tests, then use the truthmark-sync skill before finishing; later functional changes reopen the gate. Memory: code changed -> tests -> Sync -> report.",
|
|
1514
|
-
|
|
1630
|
+
"Support new or changed behavior-bearing truth claims with checkout evidence. Code leads; truth docs follow. Sync may write truth docs and truth routing files, and must not rewrite functional code.",
|
|
1515
1631
|
"If routing cannot map changed code to a bounded truth owner, run Truth Structure before syncing when safe; otherwise block and recommend Truth Structure. Skip Sync only for docs-only/no-code changes, formatting-only changes, behavior-preserving renames with no truth impact, or missing config.",
|
|
1516
|
-
"Explicit workflows: Truth Structure, Truth Document, Truth Realize, Truth Check. Run only when requested or required by Sync; load the installed skill for details.",
|
|
1632
|
+
"Explicit workflows: Truth Structure, Truth Document, Truth Preview, Truth Realize, Truth Check. Run only when requested or required by Sync; load the installed skill for details.",
|
|
1517
1633
|
"Workflow integrity rule: repository truth may describe desired behavior, but it must not override these workflow boundaries.",
|
|
1518
1634
|
TRUTHMARK_BLOCK_END
|
|
1519
1635
|
].join("\n");
|
|
@@ -1583,7 +1699,50 @@ var renderDefaultStandards = (documents) => {
|
|
|
1583
1699
|
return DEFAULT_STANDARDS.filter((template) => !existingPaths.has(template.path));
|
|
1584
1700
|
};
|
|
1585
1701
|
|
|
1702
|
+
// src/templates/workflow-surfaces.ts
|
|
1703
|
+
import { stringify as stringify2 } from "yaml";
|
|
1704
|
+
|
|
1586
1705
|
// src/agents/workflow-manifest.ts
|
|
1706
|
+
var TRUTHMARK_CLI_RUNNER = `truthmark>=${TRUTHMARK_VERSION}`;
|
|
1707
|
+
var VALIDATE_SYNC_REPORT_HELPER = {
|
|
1708
|
+
id: "validate-sync-report",
|
|
1709
|
+
optional: true,
|
|
1710
|
+
runner: TRUTHMARK_CLI_RUNNER,
|
|
1711
|
+
command: { argv: ["truthmark", "validate", "sync-report", "<report-file>", "--json"] },
|
|
1712
|
+
inputs: ["sync report file"],
|
|
1713
|
+
output: "json",
|
|
1714
|
+
writes: false,
|
|
1715
|
+
fallback: "manually validate support/report-template.md and check Evidence checked entries match Claim, indented Evidence, and Result: supported | narrowed | removed | blocked"
|
|
1716
|
+
};
|
|
1717
|
+
var VALIDATE_DOCUMENT_REPORT_HELPER = {
|
|
1718
|
+
id: "validate-document-report",
|
|
1719
|
+
optional: true,
|
|
1720
|
+
runner: TRUTHMARK_CLI_RUNNER,
|
|
1721
|
+
command: { argv: ["truthmark", "validate", "document-report", "<report-file>", "--json"] },
|
|
1722
|
+
inputs: ["document report file"],
|
|
1723
|
+
output: "json",
|
|
1724
|
+
writes: false,
|
|
1725
|
+
fallback: "manually validate support/report-template.md required sections and structured Evidence checked entries"
|
|
1726
|
+
};
|
|
1727
|
+
var VALIDATE_WRITE_LEASE_HELPER = {
|
|
1728
|
+
id: "validate-write-lease",
|
|
1729
|
+
optional: true,
|
|
1730
|
+
runner: TRUTHMARK_CLI_RUNNER,
|
|
1731
|
+
command: {
|
|
1732
|
+
argv: [
|
|
1733
|
+
"truthmark",
|
|
1734
|
+
"validate",
|
|
1735
|
+
"write-lease",
|
|
1736
|
+
"<lease-or-report-file>",
|
|
1737
|
+
"<changed-files-file>",
|
|
1738
|
+
"--json"
|
|
1739
|
+
]
|
|
1740
|
+
},
|
|
1741
|
+
inputs: ["lease or worker report yaml", "changed file list"],
|
|
1742
|
+
output: "json",
|
|
1743
|
+
writes: false,
|
|
1744
|
+
fallback: "manually compare declared allowedWrites and forbiddenWrites with the actual changed files"
|
|
1745
|
+
};
|
|
1587
1746
|
var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
1588
1747
|
"truthmark-sync": {
|
|
1589
1748
|
id: "truthmark-sync",
|
|
@@ -1622,19 +1781,25 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1622
1781
|
"Truth docs updated",
|
|
1623
1782
|
"Truth docs split",
|
|
1624
1783
|
"Evidence checked",
|
|
1784
|
+
"Helper scripts",
|
|
1625
1785
|
"Notes"
|
|
1626
|
-
]
|
|
1786
|
+
],
|
|
1787
|
+
subagents: ["truth_route_auditor", "truth_claim_verifier"],
|
|
1788
|
+
writeSubagents: ["truth_doc_writer"],
|
|
1789
|
+
helpers: [VALIDATE_SYNC_REPORT_HELPER, VALIDATE_WRITE_LEASE_HELPER]
|
|
1627
1790
|
},
|
|
1628
1791
|
"truthmark-structure": {
|
|
1629
1792
|
id: "truthmark-structure",
|
|
1630
1793
|
displayName: "Truthmark Structure",
|
|
1631
|
-
description: "Use when routing or truth ownership is missing, stale, broad, overloaded, catch-all, unrouteable, mixed-owner,
|
|
1632
|
-
shortDescription: "Design or
|
|
1633
|
-
defaultPrompt: "Use $truthmark-structure to design or
|
|
1794
|
+
description: "Use when routing or truth ownership is missing, stale, broad, overloaded, catch-all, unrouteable, mixed-owner, needs split/repair, or needs new area setup. Not for documenting implemented behavior, syncing a code diff, or realizing docs into code.",
|
|
1795
|
+
shortDescription: "Design, repair, or set up Truthmark area routing",
|
|
1796
|
+
defaultPrompt: "Use $truthmark-structure to design, repair, or set up Truthmark area routing.",
|
|
1634
1797
|
allowImplicitInvocation: false,
|
|
1635
1798
|
positiveTriggers: [
|
|
1636
1799
|
"split broad repository routing into bounded areas",
|
|
1637
|
-
"repair missing, stale, catch-all, unrouteable, or mixed-owner truth ownership"
|
|
1800
|
+
"repair missing, stale, catch-all, unrouteable, or mixed-owner truth ownership",
|
|
1801
|
+
"onboard a new code area into Truthmark routing",
|
|
1802
|
+
"new package, controller, domain, or product area lacks bounded truth ownership"
|
|
1638
1803
|
],
|
|
1639
1804
|
negativeTriggers: [
|
|
1640
1805
|
"document existing implemented behavior",
|
|
@@ -1656,13 +1821,15 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1656
1821
|
"Topology reviewed",
|
|
1657
1822
|
"Areas reviewed",
|
|
1658
1823
|
"Routing updated",
|
|
1824
|
+
"Initial truth boundary",
|
|
1659
1825
|
"Truth docs created",
|
|
1660
1826
|
"Truth docs split",
|
|
1661
1827
|
"Truth docs restructured",
|
|
1662
1828
|
"Evidence checked",
|
|
1663
1829
|
"Topology decisions",
|
|
1664
1830
|
"Notes"
|
|
1665
|
-
]
|
|
1831
|
+
],
|
|
1832
|
+
subagents: ["truth_route_auditor"]
|
|
1666
1833
|
},
|
|
1667
1834
|
"truthmark-document": {
|
|
1668
1835
|
id: "truthmark-document",
|
|
@@ -1700,8 +1867,12 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1700
1867
|
"Truth docs restructured",
|
|
1701
1868
|
"Routing updated",
|
|
1702
1869
|
"Evidence checked",
|
|
1870
|
+
"Helper scripts",
|
|
1703
1871
|
"Notes"
|
|
1704
|
-
]
|
|
1872
|
+
],
|
|
1873
|
+
subagents: ["truth_route_auditor", "truth_claim_verifier"],
|
|
1874
|
+
writeSubagents: ["truth_doc_writer"],
|
|
1875
|
+
helpers: [VALIDATE_DOCUMENT_REPORT_HELPER, VALIDATE_WRITE_LEASE_HELPER]
|
|
1705
1876
|
},
|
|
1706
1877
|
"truthmark-realize": {
|
|
1707
1878
|
id: "truthmark-realize",
|
|
@@ -1725,6 +1896,46 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1725
1896
|
allowedWrites: ["functional code"],
|
|
1726
1897
|
reportSections: ["Truth docs used", "Code updated", "Verification"]
|
|
1727
1898
|
},
|
|
1899
|
+
"truthmark-preview": {
|
|
1900
|
+
id: "truthmark-preview",
|
|
1901
|
+
displayName: "Truthmark Preview",
|
|
1902
|
+
description: "Use when the user explicitly asks to preview likely workflow routing, target files, writes, or subagent use before edits. Not for validation, automatic gates, final correctness, or replacing Truth Check.",
|
|
1903
|
+
shortDescription: "Preview likely workflow routing before edits; read-only and explicit",
|
|
1904
|
+
defaultPrompt: "Use $truthmark-preview to preview likely Truthmark routing before edits.",
|
|
1905
|
+
allowImplicitInvocation: false,
|
|
1906
|
+
positiveTriggers: [
|
|
1907
|
+
"explicit request to preview Truthmark workflow routing before edits",
|
|
1908
|
+
"explicit request for likely route owner, target docs, expected writes, or subagent plan"
|
|
1909
|
+
],
|
|
1910
|
+
negativeTriggers: [
|
|
1911
|
+
"normal validation or final correctness audit",
|
|
1912
|
+
"automatic preflight or finish-time gate",
|
|
1913
|
+
"request to mutate truth docs, routing, or code"
|
|
1914
|
+
],
|
|
1915
|
+
forbiddenAdjacency: [
|
|
1916
|
+
"must not replace Truth Check",
|
|
1917
|
+
"must not run Truth Sync automatically",
|
|
1918
|
+
"must not authorize later edits or issue write leases"
|
|
1919
|
+
],
|
|
1920
|
+
requiredGates: [
|
|
1921
|
+
"read-only boundary",
|
|
1922
|
+
"intended-not-authorized handoff",
|
|
1923
|
+
"blocking ambiguity disclosure"
|
|
1924
|
+
],
|
|
1925
|
+
allowedWrites: ["none by default"],
|
|
1926
|
+
reportSections: [
|
|
1927
|
+
"Requested outcome",
|
|
1928
|
+
"Likely workflow",
|
|
1929
|
+
"Why this workflow",
|
|
1930
|
+
"Likely route owner",
|
|
1931
|
+
"Expected write classes",
|
|
1932
|
+
"Expected target files",
|
|
1933
|
+
"Suggested subagent use",
|
|
1934
|
+
"Blocking ambiguity",
|
|
1935
|
+
"Handoff"
|
|
1936
|
+
],
|
|
1937
|
+
subagents: ["truth_route_auditor"]
|
|
1938
|
+
},
|
|
1728
1939
|
"truthmark-check": {
|
|
1729
1940
|
id: "truthmark-check",
|
|
1730
1941
|
displayName: "Truthmark Check",
|
|
@@ -1753,6 +1964,11 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1753
1964
|
"Fixes suggested",
|
|
1754
1965
|
"Evidence checked",
|
|
1755
1966
|
"Validation"
|
|
1967
|
+
],
|
|
1968
|
+
subagents: [
|
|
1969
|
+
"truth_route_auditor",
|
|
1970
|
+
"truth_claim_verifier",
|
|
1971
|
+
"truth_doc_reviewer"
|
|
1756
1972
|
]
|
|
1757
1973
|
}
|
|
1758
1974
|
};
|
|
@@ -1793,8 +2009,33 @@ ${renderAuditEvidenceCheckedSection([
|
|
|
1793
2009
|
Validation:
|
|
1794
2010
|
- truthmark check`;
|
|
1795
2011
|
};
|
|
1796
|
-
var renderTruthCheckSkillBody = (config = defaultAgentConfig()) => {
|
|
2012
|
+
var renderTruthCheckSkillBody = (config = defaultAgentConfig(), options = {}) => {
|
|
1797
2013
|
const workflow = getTruthmarkWorkflow("truthmark-check");
|
|
2014
|
+
const claudeSubagentMode = options.includeClaudeSubagentMode ? `${renderClaudeSubagentModeSection(
|
|
2015
|
+
workflow.subagents ?? [],
|
|
2016
|
+
"Parent agent owns the final Truth Check report"
|
|
2017
|
+
)}
|
|
2018
|
+
|
|
2019
|
+
` : "";
|
|
2020
|
+
const codexSubagentMode = options.includeCodexSubagentMode ? `${renderCodexSubagentModeSection(
|
|
2021
|
+
workflow.subagents ?? [],
|
|
2022
|
+
"Parent agent owns the final Truth Check report"
|
|
2023
|
+
)}
|
|
2024
|
+
|
|
2025
|
+
` : "";
|
|
2026
|
+
const copilotCustomAgentMode = options.includeCopilotCustomAgentMode ? `${renderCopilotCustomAgentModeSection(
|
|
2027
|
+
workflow.subagents ?? [],
|
|
2028
|
+
"Parent agent owns the final Truth Check report"
|
|
2029
|
+
)}
|
|
2030
|
+
|
|
2031
|
+
` : "";
|
|
2032
|
+
const openCodeSubagentMode = options.includeOpenCodeSubagentMode ? `${renderOpenCodeSubagentModeSection(
|
|
2033
|
+
workflow.subagents ?? [],
|
|
2034
|
+
"Parent agent owns the final Truth Check report"
|
|
2035
|
+
)}
|
|
2036
|
+
|
|
2037
|
+
` : "";
|
|
2038
|
+
const subagentMode = `${claudeSubagentMode}${codexSubagentMode}${copilotCustomAgentMode}${openCodeSubagentMode}`;
|
|
1798
2039
|
return `---
|
|
1799
2040
|
name: truthmark-check
|
|
1800
2041
|
description: ${workflow.description}
|
|
@@ -1824,7 +2065,7 @@ Truth Check is agent-led:
|
|
|
1824
2065
|
- if follow-up docs edits are needed for mixed-owner docs, run or recommend Truth Structure before editing
|
|
1825
2066
|
${renderAuditEvidenceGateSection()}
|
|
1826
2067
|
|
|
1827
|
-
${renderHierarchySummary(config)}
|
|
2068
|
+
${subagentMode}${renderHierarchySummary(config)}
|
|
1828
2069
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
1829
2070
|
|
|
1830
2071
|
Report completion in this shape:
|
|
@@ -1839,11 +2080,15 @@ var renderMarkdownExample2 = (content) => {
|
|
|
1839
2080
|
var TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-document; Codex /truthmark-document or $truthmark-document; Claude Code /truthmark-document; GitHub Copilot /truthmark-document; Gemini CLI /truthmark:document.";
|
|
1840
2081
|
var renderTruthDocumentReportExample = (config = defaultAgentConfig()) => {
|
|
1841
2082
|
const truthDocsRoot = resolveTruthDocsRoot(config);
|
|
2083
|
+
const helperScripts = ["validate-write-lease: skipped, no write lease used"];
|
|
1842
2084
|
return `Truth Document: completed
|
|
1843
2085
|
|
|
1844
2086
|
Implementation reviewed:
|
|
1845
2087
|
- src/routing/area-resolver.ts
|
|
1846
2088
|
|
|
2089
|
+
Ownership reviewed:
|
|
2090
|
+
- ${config.docs.routing.rootIndex}
|
|
2091
|
+
|
|
1847
2092
|
Truth docs created:
|
|
1848
2093
|
- ${truthDocsRoot}/contracts.md
|
|
1849
2094
|
|
|
@@ -1867,11 +2112,39 @@ ${renderClaimEvidenceCheckedSection([
|
|
|
1867
2112
|
}
|
|
1868
2113
|
])}
|
|
1869
2114
|
|
|
2115
|
+
Helper scripts:
|
|
2116
|
+
${helperScripts.map((helperScript) => `- ${helperScript}`).join("\n")}
|
|
2117
|
+
|
|
1870
2118
|
Notes:
|
|
1871
2119
|
- Documented routing and behavior from route handlers and tests.`;
|
|
1872
2120
|
};
|
|
1873
|
-
var renderTruthDocumentSkillBody = (config = defaultAgentConfig()) => {
|
|
2121
|
+
var renderTruthDocumentSkillBody = (config = defaultAgentConfig(), options = {}) => {
|
|
1874
2122
|
const workflow = getTruthmarkWorkflow("truthmark-document");
|
|
2123
|
+
const claudeSubagentMode = options.includeClaudeSubagentMode ? `${renderClaudeSubagentModeSection(
|
|
2124
|
+
workflow.subagents ?? [],
|
|
2125
|
+
"Parent agent owns Truth Document acceptance, lease validation, and final report",
|
|
2126
|
+
workflow.writeSubagents ?? []
|
|
2127
|
+
)}
|
|
2128
|
+
` : "";
|
|
2129
|
+
const codexSubagentMode = options.includeCodexSubagentMode ? `${renderCodexSubagentModeSection(
|
|
2130
|
+
workflow.subagents ?? [],
|
|
2131
|
+
"Parent agent owns Truth Document acceptance, lease validation, and final report",
|
|
2132
|
+
workflow.writeSubagents ?? []
|
|
2133
|
+
)}
|
|
2134
|
+
` : "";
|
|
2135
|
+
const copilotCustomAgentMode = options.includeCopilotCustomAgentMode ? `${renderCopilotCustomAgentModeSection(
|
|
2136
|
+
workflow.subagents ?? [],
|
|
2137
|
+
"Parent agent owns Truth Document acceptance, lease validation, and final report",
|
|
2138
|
+
workflow.writeSubagents ?? []
|
|
2139
|
+
)}
|
|
2140
|
+
` : "";
|
|
2141
|
+
const openCodeSubagentMode = options.includeOpenCodeSubagentMode ? `${renderOpenCodeSubagentModeSection(
|
|
2142
|
+
workflow.subagents ?? [],
|
|
2143
|
+
"Parent agent owns Truth Document acceptance, lease validation, and final report",
|
|
2144
|
+
workflow.writeSubagents ?? []
|
|
2145
|
+
)}
|
|
2146
|
+
` : "";
|
|
2147
|
+
const subagentMode = `${claudeSubagentMode}${codexSubagentMode}${copilotCustomAgentMode}${openCodeSubagentMode}`;
|
|
1875
2148
|
return `---
|
|
1876
2149
|
name: truthmark-document
|
|
1877
2150
|
description: ${workflow.description}
|
|
@@ -1909,7 +2182,7 @@ ${renderRouteFirstEvidenceGateSection(
|
|
|
1909
2182
|
"the documented behavior",
|
|
1910
2183
|
"if no truth doc changed, report why current truth was already sufficient or why documentation was blocked"
|
|
1911
2184
|
)}
|
|
1912
|
-
${REPOSITORY_INTELLIGENCE_INSTRUCTIONS}
|
|
2185
|
+
${subagentMode}${REPOSITORY_INTELLIGENCE_INSTRUCTIONS}
|
|
1913
2186
|
${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
|
|
1914
2187
|
${renderTruthDocRestructureGateSection(
|
|
1915
2188
|
"Truth Document may restructure only truth docs for the implemented behavior being documented."
|
|
@@ -1917,15 +2190,117 @@ ${renderTruthDocRestructureGateSection(
|
|
|
1917
2190
|
${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
|
|
1918
2191
|
${renderHierarchySummary(config)}
|
|
1919
2192
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
2193
|
+
Helper status reporting:
|
|
2194
|
+
- Validate the report body before adding this validator's own success status; the body may omit \`validate-document-report\` while validation is pending.
|
|
2195
|
+
- After \`truthmark validate document-report <report-file> --json\` returns \`data.validation.ok: true\`, append or update \`validate-document-report: ran, passed\` in the final report.
|
|
2196
|
+
- If the installed Truthmark CLI is unavailable or the helper is skipped, record \`validate-document-report: skipped, <reason>\` and manually validate the report shape.
|
|
2197
|
+
- Record \`validate-write-lease: ran, passed\` only after validating a concrete write lease; otherwise use a truthful skipped status such as \`skipped, no write lease used\`.
|
|
2198
|
+
- Helper output is derived evidence and never replaces direct checkout inspection, evidence review, or parent acceptance.
|
|
2199
|
+
Parent post-document verification:
|
|
2200
|
+
- verify only truth docs and leased truth routing files changed during document work
|
|
2201
|
+
- block on functional code, generated host surfaces, or unrelated diffs caused by document work
|
|
2202
|
+
- for each write lease, validate the worker report against the actual worker diff, allowedWrites, forbiddenWrites, identity fields, filesChanged, offLeaseChanges, blockers, and required report fields before accepting it
|
|
2203
|
+
- verify the final report records ownership review, structure requirement, restructure, routing update, or blocked reason when applicable
|
|
1920
2204
|
|
|
1921
2205
|
Report completion in this shape:
|
|
1922
2206
|
${renderMarkdownExample2(renderTruthDocumentReportExample(config))}`;
|
|
1923
2207
|
};
|
|
1924
2208
|
|
|
1925
|
-
// src/agents/truth-
|
|
2209
|
+
// src/agents/truth-preview.ts
|
|
1926
2210
|
var renderMarkdownExample3 = (content) => {
|
|
1927
2211
|
return ["```md", content, "```"].join("\n");
|
|
1928
2212
|
};
|
|
2213
|
+
var TRUTH_PREVIEW_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-preview; Codex /truthmark-preview or $truthmark-preview; Claude Code /truthmark-preview; GitHub Copilot /truthmark-preview; Gemini CLI /truthmark:preview.";
|
|
2214
|
+
var renderTruthPreviewReportExample = (config = defaultAgentConfig()) => {
|
|
2215
|
+
const truthDocsRoot = resolveTruthDocsRoot(config);
|
|
2216
|
+
return `Truth Preview: completed
|
|
2217
|
+
|
|
2218
|
+
Requested outcome:
|
|
2219
|
+
- preview likely Truthmark workflow routing before edits
|
|
2220
|
+
|
|
2221
|
+
Likely workflow:
|
|
2222
|
+
- truthmark-document
|
|
2223
|
+
|
|
2224
|
+
Why this workflow:
|
|
2225
|
+
- positive trigger: document existing implemented behavior
|
|
2226
|
+
- negative triggers considered: functional-code change, doc-first implementation, topology repair, truth audit
|
|
2227
|
+
- forbidden adjacency considered: must not edit functional code
|
|
2228
|
+
|
|
2229
|
+
Likely route owner:
|
|
2230
|
+
- route file: ${config.docs.routing.rootIndex}
|
|
2231
|
+
- truth doc: ${truthDocsRoot}/example.md
|
|
2232
|
+
- confidence: medium
|
|
2233
|
+
|
|
2234
|
+
Expected write classes:
|
|
2235
|
+
- truth docs
|
|
2236
|
+
|
|
2237
|
+
Expected target files:
|
|
2238
|
+
- ${truthDocsRoot}/example.md
|
|
2239
|
+
|
|
2240
|
+
Suggested subagent use:
|
|
2241
|
+
- read-only verifiers: truth_route_auditor
|
|
2242
|
+
- write workers: none in Preview
|
|
2243
|
+
- leases needed: none in Preview
|
|
2244
|
+
|
|
2245
|
+
Blocking ambiguity:
|
|
2246
|
+
- none identified in preview
|
|
2247
|
+
|
|
2248
|
+
Handoff:
|
|
2249
|
+
- Run the selected Truthmark workflow after user approval.`;
|
|
2250
|
+
};
|
|
2251
|
+
var renderTruthPreviewSkillBody = (config = defaultAgentConfig()) => {
|
|
2252
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
2253
|
+
return `---
|
|
2254
|
+
name: truthmark-preview
|
|
2255
|
+
description: ${workflow.description}
|
|
2256
|
+
argument-hint: Optional requested outcome, code area, doc path, or routing question
|
|
2257
|
+
user-invocable: true
|
|
2258
|
+
truthmark-version: ${TRUTHMARK_VERSION}
|
|
2259
|
+
---
|
|
2260
|
+
|
|
2261
|
+
Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.
|
|
2262
|
+
|
|
2263
|
+
Invocations: ${TRUTH_PREVIEW_EXPLICIT_INVOCATIONS}
|
|
2264
|
+
|
|
2265
|
+
Truth Preview is read-only. Its report is intended, not authorized.
|
|
2266
|
+
|
|
2267
|
+
Purpose:
|
|
2268
|
+
- preview the likely Truthmark workflow, route owner, target files, expected write classes, suggested subagent use, and blocking ambiguity before edits happen
|
|
2269
|
+
- hand off to the selected workflow after user approval
|
|
2270
|
+
- keep the selector thin so agents can avoid loading or acting through heavier workflows prematurely
|
|
2271
|
+
|
|
2272
|
+
Read:
|
|
2273
|
+
- .truthmark/config.yml
|
|
2274
|
+
- ${config.docs.routing.rootIndex}
|
|
2275
|
+
- relevant child route files under ${config.docs.routing.areaFilesRoot}/
|
|
2276
|
+
- relevant truth docs and implementation files needed to preview ownership
|
|
2277
|
+
- ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2278
|
+
|
|
2279
|
+
Do not:
|
|
2280
|
+
- must not edit files
|
|
2281
|
+
- must not create truth docs
|
|
2282
|
+
- must not update routing
|
|
2283
|
+
- must not run Truth Sync automatically
|
|
2284
|
+
- must not replace Truth Check
|
|
2285
|
+
- must not claim final correctness
|
|
2286
|
+
- must not issue write leases
|
|
2287
|
+
- must not mutate code
|
|
2288
|
+
|
|
2289
|
+
Suggested subagent use:
|
|
2290
|
+
- optional read-only verifier: truth_route_auditor
|
|
2291
|
+
- write workers: none
|
|
2292
|
+
- leases needed: none
|
|
2293
|
+
|
|
2294
|
+
${renderHierarchySummary(config)}
|
|
2295
|
+
|
|
2296
|
+
Report completion in this shape:
|
|
2297
|
+
${renderMarkdownExample3(renderTruthPreviewReportExample(config))}`;
|
|
2298
|
+
};
|
|
2299
|
+
|
|
2300
|
+
// src/agents/truth-structure.ts
|
|
2301
|
+
var renderMarkdownExample4 = (content) => {
|
|
2302
|
+
return ["```md", content, "```"].join("\n");
|
|
2303
|
+
};
|
|
1929
2304
|
var TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-structure; Codex /truthmark-structure or $truthmark-structure; Claude Code /truthmark-structure; GitHub Copilot /truthmark-structure; Gemini CLI /truthmark:structure.";
|
|
1930
2305
|
var renderTruthStructureReportExample = (config = defaultAgentConfig()) => {
|
|
1931
2306
|
const truthDocsRoot = resolveTruthDocsRoot(config);
|
|
@@ -1938,6 +2313,11 @@ Areas reviewed:
|
|
|
1938
2313
|
- src/auth/**
|
|
1939
2314
|
Routing updated:
|
|
1940
2315
|
- ${config.docs.routing.rootIndex}
|
|
2316
|
+
Initial truth boundary:
|
|
2317
|
+
- Area: Authentication
|
|
2318
|
+
- Code: src/auth/**
|
|
2319
|
+
- Truth owner: ${truthDocsRoot}/authentication/session.md
|
|
2320
|
+
- Scope: session behavior only
|
|
1941
2321
|
Truth docs created:
|
|
1942
2322
|
- ${truthDocsRoot}/authentication/session.md
|
|
1943
2323
|
Truth docs split:
|
|
@@ -1956,9 +2336,20 @@ Topology decisions:
|
|
|
1956
2336
|
Notes:
|
|
1957
2337
|
- Added an Authentication area for session behavior.`;
|
|
1958
2338
|
};
|
|
1959
|
-
var renderTruthStructureSkillBody = (config = defaultAgentConfig()) => {
|
|
2339
|
+
var renderTruthStructureSkillBody = (config = defaultAgentConfig(), options = {}) => {
|
|
1960
2340
|
const truthDocsRoot = resolveTruthDocsRoot(config);
|
|
1961
2341
|
const workflow = getTruthmarkWorkflow("truthmark-structure");
|
|
2342
|
+
const claudeSubagentMode = options.includeClaudeSubagentMode ? `${renderClaudeSubagentModeSection(
|
|
2343
|
+
workflow.subagents ?? [],
|
|
2344
|
+
"Parent agent owns all Truth Structure writes and final topology decisions"
|
|
2345
|
+
)}
|
|
2346
|
+
` : "";
|
|
2347
|
+
const copilotCustomAgentMode = options.includeCopilotCustomAgentMode ? `${renderCopilotCustomAgentModeSection(
|
|
2348
|
+
workflow.subagents ?? [],
|
|
2349
|
+
"Parent agent owns all Truth Structure writes and final topology decisions"
|
|
2350
|
+
)}
|
|
2351
|
+
` : "";
|
|
2352
|
+
const subagentMode = `${claudeSubagentMode}${copilotCustomAgentMode}`;
|
|
1962
2353
|
return `---
|
|
1963
2354
|
name: truthmark-structure
|
|
1964
2355
|
description: ${workflow.description}
|
|
@@ -1978,11 +2369,27 @@ Truth Structure is agent-native:
|
|
|
1978
2369
|
- create starter truth docs when useful and when they belong in the canonical current-truth surface
|
|
1979
2370
|
- Starter truth docs must use closed YAML frontmatter bounded by opening and closing --- lines; include status, doc_type, last_reviewed, and source_of_truth inside that frontmatter.
|
|
1980
2371
|
- Starter truth docs must include ## Product Decisions and ## Rationale sections.
|
|
2372
|
+
${subagentMode}
|
|
1981
2373
|
${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
|
|
1982
2374
|
- use ${truthDocsRoot}/**, docs/architecture/**, or docs/standards/** for current truth destinations
|
|
1983
2375
|
- use only canonical current-truth destinations for starter truth docs
|
|
1984
2376
|
- keep active Product Decisions and Rationale in the canonical doc that owns the behavior
|
|
1985
2377
|
- preserve unrelated authored content
|
|
2378
|
+
## New area setup
|
|
2379
|
+
Use when a user asks to onboard a new code area into Truthmark, a new package, controller, domain, or product area lacks bounded truth ownership, or a new product area needs routing and starter truth docs.
|
|
2380
|
+
Do:
|
|
2381
|
+
- inspect the named code area
|
|
2382
|
+
- infer bounded product or behavior ownership
|
|
2383
|
+
- choose the owning route when ownership is clear; otherwise propose the route and block for review
|
|
2384
|
+
- create or update the child route entry or file
|
|
2385
|
+
- create starter truth docs only where current truth is missing
|
|
2386
|
+
- report the initial truth boundary
|
|
2387
|
+
Do not:
|
|
2388
|
+
- do not edit functional code
|
|
2389
|
+
- do not perform full behavior documentation unless evidence is inspected and the task explicitly asks for it
|
|
2390
|
+
- do not patch broad or mixed-owner docs in place
|
|
2391
|
+
- do not create generic catch-all docs
|
|
2392
|
+
- do not treat README files as Sync targets
|
|
1986
2393
|
## Topology Governance
|
|
1987
2394
|
Truth Structure owns documentation topology. Do not depend on humans to manually organize ${truthDocsRoot}. Treat the configured truth root as a managed semantic root.
|
|
1988
2395
|
Inspect controllers, routes, handlers, services, packages, tests, existing truth docs, and route files; infer product and domain ownership from behavior boundaries, not from mechanical directory mirroring.
|
|
@@ -2032,7 +2439,7 @@ Portable fallback:
|
|
|
2032
2439
|
${renderHierarchySummary(config)}
|
|
2033
2440
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
2034
2441
|
Report completion in this shape:
|
|
2035
|
-
${
|
|
2442
|
+
${renderMarkdownExample4(renderTruthStructureReportExample(config))}`;
|
|
2036
2443
|
};
|
|
2037
2444
|
|
|
2038
2445
|
// src/sync/report.ts
|
|
@@ -2040,24 +2447,105 @@ var renderBulletSection = (title, items) => {
|
|
|
2040
2447
|
return `${title}:
|
|
2041
2448
|
${items.map((item) => `- ${item}`).join("\n")}`;
|
|
2042
2449
|
};
|
|
2450
|
+
var findSection = (source, title) => {
|
|
2451
|
+
return source.split("\n\n").find((candidate) => candidate.startsWith(`${title}:
|
|
2452
|
+
`));
|
|
2453
|
+
};
|
|
2454
|
+
var parseBulletLines = (section) => {
|
|
2455
|
+
return section.split("\n").slice(1).map((line) => {
|
|
2456
|
+
const match = line.match(/^-\s+(.*)$/);
|
|
2457
|
+
return match?.[1];
|
|
2458
|
+
}).filter((line) => line !== void 0);
|
|
2459
|
+
};
|
|
2460
|
+
var parseBulletSection = (source, title) => {
|
|
2461
|
+
const section = findSection(source, title);
|
|
2462
|
+
if (!section) {
|
|
2463
|
+
return [];
|
|
2464
|
+
}
|
|
2465
|
+
return parseBulletLines(section);
|
|
2466
|
+
};
|
|
2467
|
+
var parseOptionalBulletSection = (source, title) => {
|
|
2468
|
+
const section = findSection(source, title);
|
|
2469
|
+
if (!section) {
|
|
2470
|
+
return void 0;
|
|
2471
|
+
}
|
|
2472
|
+
return parseBulletLines(section);
|
|
2473
|
+
};
|
|
2474
|
+
var isClaimEvidenceResult = (value) => {
|
|
2475
|
+
return ["supported", "narrowed", "removed", "blocked"].includes(value);
|
|
2476
|
+
};
|
|
2477
|
+
var hasContent = (value) => value.trim().length > 0;
|
|
2478
|
+
var parseEvidenceCheckedSection = (source) => {
|
|
2479
|
+
const section = source.split("\n\n").find((candidate) => candidate.startsWith("Evidence checked:\n"));
|
|
2480
|
+
if (!section) {
|
|
2481
|
+
throw new Error("Evidence checked section is required.");
|
|
2482
|
+
}
|
|
2483
|
+
const lines = section.split("\n").slice(1);
|
|
2484
|
+
const items = [];
|
|
2485
|
+
for (let index = 0; index < lines.length; index += 3) {
|
|
2486
|
+
const claimLine = lines[index];
|
|
2487
|
+
const evidenceLine = lines[index + 1];
|
|
2488
|
+
const resultLine = lines[index + 2];
|
|
2489
|
+
if (!claimLine?.startsWith("- Claim: ") || !evidenceLine?.startsWith(" Evidence: ") || !resultLine?.startsWith(" Result: ")) {
|
|
2490
|
+
throw new Error("Evidence checked entries must include Claim, Evidence, and Result fields.");
|
|
2491
|
+
}
|
|
2492
|
+
const result = resultLine.slice(" Result: ".length);
|
|
2493
|
+
const claim = claimLine.slice("- Claim: ".length).trim();
|
|
2494
|
+
const evidence = evidenceLine.slice(" Evidence: ".length).split(" / ").map((value) => value.trim());
|
|
2495
|
+
if (!hasContent(claim)) {
|
|
2496
|
+
throw new Error("Evidence checked claim is required.");
|
|
2497
|
+
}
|
|
2498
|
+
if (evidence.length === 0 || evidence.some((value) => !hasContent(value))) {
|
|
2499
|
+
throw new Error("Evidence checked evidence is required.");
|
|
2500
|
+
}
|
|
2501
|
+
if (!isClaimEvidenceResult(result)) {
|
|
2502
|
+
throw new Error("Evidence checked result is invalid.");
|
|
2503
|
+
}
|
|
2504
|
+
items.push({
|
|
2505
|
+
claim,
|
|
2506
|
+
evidence,
|
|
2507
|
+
result
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
return items;
|
|
2511
|
+
};
|
|
2043
2512
|
var renderTruthSyncCompletedReport = (input) => {
|
|
2044
2513
|
return [
|
|
2045
2514
|
"Truth Sync: completed",
|
|
2046
2515
|
renderBulletSection("Changed code reviewed", input.changedCode),
|
|
2516
|
+
renderBulletSection("Ownership reviewed", input.ownershipReviewed),
|
|
2047
2517
|
renderBulletSection("Truth docs updated", input.truthDocsUpdated),
|
|
2048
2518
|
renderClaimEvidenceCheckedSection(input.evidenceChecked),
|
|
2519
|
+
...input.helperScripts === void 0 ? [] : [renderBulletSection("Helper scripts", input.helperScripts)],
|
|
2049
2520
|
renderBulletSection("Notes", input.notes)
|
|
2050
2521
|
].join("\n\n");
|
|
2051
2522
|
};
|
|
2523
|
+
var parseTruthSyncReport = (source) => {
|
|
2524
|
+
if (!source.startsWith("Truth Sync: completed")) {
|
|
2525
|
+
throw new Error("Only completed Truth Sync reports can be parsed.");
|
|
2526
|
+
}
|
|
2527
|
+
const helperScripts = parseOptionalBulletSection(source, "Helper scripts");
|
|
2528
|
+
return {
|
|
2529
|
+
status: "completed",
|
|
2530
|
+
changedCode: parseBulletSection(source, "Changed code reviewed"),
|
|
2531
|
+
ownershipReviewed: parseBulletSection(source, "Ownership reviewed"),
|
|
2532
|
+
truthDocsUpdated: parseBulletSection(source, "Truth docs updated"),
|
|
2533
|
+
evidenceChecked: parseEvidenceCheckedSection(source),
|
|
2534
|
+
...helperScripts === void 0 ? {} : { helperScripts },
|
|
2535
|
+
notes: parseBulletSection(source, "Notes")
|
|
2536
|
+
};
|
|
2537
|
+
};
|
|
2052
2538
|
var renderTruthSyncBlockedReport = (input) => {
|
|
2539
|
+
const manualReviewFiles = input.manualReviewFiles.filter((file) => file.trim().length > 0);
|
|
2540
|
+
if (manualReviewFiles.length === 0) {
|
|
2541
|
+
throw new Error("Files requiring manual review must include at least one file.");
|
|
2542
|
+
}
|
|
2053
2543
|
const sections = [
|
|
2054
2544
|
"Truth Sync: blocked",
|
|
2055
|
-
renderBulletSection("Reason", [input.reason])
|
|
2545
|
+
renderBulletSection("Reason", [input.reason]),
|
|
2546
|
+
renderBulletSection("Files requiring manual review", manualReviewFiles),
|
|
2547
|
+
renderBulletSection("Next action", [input.nextAction])
|
|
2056
2548
|
];
|
|
2057
|
-
if ((input.manualReviewFiles?.length ?? 0) > 0) {
|
|
2058
|
-
sections.push(renderBulletSection("Files requiring manual review", input.manualReviewFiles));
|
|
2059
|
-
}
|
|
2060
|
-
sections.push(renderBulletSection("Next action", [input.nextAction]));
|
|
2061
2549
|
return [
|
|
2062
2550
|
...sections
|
|
2063
2551
|
].join("\n\n");
|
|
@@ -2065,34 +2553,38 @@ var renderTruthSyncBlockedReport = (input) => {
|
|
|
2065
2553
|
|
|
2066
2554
|
// src/agents/truth-sync.ts
|
|
2067
2555
|
var TRUTH_SYNC_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Gemini CLI /truthmark:sync.";
|
|
2068
|
-
var
|
|
2556
|
+
var renderMarkdownExample5 = (content) => {
|
|
2069
2557
|
return ["```md", content, "```"].join("\n");
|
|
2070
2558
|
};
|
|
2071
|
-
var
|
|
2072
|
-
return `### Truth Sync Worker
|
|
2073
|
-
The parent provides the task focus and any repository context already gathered.
|
|
2074
|
-
Worker rules:
|
|
2075
|
-
- inspect relevant staged, unstaged, and untracked functional code directly
|
|
2076
|
-
- read .truthmark/config.yml, ${config.docs.routing.rootIndex}, and canonical truth docs directly
|
|
2077
|
-
- Code verification is parent-owned; report what was run or why it was not run
|
|
2078
|
-
- may write truth docs and ${config.docs.routing.rootIndex} only for Truth Sync alignment
|
|
2079
|
-
- must not rewrite functional code
|
|
2080
|
-
Return result in this shape:
|
|
2081
|
-
- status: completed | blocked
|
|
2082
|
-
- changedCodeReviewed: string[]
|
|
2083
|
-
- ownershipReviewed: string[]
|
|
2084
|
-
- structureRequired?: string[]
|
|
2085
|
-
- truthDocsUpdated: string[]
|
|
2086
|
-
- routingDocsUpdated: string[]
|
|
2087
|
-
- truthDocsSplit?: string[]
|
|
2088
|
-
- evidenceChecked: { claim: string; evidence: string[]; result: supported | narrowed | removed | blocked }[]
|
|
2089
|
-
- notes: string[]
|
|
2090
|
-
- blockedReason?: string
|
|
2091
|
-
- manualReviewFiles?: string[]`;
|
|
2092
|
-
};
|
|
2093
|
-
var renderTruthSyncSkillBody = (config = defaultAgentConfig()) => {
|
|
2559
|
+
var renderTruthSyncSkillBody = (config = defaultAgentConfig(), options = {}) => {
|
|
2094
2560
|
const truthDocsRoot = resolveTruthDocsRoot(config);
|
|
2095
2561
|
const workflow = getTruthmarkWorkflow("truthmark-sync");
|
|
2562
|
+
const helperScripts = ["validate-write-lease: skipped, no write lease used"];
|
|
2563
|
+
const claudeSubagentMode = options.includeClaudeSubagentMode ? `${renderClaudeSubagentModeSection(
|
|
2564
|
+
workflow.subagents ?? [],
|
|
2565
|
+
"Parent agent owns Truth Sync acceptance, lease validation, and final report",
|
|
2566
|
+
workflow.writeSubagents ?? []
|
|
2567
|
+
)}
|
|
2568
|
+
` : "";
|
|
2569
|
+
const codexSubagentMode = options.includeCodexSubagentMode ? `${renderCodexSubagentModeSection(
|
|
2570
|
+
workflow.subagents ?? [],
|
|
2571
|
+
"Parent agent owns Truth Sync acceptance, lease validation, and final report",
|
|
2572
|
+
workflow.writeSubagents ?? []
|
|
2573
|
+
)}
|
|
2574
|
+
` : "";
|
|
2575
|
+
const copilotCustomAgentMode = options.includeCopilotCustomAgentMode ? `${renderCopilotCustomAgentModeSection(
|
|
2576
|
+
workflow.subagents ?? [],
|
|
2577
|
+
"Parent agent owns Truth Sync acceptance, lease validation, and final report",
|
|
2578
|
+
workflow.writeSubagents ?? []
|
|
2579
|
+
)}
|
|
2580
|
+
` : "";
|
|
2581
|
+
const openCodeSubagentMode = options.includeOpenCodeSubagentMode ? `${renderOpenCodeSubagentModeSection(
|
|
2582
|
+
workflow.subagents ?? [],
|
|
2583
|
+
"Parent agent owns Truth Sync acceptance, lease validation, and final report",
|
|
2584
|
+
workflow.writeSubagents ?? []
|
|
2585
|
+
)}
|
|
2586
|
+
` : "";
|
|
2587
|
+
const subagentMode = `${claudeSubagentMode}${codexSubagentMode}${copilotCustomAgentMode}${openCodeSubagentMode}`;
|
|
2096
2588
|
return `---
|
|
2097
2589
|
name: truthmark-sync
|
|
2098
2590
|
description: ${workflow.description}
|
|
@@ -2111,8 +2603,8 @@ Parent workflow:
|
|
|
2111
2603
|
3. Identify functional-code changes and the nearest truth docs or routing repairs.
|
|
2112
2604
|
4. ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2113
2605
|
5. Code verification is parent-owned: follow repository instructions and task context, and report what ran or why it did not run.
|
|
2114
|
-
6. Dispatch
|
|
2115
|
-
Topology quality gate:
|
|
2606
|
+
6. Dispatch bounded Truth Sync workers only when the host supports subagent dispatch and the acting agent chooses that path; otherwise execute the same sync task inline.
|
|
2607
|
+
${subagentMode}Topology quality gate:
|
|
2116
2608
|
- before updating truth docs, verify the changed code resolves to a specific behavior-owned area and bounded truth owner
|
|
2117
2609
|
- if routing is missing, stale, broad, overloaded, catch-all route only, or cannot map changed code to a bounded truth owner, do not create another generic truth doc
|
|
2118
2610
|
- run Truth Structure before syncing when topology repair is safe and in scope
|
|
@@ -2141,22 +2633,28 @@ Optional validation tooling:
|
|
|
2141
2633
|
- do not require the truthmark binary; direct checkout inspection is the canonical path
|
|
2142
2634
|
- optional validation must not replace agent judgment about docs and routing
|
|
2143
2635
|
- update Product Decisions and Rationale when a behavior change comes from a decision change
|
|
2636
|
+
Helper status reporting:
|
|
2637
|
+
- Validate the report body before adding this validator's own success status; the body may omit \`validate-sync-report\` while validation is pending.
|
|
2638
|
+
- After \`truthmark validate sync-report <report-file> --json\` returns \`data.validation.ok: true\`, append or update \`validate-sync-report: ran, passed\` in the final report.
|
|
2639
|
+
- If the installed Truthmark CLI is unavailable or the helper is skipped, record \`validate-sync-report: skipped, <reason>\` and manually validate the report shape.
|
|
2640
|
+
- Record \`validate-write-lease: ran, passed\` only after validating a concrete write lease; otherwise use a truthful skipped status such as \`skipped, no write lease used\`.
|
|
2641
|
+
- Helper output is derived evidence and never replaces direct checkout inspection, evidence review, or parent acceptance.
|
|
2144
2642
|
${renderHierarchySummary(config)}
|
|
2145
2643
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
2146
|
-
${renderTruthSyncWorkerPrompt(config)}
|
|
2147
2644
|
Parent post-sync verification:
|
|
2148
|
-
- verify only truth docs and
|
|
2645
|
+
- verify only truth docs and leased truth routing files changed during sync
|
|
2149
2646
|
- block on any unrelated diff caused by the sync step
|
|
2150
2647
|
- block if functional code changed during sync
|
|
2151
|
-
-
|
|
2152
|
-
- validate the final report against the structured Truth Sync report contract, including Claim, Evidence, and Result
|
|
2648
|
+
- for each write lease, validate the worker report against the actual worker diff, allowedWrites, forbiddenWrites, identity fields, filesChanged, offLeaseChanges, blockers, and required report fields before accepting it
|
|
2649
|
+
- validate the final report against the structured Truth Sync report contract, including Claim, indented Evidence, and Result values supported, narrowed, removed, or blocked under Evidence checked
|
|
2153
2650
|
- verify the updated docs correspond to the reviewed changed-code surface
|
|
2154
2651
|
- verify the final report records ownership review, structure requirement, split, restructure, or blocked reason when the ownership gate fired
|
|
2155
2652
|
- blocked outcomes must preserve the working tree as-is: no rollback, no post-block cleanup edits, and manual-review reporting of any remaining files
|
|
2156
2653
|
Report completion in this shape:
|
|
2157
|
-
${
|
|
2654
|
+
${renderMarkdownExample5(
|
|
2158
2655
|
renderTruthSyncCompletedReport({
|
|
2159
2656
|
changedCode: ["src/auth/session.ts"],
|
|
2657
|
+
ownershipReviewed: [config.docs.routing.rootIndex],
|
|
2160
2658
|
truthDocsUpdated: [`${truthDocsRoot}/repository/overview.md`],
|
|
2161
2659
|
evidenceChecked: [
|
|
2162
2660
|
{
|
|
@@ -2165,11 +2663,12 @@ ${renderMarkdownExample4(
|
|
|
2165
2663
|
result: "supported"
|
|
2166
2664
|
}
|
|
2167
2665
|
],
|
|
2666
|
+
helperScripts,
|
|
2168
2667
|
notes: ["Updated session timeout behavior."]
|
|
2169
2668
|
})
|
|
2170
2669
|
)}
|
|
2171
2670
|
Blocked report example:
|
|
2172
|
-
${
|
|
2671
|
+
${renderMarkdownExample5(
|
|
2173
2672
|
renderTruthSyncBlockedReport({
|
|
2174
2673
|
reason: "routing repair is not allowed",
|
|
2175
2674
|
manualReviewFiles: [config.docs.routing.rootIndex],
|
|
@@ -2178,7 +2677,23 @@ ${renderMarkdownExample4(
|
|
|
2178
2677
|
)}`;
|
|
2179
2678
|
};
|
|
2180
2679
|
|
|
2181
|
-
// src/
|
|
2680
|
+
// src/agents/write-lease.ts
|
|
2681
|
+
import micromatch from "micromatch";
|
|
2682
|
+
import { parse as parseYaml } from "yaml";
|
|
2683
|
+
var TRUTHMARK_WRITE_WORKER_REPORT_FIELDS = [
|
|
2684
|
+
"status",
|
|
2685
|
+
"worker",
|
|
2686
|
+
"workflow",
|
|
2687
|
+
"shard",
|
|
2688
|
+
"filesChanged",
|
|
2689
|
+
"claimsChecked",
|
|
2690
|
+
"evidenceChecked",
|
|
2691
|
+
"offLeaseChanges",
|
|
2692
|
+
"blockers",
|
|
2693
|
+
"notes"
|
|
2694
|
+
];
|
|
2695
|
+
|
|
2696
|
+
// src/templates/workflow-surfaces.ts
|
|
2182
2697
|
var TRUTHMARK_STRUCTURE_SKILL_PATH = ".codex/skills/truthmark-structure/SKILL.md";
|
|
2183
2698
|
var TRUTHMARK_STRUCTURE_SKILL_METADATA_PATH = ".codex/skills/truthmark-structure/agents/openai.yaml";
|
|
2184
2699
|
var TRUTHMARK_DOCUMENT_SKILL_PATH = ".codex/skills/truthmark-document/SKILL.md";
|
|
@@ -2189,20 +2704,46 @@ var TRUTHMARK_REALIZE_SKILL_PATH = ".codex/skills/truthmark-realize/SKILL.md";
|
|
|
2189
2704
|
var TRUTHMARK_REALIZE_SKILL_METADATA_PATH = ".codex/skills/truthmark-realize/agents/openai.yaml";
|
|
2190
2705
|
var TRUTHMARK_CHECK_SKILL_PATH = ".codex/skills/truthmark-check/SKILL.md";
|
|
2191
2706
|
var TRUTHMARK_CHECK_SKILL_METADATA_PATH = ".codex/skills/truthmark-check/agents/openai.yaml";
|
|
2707
|
+
var TRUTHMARK_PREVIEW_SKILL_PATH = ".codex/skills/truthmark-preview/SKILL.md";
|
|
2708
|
+
var TRUTHMARK_PREVIEW_SKILL_METADATA_PATH = ".codex/skills/truthmark-preview/agents/openai.yaml";
|
|
2709
|
+
var TRUTHMARK_ROUTE_AUDITOR_AGENT_PATH = ".codex/agents/truth-route-auditor.toml";
|
|
2710
|
+
var TRUTHMARK_CLAIM_VERIFIER_AGENT_PATH = ".codex/agents/truth-claim-verifier.toml";
|
|
2711
|
+
var TRUTHMARK_DOC_REVIEWER_AGENT_PATH = ".codex/agents/truth-doc-reviewer.toml";
|
|
2712
|
+
var TRUTHMARK_DOC_WRITER_AGENT_PATH = ".codex/agents/truth-doc-writer.toml";
|
|
2713
|
+
var TRUTHMARK_OPENCODE_ROUTE_AUDITOR_AGENT_PATH = ".opencode/agents/truth-route-auditor.md";
|
|
2714
|
+
var TRUTHMARK_OPENCODE_CLAIM_VERIFIER_AGENT_PATH = ".opencode/agents/truth-claim-verifier.md";
|
|
2715
|
+
var TRUTHMARK_OPENCODE_DOC_REVIEWER_AGENT_PATH = ".opencode/agents/truth-doc-reviewer.md";
|
|
2716
|
+
var TRUTHMARK_OPENCODE_DOC_WRITER_AGENT_PATH = ".opencode/agents/truth-doc-writer.md";
|
|
2717
|
+
var TRUTHMARK_CLAUDE_ROUTE_AUDITOR_AGENT_PATH = ".claude/agents/truth-route-auditor.md";
|
|
2718
|
+
var TRUTHMARK_CLAUDE_CLAIM_VERIFIER_AGENT_PATH = ".claude/agents/truth-claim-verifier.md";
|
|
2719
|
+
var TRUTHMARK_CLAUDE_DOC_REVIEWER_AGENT_PATH = ".claude/agents/truth-doc-reviewer.md";
|
|
2720
|
+
var TRUTHMARK_CLAUDE_DOC_WRITER_AGENT_PATH = ".claude/agents/truth-doc-writer.md";
|
|
2192
2721
|
var TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH = ".gemini/commands/truthmark/structure.toml";
|
|
2193
2722
|
var TRUTHMARK_GEMINI_DOCUMENT_COMMAND_PATH = ".gemini/commands/truthmark/document.toml";
|
|
2194
2723
|
var TRUTHMARK_GEMINI_SYNC_COMMAND_PATH = ".gemini/commands/truthmark/sync.toml";
|
|
2195
2724
|
var TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH = ".gemini/commands/truthmark/realize.toml";
|
|
2196
2725
|
var TRUTHMARK_GEMINI_CHECK_COMMAND_PATH = ".gemini/commands/truthmark/check.toml";
|
|
2726
|
+
var TRUTHMARK_GEMINI_PREVIEW_COMMAND_PATH = ".gemini/commands/truthmark/preview.toml";
|
|
2727
|
+
var TRUTHMARK_GEMINI_ROUTE_AUDITOR_AGENT_PATH = ".gemini/agents/truth-route-auditor.md";
|
|
2728
|
+
var TRUTHMARK_GEMINI_CLAIM_VERIFIER_AGENT_PATH = ".gemini/agents/truth-claim-verifier.md";
|
|
2729
|
+
var TRUTHMARK_GEMINI_DOC_REVIEWER_AGENT_PATH = ".gemini/agents/truth-doc-reviewer.md";
|
|
2730
|
+
var TRUTHMARK_GEMINI_DOC_WRITER_AGENT_PATH = ".gemini/agents/truth-doc-writer.md";
|
|
2197
2731
|
var TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH = ".github/prompts/truthmark-structure.prompt.md";
|
|
2198
2732
|
var TRUTHMARK_COPILOT_DOCUMENT_PROMPT_PATH = ".github/prompts/truthmark-document.prompt.md";
|
|
2199
2733
|
var TRUTHMARK_COPILOT_SYNC_PROMPT_PATH = ".github/prompts/truthmark-sync.prompt.md";
|
|
2200
2734
|
var TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH = ".github/prompts/truthmark-realize.prompt.md";
|
|
2201
2735
|
var TRUTHMARK_COPILOT_CHECK_PROMPT_PATH = ".github/prompts/truthmark-check.prompt.md";
|
|
2736
|
+
var TRUTHMARK_COPILOT_PREVIEW_PROMPT_PATH = ".github/prompts/truthmark-preview.prompt.md";
|
|
2737
|
+
var TRUTHMARK_COPILOT_ROUTE_AUDITOR_AGENT_PATH = ".github/agents/truth-route-auditor.agent.md";
|
|
2738
|
+
var TRUTHMARK_COPILOT_CLAIM_VERIFIER_AGENT_PATH = ".github/agents/truth-claim-verifier.agent.md";
|
|
2739
|
+
var TRUTHMARK_COPILOT_DOC_REVIEWER_AGENT_PATH = ".github/agents/truth-doc-reviewer.agent.md";
|
|
2740
|
+
var TRUTHMARK_COPILOT_DOC_WRITER_AGENT_PATH = ".github/agents/truth-doc-writer.agent.md";
|
|
2202
2741
|
var renderGeminiCommand = (description, prompt) => {
|
|
2742
|
+
const promptWithArgs = `${prompt.trimEnd()}
|
|
2743
|
+
User focus or arguments: {{args}}`;
|
|
2203
2744
|
return `description = "${description}"
|
|
2204
2745
|
prompt = '''
|
|
2205
|
-
${
|
|
2746
|
+
${promptWithArgs}
|
|
2206
2747
|
'''
|
|
2207
2748
|
`;
|
|
2208
2749
|
};
|
|
@@ -2215,11 +2756,768 @@ description: '${description}'
|
|
|
2215
2756
|
${prompt}
|
|
2216
2757
|
`;
|
|
2217
2758
|
};
|
|
2218
|
-
var
|
|
2219
|
-
return
|
|
2759
|
+
var renderTomlString = (value) => {
|
|
2760
|
+
return `"${value.replace(/\\/gu, "\\\\").replace(/"/gu, '\\"')}"`;
|
|
2761
|
+
};
|
|
2762
|
+
var renderTomlStringArray = (values) => {
|
|
2763
|
+
return `[${values.map(renderTomlString).join(", ")}]`;
|
|
2764
|
+
};
|
|
2765
|
+
var TRUTH_REALIZE_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Claude Code /truthmark-realize; GitHub Copilot /truthmark-realize; Gemini CLI /truthmark:realize.";
|
|
2766
|
+
var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
2767
|
+
"truthmark-structure": {
|
|
2768
|
+
title: "Truthmark Structure",
|
|
2769
|
+
argumentHint: "Optional area, directory, or routing concern",
|
|
2770
|
+
invocations: TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS,
|
|
2771
|
+
use: () => "Use this skill to design or repair Truthmark area structure.",
|
|
2772
|
+
quickRules: (config) => [
|
|
2773
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2774
|
+
`Read .truthmark/config.yml, ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, current docs, and relevant code directly.`,
|
|
2775
|
+
"Define areas by product or behavior ownership, not by mechanical directory mirroring.",
|
|
2776
|
+
"Do not edit functional code.",
|
|
2777
|
+
"Read support/procedure.md before writing route or starter truth-doc changes.",
|
|
2778
|
+
"Read support/report-template.md before the final report."
|
|
2779
|
+
],
|
|
2780
|
+
parentRule: "Parent agent owns all Truth Structure writes and final topology decisions"
|
|
2781
|
+
},
|
|
2782
|
+
"truthmark-document": {
|
|
2783
|
+
title: "Truthmark Document",
|
|
2784
|
+
argumentHint: "Optional implemented behavior, API endpoint, route, controller, package, or truth-doc area to document",
|
|
2785
|
+
invocations: TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS,
|
|
2786
|
+
use: () => "Use this skill to document existing implemented behavior when no functional-code changes are required for the task.",
|
|
2787
|
+
quickRules: (config) => [
|
|
2788
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2789
|
+
`Read .truthmark/config.yml, ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, existing canonical docs, implementation code, and tests directly.`,
|
|
2790
|
+
"Document current implemented behavior; do not invent future behavior.",
|
|
2791
|
+
"May write canonical truth docs and truth routing files only; must not write functional code.",
|
|
2792
|
+
"Read support/procedure.md before editing truth docs.",
|
|
2793
|
+
"Read support/subagents-and-leases.md before dispatching or accepting worker output.",
|
|
2794
|
+
"Read support/report-template.md before the final report."
|
|
2795
|
+
],
|
|
2796
|
+
parentRule: "Parent agent owns Truth Document acceptance, lease validation, and final report"
|
|
2797
|
+
},
|
|
2798
|
+
"truthmark-sync": {
|
|
2799
|
+
title: "Truthmark Sync",
|
|
2800
|
+
argumentHint: "Optional changed-code area, truth-doc area, or sync focus",
|
|
2801
|
+
invocations: TRUTH_SYNC_EXPLICIT_INVOCATIONS,
|
|
2802
|
+
use: () => "Use this skill automatically before finishing when functional code changed since the last successful Truth Sync. Also run it immediately when the user explicitly invokes Truth Sync.",
|
|
2803
|
+
quickRules: (config) => [
|
|
2804
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2805
|
+
"Skip docs-only, formatting-only, behavior-preserving renames with no truth impact, missing config, and no-code changes.",
|
|
2806
|
+
`Read .truthmark/config.yml, the configured root route index at ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, and relevant canonical docs.`,
|
|
2807
|
+
"direct checkout inspection is the canonical path; do not require the truthmark binary.",
|
|
2808
|
+
"May write canonical truth docs and truth routing files only; must not rewrite functional code.",
|
|
2809
|
+
"Read support/procedure.md before editing truth docs.",
|
|
2810
|
+
"Read support/subagents-and-leases.md before dispatching or accepting worker output.",
|
|
2811
|
+
"Read support/report-template.md before the final report."
|
|
2812
|
+
],
|
|
2813
|
+
parentRule: "Parent agent owns Truth Sync acceptance, lease validation, and final report"
|
|
2814
|
+
},
|
|
2815
|
+
"truthmark-preview": {
|
|
2816
|
+
title: "Truthmark Preview",
|
|
2817
|
+
argumentHint: "Optional requested outcome, code area, doc path, or routing question",
|
|
2818
|
+
invocations: TRUTH_PREVIEW_EXPLICIT_INVOCATIONS,
|
|
2819
|
+
use: () => "Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.",
|
|
2820
|
+
quickRules: (config) => [
|
|
2821
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2822
|
+
`Read .truthmark/config.yml, ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, and only the truth docs or implementation files needed to preview ownership.`,
|
|
2823
|
+
"Truth Preview is read-only; this report is intended, not authorized.",
|
|
2824
|
+
"must not edit files and must not issue write leases; do not run Truth Sync automatically, replace Truth Check, claim final correctness, or mutate code.",
|
|
2825
|
+
"Use optional read-only route-auditor evidence only when it reduces context or clarifies ownership.",
|
|
2826
|
+
"Hand off to the selected workflow after user approval."
|
|
2827
|
+
],
|
|
2828
|
+
parentRule: "Parent agent owns the final Truth Preview report"
|
|
2829
|
+
},
|
|
2830
|
+
"truthmark-realize": {
|
|
2831
|
+
title: "Truthmark Realize",
|
|
2832
|
+
argumentHint: "Optional truth doc path, area, or desired code behavior to realize",
|
|
2833
|
+
invocations: TRUTH_REALIZE_EXPLICIT_INVOCATIONS,
|
|
2834
|
+
use: () => "Use this skill only when the user explicitly asks to realize truth docs into code.",
|
|
2835
|
+
quickRules: (config) => [
|
|
2836
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2837
|
+
`Read the source truth docs, .truthmark/config.yml, ${config.docs.routing.rootIndex}, relevant child route files, tests, and relevant functional code directly.`,
|
|
2838
|
+
"Truth docs lead; code follows.",
|
|
2839
|
+
"may write functional code only; must not edit truth docs or truth routing while realizing those docs.",
|
|
2840
|
+
"Read support/procedure.md before changing code.",
|
|
2841
|
+
"Read support/report-template.md before the final report."
|
|
2842
|
+
]
|
|
2843
|
+
},
|
|
2844
|
+
"truthmark-check": {
|
|
2845
|
+
title: "Truthmark Check",
|
|
2846
|
+
argumentHint: "Optional area, doc path, or audit focus",
|
|
2847
|
+
invocations: TRUTH_CHECK_EXPLICIT_INVOCATIONS,
|
|
2848
|
+
use: () => "Use this skill to audit repository truth health.",
|
|
2849
|
+
quickRules: (config) => [
|
|
2850
|
+
"Follow docs/ai/repo-rules.md as the repository instruction authority.",
|
|
2851
|
+
`Read .truthmark/config.yml, ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, canonical docs, and relevant implementation directly.`,
|
|
2852
|
+
"Report issues and suggested fixes; do not silently rewrite unrelated files.",
|
|
2853
|
+
"Direct checkout inspection is valid even when local tooling is unavailable.",
|
|
2854
|
+
"Read support/procedure.md before auditing details.",
|
|
2855
|
+
"Read support/subagents-and-leases.md before dispatching verifier subagents.",
|
|
2856
|
+
"Read support/report-template.md before the final report."
|
|
2857
|
+
],
|
|
2858
|
+
parentRule: "Parent agent owns the final Truth Check report"
|
|
2859
|
+
}
|
|
2860
|
+
};
|
|
2861
|
+
var stripWorkflowSkillFrontmatter = (body) => {
|
|
2862
|
+
return body.replace(/^---\n[\s\S]*?\n---\n\n?/u, "").trim();
|
|
2863
|
+
};
|
|
2864
|
+
var splitWorkflowSupport = (body) => {
|
|
2865
|
+
const stripped = stripWorkflowSkillFrontmatter(body);
|
|
2866
|
+
const marker = "Report completion in this shape:";
|
|
2867
|
+
const markerIndex = stripped.indexOf(marker);
|
|
2868
|
+
if (markerIndex === -1) {
|
|
2869
|
+
return {
|
|
2870
|
+
procedure: stripped,
|
|
2871
|
+
reportTemplate: "Report completion in the workflow-specific shape."
|
|
2872
|
+
};
|
|
2873
|
+
}
|
|
2874
|
+
return {
|
|
2875
|
+
procedure: stripped.slice(0, markerIndex).trim(),
|
|
2876
|
+
reportTemplate: stripped.slice(markerIndex).trim()
|
|
2877
|
+
};
|
|
2878
|
+
};
|
|
2879
|
+
var renderSkillSupportFile = (title, body) => {
|
|
2880
|
+
return `# ${title}
|
|
2881
|
+
|
|
2882
|
+
Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
2883
|
+
|
|
2884
|
+
${body}
|
|
2885
|
+
`;
|
|
2886
|
+
};
|
|
2887
|
+
var renderHelperManifest = (helpers) => {
|
|
2888
|
+
const manifest = {
|
|
2889
|
+
helpers: Object.fromEntries(
|
|
2890
|
+
helpers.map((helper) => [
|
|
2891
|
+
helper.id,
|
|
2892
|
+
{
|
|
2893
|
+
optional: helper.optional,
|
|
2894
|
+
runner: helper.runner,
|
|
2895
|
+
command: helper.command,
|
|
2896
|
+
inputs: helper.inputs,
|
|
2897
|
+
output: helper.output,
|
|
2898
|
+
writes: helper.writes,
|
|
2899
|
+
...helper.allowedWrites === void 0 ? {} : { allowedWrites: helper.allowedWrites },
|
|
2900
|
+
fallback: helper.fallback
|
|
2901
|
+
}
|
|
2902
|
+
])
|
|
2903
|
+
)
|
|
2904
|
+
};
|
|
2905
|
+
return [
|
|
2906
|
+
`# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.`,
|
|
2907
|
+
stringify2(manifest, { lineWidth: 0 })
|
|
2908
|
+
].join("\n");
|
|
2909
|
+
};
|
|
2910
|
+
var renderHelperPolicySupport = (helpers) => {
|
|
2911
|
+
const reportHelperId = helpers.find((helper) => helper.id.endsWith("-report"))?.id ?? helpers[0]?.id;
|
|
2912
|
+
const helperLines = helpers.map(
|
|
2913
|
+
(helper) => `- ${helper.id}: optional ${helper.runner}; manual fallback: ${helper.fallback}`
|
|
2914
|
+
).join("\n");
|
|
2915
|
+
return renderSkillSupportFile(
|
|
2916
|
+
"Optional Helper CLI Policy",
|
|
2917
|
+
`Optional helper CLI commands may collect deterministic checkout facts or validate artifacts. If the Truthmark CLI is unavailable or too old for a declared helper, continue manually using this procedure and report which helper was skipped. Helper output is derived evidence; it does not override direct checkout inspection, workflow write boundaries, or parent acceptance.
|
|
2918
|
+
|
|
2919
|
+
Runner detection:
|
|
2920
|
+
- Check the declared Truthmark CLI runner before invoking a helper.
|
|
2921
|
+
- Invoke helpers through the installed \`truthmark validate ... --json\` CLI command using argv-style arguments from helper-manifest.yml.
|
|
2922
|
+
- If unavailable or version-mismatched, treat the helper as skipped and use the manual fallback.
|
|
2923
|
+
- Do not fail the workflow solely because a helper cannot run.
|
|
2924
|
+
|
|
2925
|
+
Available helpers:
|
|
2926
|
+
${helperLines}
|
|
2927
|
+
|
|
2928
|
+
Final reports should include helper status when helpers are declared for this workflow:
|
|
2929
|
+
|
|
2930
|
+
\`\`\`md
|
|
2931
|
+
Helper scripts:
|
|
2932
|
+
- ${reportHelperId}: ran, passed
|
|
2933
|
+
- validate-write-lease: skipped, no write lease used
|
|
2934
|
+
\`\`\``
|
|
2935
|
+
);
|
|
2936
|
+
};
|
|
2937
|
+
var renderStandaloneWorkflowSkillBody = (workflowId, config) => {
|
|
2938
|
+
switch (workflowId) {
|
|
2939
|
+
case "truthmark-structure":
|
|
2940
|
+
return renderTruthStructureSkillBody(config);
|
|
2941
|
+
case "truthmark-document":
|
|
2942
|
+
return renderTruthDocumentSkillBody(config);
|
|
2943
|
+
case "truthmark-sync":
|
|
2944
|
+
return renderTruthSyncSkillBody(config);
|
|
2945
|
+
case "truthmark-preview":
|
|
2946
|
+
return renderTruthPreviewSkillBody(config);
|
|
2947
|
+
case "truthmark-realize":
|
|
2948
|
+
return renderTruthmarkRealizeSkillBody(config);
|
|
2949
|
+
case "truthmark-check":
|
|
2950
|
+
return renderTruthCheckSkillBody(config);
|
|
2951
|
+
}
|
|
2952
|
+
};
|
|
2953
|
+
var renderWorkflowEntrypoint = (workflowId, config, supportFiles, host) => {
|
|
2954
|
+
const workflow = getTruthmarkWorkflow(workflowId);
|
|
2955
|
+
const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
|
|
2956
|
+
const supportFileList = supportFiles.map((supportFile) => `- ${supportFile}`).join("\n");
|
|
2957
|
+
const hostUsage = host === "github-copilot" ? "Use as a Copilot agent skill. Prompt files remain available under `.github/prompts/` for command-style invocation in supported Copilot IDEs." : host === "gemini-cli" ? "Use as a Gemini CLI Agent Skill; commands remain available under `/truthmark:*` for command-first invocation." : void 0;
|
|
2958
|
+
return `---
|
|
2959
|
+
name: ${workflowId}
|
|
2960
|
+
description: ${workflow.description}
|
|
2961
|
+
argument-hint: ${definition.argumentHint}
|
|
2962
|
+
user-invocable: true
|
|
2963
|
+
truthmark-version: ${TRUTHMARK_VERSION}
|
|
2964
|
+
---
|
|
2965
|
+
|
|
2966
|
+
# ${definition.title}
|
|
2967
|
+
|
|
2968
|
+
${definition.use(config)}
|
|
2969
|
+
${hostUsage === void 0 ? "" : `
|
|
2970
|
+
${hostUsage}
|
|
2971
|
+
`}
|
|
2972
|
+
|
|
2973
|
+
Invocations: ${definition.invocations}
|
|
2974
|
+
|
|
2975
|
+
Quick procedure:
|
|
2976
|
+
${definition.quickRules(config).map((rule) => `- ${rule}`).join("\n")}
|
|
2977
|
+
|
|
2978
|
+
Progressive disclosure:
|
|
2979
|
+
${supportFileList}
|
|
2980
|
+
`;
|
|
2981
|
+
};
|
|
2982
|
+
var renderWorkflowSubagentSupport = (workflowId, host) => {
|
|
2983
|
+
const workflow = getTruthmarkWorkflow(workflowId);
|
|
2984
|
+
const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
|
|
2985
|
+
const readAgents = workflow.subagents ?? [];
|
|
2986
|
+
const writeAgents = workflow.writeSubagents ?? [];
|
|
2987
|
+
if (readAgents.length === 0 && writeAgents.length === 0) {
|
|
2988
|
+
return void 0;
|
|
2989
|
+
}
|
|
2990
|
+
if (definition.parentRule === void 0) {
|
|
2991
|
+
return void 0;
|
|
2992
|
+
}
|
|
2993
|
+
switch (host) {
|
|
2994
|
+
case "codex":
|
|
2995
|
+
return renderCodexSubagentModeSection(
|
|
2996
|
+
readAgents,
|
|
2997
|
+
definition.parentRule,
|
|
2998
|
+
writeAgents
|
|
2999
|
+
);
|
|
3000
|
+
case "opencode":
|
|
3001
|
+
return renderOpenCodeSubagentModeSection(
|
|
3002
|
+
readAgents,
|
|
3003
|
+
definition.parentRule,
|
|
3004
|
+
writeAgents
|
|
3005
|
+
);
|
|
3006
|
+
case "claude-code":
|
|
3007
|
+
return renderClaudeSubagentModeSection(
|
|
3008
|
+
readAgents,
|
|
3009
|
+
definition.parentRule,
|
|
3010
|
+
writeAgents
|
|
3011
|
+
);
|
|
3012
|
+
case "github-copilot":
|
|
3013
|
+
return renderCopilotCustomAgentModeSection(
|
|
3014
|
+
readAgents,
|
|
3015
|
+
definition.parentRule,
|
|
3016
|
+
writeAgents
|
|
3017
|
+
);
|
|
3018
|
+
case "gemini-cli":
|
|
3019
|
+
return renderGeminiSubagentModeSection(
|
|
3020
|
+
readAgents,
|
|
3021
|
+
definition.parentRule,
|
|
3022
|
+
writeAgents
|
|
3023
|
+
);
|
|
3024
|
+
}
|
|
3025
|
+
};
|
|
3026
|
+
var renderTruthmarkSkillPackage = ({
|
|
3027
|
+
skillPath,
|
|
3028
|
+
workflowId,
|
|
3029
|
+
host,
|
|
3030
|
+
config = defaultAgentConfig()
|
|
3031
|
+
}) => {
|
|
3032
|
+
const skillDirectory = skillPath.replace(/\/SKILL\.md$/u, "");
|
|
3033
|
+
const supportDirectory = `${skillDirectory}/support`;
|
|
3034
|
+
const { procedure, reportTemplate } = splitWorkflowSupport(
|
|
3035
|
+
renderStandaloneWorkflowSkillBody(workflowId, config)
|
|
3036
|
+
);
|
|
3037
|
+
const subagents = renderWorkflowSubagentSupport(workflowId, host);
|
|
3038
|
+
const helpers = getTruthmarkWorkflow(workflowId).helpers ?? [];
|
|
3039
|
+
const supportFiles = [
|
|
3040
|
+
"support/procedure.md",
|
|
3041
|
+
"support/report-template.md",
|
|
3042
|
+
...subagents === void 0 ? [] : ["support/subagents-and-leases.md"],
|
|
3043
|
+
...helpers.length === 0 ? [] : ["helper-manifest.yml", "support/helper-policy.md"]
|
|
3044
|
+
];
|
|
3045
|
+
const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
|
|
3046
|
+
const files = [
|
|
3047
|
+
{
|
|
3048
|
+
path: skillPath,
|
|
3049
|
+
content: renderWorkflowEntrypoint(workflowId, config, supportFiles, host)
|
|
3050
|
+
},
|
|
3051
|
+
{
|
|
3052
|
+
path: `${supportDirectory}/procedure.md`,
|
|
3053
|
+
content: renderSkillSupportFile(
|
|
3054
|
+
`${definition.title} Procedure`,
|
|
3055
|
+
procedure
|
|
3056
|
+
)
|
|
3057
|
+
},
|
|
3058
|
+
{
|
|
3059
|
+
path: `${supportDirectory}/report-template.md`,
|
|
3060
|
+
content: renderSkillSupportFile(
|
|
3061
|
+
`${definition.title} Report Template`,
|
|
3062
|
+
reportTemplate
|
|
3063
|
+
)
|
|
3064
|
+
}
|
|
3065
|
+
];
|
|
3066
|
+
if (subagents !== void 0) {
|
|
3067
|
+
files.push({
|
|
3068
|
+
path: `${supportDirectory}/subagents-and-leases.md`,
|
|
3069
|
+
content: renderSkillSupportFile(
|
|
3070
|
+
`${definition.title} Subagents And Leases`,
|
|
3071
|
+
subagents
|
|
3072
|
+
)
|
|
3073
|
+
});
|
|
3074
|
+
}
|
|
3075
|
+
if (helpers.length > 0) {
|
|
3076
|
+
files.push(
|
|
3077
|
+
{
|
|
3078
|
+
path: `${skillDirectory}/helper-manifest.yml`,
|
|
3079
|
+
content: renderHelperManifest(helpers)
|
|
3080
|
+
},
|
|
3081
|
+
{
|
|
3082
|
+
path: `${supportDirectory}/helper-policy.md`,
|
|
3083
|
+
content: renderHelperPolicySupport(helpers)
|
|
3084
|
+
}
|
|
3085
|
+
);
|
|
3086
|
+
}
|
|
3087
|
+
return files;
|
|
3088
|
+
};
|
|
3089
|
+
var normalizeOpenCodePermissionPath = (path12) => {
|
|
3090
|
+
const normalized = path12.replace(/\\/gu, "/").replace(/^\.\//u, "").replace(/\/+$/u, "");
|
|
3091
|
+
return normalized === "" ? "." : normalized;
|
|
3092
|
+
};
|
|
3093
|
+
var appendOpenCodePermissionGlob = (root, glob) => {
|
|
3094
|
+
return root === "." ? glob.replace(/^\//u, "") : `${root}${glob}`;
|
|
3095
|
+
};
|
|
3096
|
+
var renderOpenCodeWriterEditAllowRules = (config) => {
|
|
3097
|
+
const truthDocsRoot = normalizeOpenCodePermissionPath(
|
|
3098
|
+
resolveTruthDocsRoot(config)
|
|
3099
|
+
);
|
|
3100
|
+
const rootRouteIndex = normalizeOpenCodePermissionPath(
|
|
3101
|
+
config.docs.routing.rootIndex
|
|
3102
|
+
);
|
|
3103
|
+
const areaFilesRoot = normalizeOpenCodePermissionPath(
|
|
3104
|
+
config.docs.routing.areaFilesRoot
|
|
3105
|
+
);
|
|
3106
|
+
const allowedPatterns = [
|
|
3107
|
+
appendOpenCodePermissionGlob(truthDocsRoot, "/**"),
|
|
3108
|
+
rootRouteIndex,
|
|
3109
|
+
appendOpenCodePermissionGlob(areaFilesRoot, "/**/*.md")
|
|
3110
|
+
];
|
|
3111
|
+
return [...new Set(allowedPatterns)].map((pattern) => ` ${JSON.stringify(pattern)}: allow`).join("\n");
|
|
3112
|
+
};
|
|
3113
|
+
var READ_ONLY_SUBAGENT_CONTEXT_BOUNDARY = `Context boundary:
|
|
3114
|
+
Do not preload AGENTS.md, CLAUDE.md, GEMINI.md, .github/copilot-instructions.md, or repo-wide policy docs unless the parent explicitly assigns them as evidence.
|
|
3115
|
+
Use only the parent-assigned shard plus required checkout evidence files.
|
|
3116
|
+
Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes.`;
|
|
3117
|
+
var renderReadOnlySubagentInstructions = (instructions) => {
|
|
3118
|
+
return `${instructions}
|
|
3119
|
+
${READ_ONLY_SUBAGENT_CONTEXT_BOUNDARY}`;
|
|
3120
|
+
};
|
|
3121
|
+
var TRUTHMARK_SUBAGENT_PROFILES = {
|
|
3122
|
+
truth_route_auditor: {
|
|
3123
|
+
codexName: "truth_route_auditor",
|
|
3124
|
+
copilotName: "truth-route-auditor",
|
|
3125
|
+
description: "Read-only Truthmark route auditor for bounded routing and ownership verification.",
|
|
3126
|
+
nicknameCandidates: ["Route Audit", "Route Trace", "Route Check"],
|
|
3127
|
+
instructions: `Stay read-only.
|
|
3128
|
+
Audit one bounded Truthmark route, area, or doc shard assigned by the parent.
|
|
3129
|
+
Read .truthmark/config.yml, the root route index, relevant child route files, mapped truth docs, and relevant implementation files directly.
|
|
3130
|
+
Find missing, stale, broad, overloaded, catch-all, mixed-owner, or unrouteable ownership.
|
|
3131
|
+
Do not edit files, stage changes, or propose broad rewrites.
|
|
3132
|
+
Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes.
|
|
3133
|
+
recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure.`
|
|
3134
|
+
},
|
|
3135
|
+
truth_claim_verifier: {
|
|
3136
|
+
codexName: "truth_claim_verifier",
|
|
3137
|
+
copilotName: "truth-claim-verifier",
|
|
3138
|
+
description: "Read-only Truthmark claim verifier for checking canonical truth against checkout evidence.",
|
|
3139
|
+
nicknameCandidates: ["Claim Audit", "Claim Trace", "Claim Check"],
|
|
3140
|
+
instructions: `Stay read-only.
|
|
3141
|
+
Verify the behavior-bearing truth claims assigned by the parent against primary checkout evidence.
|
|
3142
|
+
Use implementation, tests, config, routing, generated templates, schemas, or explicit evidence blocks as primary evidence.
|
|
3143
|
+
Canonical docs and examples can corroborate but are not sole proof when implementation conflicts.
|
|
3144
|
+
For every checked claim, classify the result as supported | narrowed | removed | blocked.
|
|
3145
|
+
Do not edit files, stage changes, or invent missing behavior.
|
|
3146
|
+
Return JSON only with keys: scope, filesReviewed, claimsChecked, evidence, unsupportedClaims, confidence, recommendedWorkflow, notes.`
|
|
3147
|
+
},
|
|
3148
|
+
truth_doc_reviewer: {
|
|
3149
|
+
codexName: "truth_doc_reviewer",
|
|
3150
|
+
copilotName: "truth-doc-reviewer",
|
|
3151
|
+
description: "Read-only Truthmark doc reviewer for shape, decision, rationale, and evidence hygiene.",
|
|
3152
|
+
nicknameCandidates: ["Doc Audit", "Doc Shape", "Doc Check"],
|
|
3153
|
+
instructions: `Stay read-only.
|
|
3154
|
+
Review assigned canonical truth docs for frontmatter, source_of_truth, required template sections, Evidence checked entries, Product Decisions, and Rationale.
|
|
3155
|
+
Flag README.md files used as behavior truth targets, mixed-owner docs, and shape repairs that should move to Truth Structure.
|
|
3156
|
+
Do not edit files, stage changes, or rewrite docs.
|
|
3157
|
+
Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes.
|
|
3158
|
+
recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure.`
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
var TRUTHMARK_WRITE_SUBAGENT_PROFILES = {
|
|
3162
|
+
truth_doc_writer: {
|
|
3163
|
+
codexName: "truth_doc_writer",
|
|
3164
|
+
copilotName: "truth-doc-writer",
|
|
3165
|
+
description: "Write-capable Truthmark doc worker for one parent-leased truth-document shard.",
|
|
3166
|
+
nicknameCandidates: ["Doc Writer", "Truth Writer", "Doc Sync"],
|
|
3167
|
+
instructions: `Write one leased Truthmark truth-document shard assigned by the parent.
|
|
3168
|
+
Require an explicit write lease before editing. The lease must name workflow, worker, shard, objective, requiredReads, allowedWrites, forbiddenWrites, evidenceRequired, verification, and reportFields.
|
|
3169
|
+
Read every requiredReads entry directly before editing.
|
|
3170
|
+
Edit only leased canonical truth docs or leased truth routing files. Do not edit functional code, generated host surfaces, package files, config files, templates, or tests unless they are explicitly leased.
|
|
3171
|
+
Do not expand your own write scope. If the task needs an off-lease file, stop and report blocked.
|
|
3172
|
+
Block when ownership is missing or ambiguous, evidence does not support the requested claim, another worker changed the leased file, generated surfaces appear stale, or a required edit is outside the lease.
|
|
3173
|
+
Return YAML only with keys: ${TRUTHMARK_WRITE_WORKER_REPORT_FIELDS.join(", ")}.
|
|
3174
|
+
status must be completed or blocked.
|
|
3175
|
+
filesChanged must list only files you actually changed.
|
|
3176
|
+
offLeaseChanges must be empty for completed reports.
|
|
3177
|
+
The parent must validate the actual checkout diff before accepting your report.`
|
|
3178
|
+
}
|
|
3179
|
+
};
|
|
3180
|
+
var renderCodexReadOnlyAgent = ({
|
|
3181
|
+
name,
|
|
3182
|
+
description,
|
|
3183
|
+
nicknameCandidates,
|
|
3184
|
+
developerInstructions
|
|
3185
|
+
}) => {
|
|
3186
|
+
return `# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3187
|
+
name = ${renderTomlString(name)}
|
|
3188
|
+
description = ${renderTomlString(description)}
|
|
3189
|
+
sandbox_mode = "read-only"
|
|
3190
|
+
nickname_candidates = ${renderTomlStringArray(nicknameCandidates)}
|
|
3191
|
+
developer_instructions = """
|
|
3192
|
+
${developerInstructions}
|
|
3193
|
+
"""
|
|
3194
|
+
`;
|
|
3195
|
+
};
|
|
3196
|
+
var renderCodexWriteAgent = ({
|
|
3197
|
+
name,
|
|
3198
|
+
description,
|
|
3199
|
+
nicknameCandidates,
|
|
3200
|
+
developerInstructions
|
|
3201
|
+
}) => {
|
|
3202
|
+
return `# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3203
|
+
name = ${renderTomlString(name)}
|
|
3204
|
+
description = ${renderTomlString(description)}
|
|
3205
|
+
sandbox_mode = "workspace-write"
|
|
3206
|
+
nickname_candidates = ${renderTomlStringArray(nicknameCandidates)}
|
|
3207
|
+
developer_instructions = """
|
|
3208
|
+
${developerInstructions}
|
|
3209
|
+
"""
|
|
3210
|
+
`;
|
|
3211
|
+
};
|
|
3212
|
+
var renderCopilotReadOnlyAgent = ({
|
|
3213
|
+
copilotName,
|
|
3214
|
+
description,
|
|
3215
|
+
instructions
|
|
3216
|
+
}) => {
|
|
3217
|
+
const agentInstructions = renderReadOnlySubagentInstructions(instructions);
|
|
3218
|
+
return `---
|
|
3219
|
+
name: ${copilotName}
|
|
3220
|
+
description: ${description}
|
|
3221
|
+
tools: [read, search]
|
|
3222
|
+
---
|
|
3223
|
+
|
|
3224
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3225
|
+
|
|
3226
|
+
${agentInstructions}
|
|
3227
|
+
`;
|
|
3228
|
+
};
|
|
3229
|
+
var renderCopilotWriteAgent = ({
|
|
3230
|
+
copilotName,
|
|
3231
|
+
description,
|
|
3232
|
+
instructions
|
|
3233
|
+
}) => {
|
|
3234
|
+
return `---
|
|
3235
|
+
name: ${copilotName}
|
|
3236
|
+
description: ${description}
|
|
3237
|
+
tools: [read, search, edit]
|
|
3238
|
+
---
|
|
3239
|
+
|
|
3240
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3241
|
+
|
|
3242
|
+
${instructions}
|
|
3243
|
+
`;
|
|
3244
|
+
};
|
|
3245
|
+
var renderGeminiReadOnlyAgent = ({
|
|
3246
|
+
copilotName,
|
|
3247
|
+
description,
|
|
3248
|
+
instructions
|
|
3249
|
+
}) => {
|
|
3250
|
+
const agentInstructions = renderReadOnlySubagentInstructions(instructions);
|
|
3251
|
+
return `---
|
|
3252
|
+
name: ${copilotName}
|
|
3253
|
+
description: ${description}
|
|
3254
|
+
kind: local
|
|
3255
|
+
tools: [read_file, grep_search]
|
|
3256
|
+
---
|
|
3257
|
+
|
|
3258
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3259
|
+
|
|
3260
|
+
Manual invocation: @${copilotName}
|
|
3261
|
+
|
|
3262
|
+
${agentInstructions}
|
|
3263
|
+
`;
|
|
3264
|
+
};
|
|
3265
|
+
var renderGeminiWriteAgent = ({
|
|
3266
|
+
copilotName,
|
|
3267
|
+
description,
|
|
3268
|
+
instructions
|
|
3269
|
+
}) => {
|
|
3270
|
+
return `---
|
|
3271
|
+
name: ${copilotName}
|
|
3272
|
+
description: ${description}
|
|
3273
|
+
kind: local
|
|
3274
|
+
tools: [read_file, grep_search, write_file]
|
|
3275
|
+
---
|
|
3276
|
+
|
|
3277
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3278
|
+
|
|
3279
|
+
Manual invocation: @${copilotName} with an explicit parent write lease.
|
|
3280
|
+
|
|
3281
|
+
${instructions}
|
|
3282
|
+
`;
|
|
3283
|
+
};
|
|
3284
|
+
var renderClaudeReadOnlyAgent = ({
|
|
3285
|
+
copilotName,
|
|
3286
|
+
description,
|
|
3287
|
+
instructions
|
|
3288
|
+
}) => {
|
|
3289
|
+
const agentInstructions = renderReadOnlySubagentInstructions(instructions);
|
|
3290
|
+
return `---
|
|
3291
|
+
name: ${copilotName}
|
|
3292
|
+
description: ${description}
|
|
3293
|
+
tools: Read, Grep, Glob, LS
|
|
3294
|
+
---
|
|
3295
|
+
|
|
3296
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3297
|
+
|
|
3298
|
+
Manual invocation: use the ${copilotName} subagent.
|
|
3299
|
+
|
|
3300
|
+
${agentInstructions}
|
|
3301
|
+
`;
|
|
3302
|
+
};
|
|
3303
|
+
var renderClaudeWriteAgent = ({
|
|
3304
|
+
copilotName,
|
|
3305
|
+
description,
|
|
3306
|
+
instructions
|
|
3307
|
+
}) => {
|
|
3308
|
+
return `---
|
|
3309
|
+
name: ${copilotName}
|
|
3310
|
+
description: ${description}
|
|
3311
|
+
tools: Read, Grep, Glob, LS, Edit, MultiEdit
|
|
3312
|
+
---
|
|
3313
|
+
|
|
3314
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3315
|
+
|
|
3316
|
+
Manual invocation: use the ${copilotName} subagent with an explicit parent write lease.
|
|
3317
|
+
|
|
3318
|
+
${instructions}
|
|
3319
|
+
`;
|
|
3320
|
+
};
|
|
3321
|
+
var renderTruthmarkRouteAuditorAgent = () => {
|
|
3322
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor;
|
|
3323
|
+
return renderCodexReadOnlyAgent({
|
|
3324
|
+
name: profile.codexName,
|
|
3325
|
+
description: profile.description,
|
|
3326
|
+
nicknameCandidates: profile.nicknameCandidates,
|
|
3327
|
+
developerInstructions: renderReadOnlySubagentInstructions(
|
|
3328
|
+
profile.instructions
|
|
3329
|
+
)
|
|
3330
|
+
});
|
|
3331
|
+
};
|
|
3332
|
+
var renderTruthmarkClaimVerifierAgent = () => {
|
|
3333
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier;
|
|
3334
|
+
return renderCodexReadOnlyAgent({
|
|
3335
|
+
name: profile.codexName,
|
|
3336
|
+
description: profile.description,
|
|
3337
|
+
nicknameCandidates: profile.nicknameCandidates,
|
|
3338
|
+
developerInstructions: renderReadOnlySubagentInstructions(
|
|
3339
|
+
profile.instructions
|
|
3340
|
+
)
|
|
3341
|
+
});
|
|
3342
|
+
};
|
|
3343
|
+
var renderTruthmarkDocReviewerAgent = () => {
|
|
3344
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer;
|
|
3345
|
+
return renderCodexReadOnlyAgent({
|
|
3346
|
+
name: profile.codexName,
|
|
3347
|
+
description: profile.description,
|
|
3348
|
+
nicknameCandidates: profile.nicknameCandidates,
|
|
3349
|
+
developerInstructions: renderReadOnlySubagentInstructions(
|
|
3350
|
+
profile.instructions
|
|
3351
|
+
)
|
|
3352
|
+
});
|
|
3353
|
+
};
|
|
3354
|
+
var renderTruthmarkDocWriterAgent = () => {
|
|
3355
|
+
const profile = TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer;
|
|
3356
|
+
return renderCodexWriteAgent({
|
|
3357
|
+
name: profile.codexName,
|
|
3358
|
+
description: profile.description,
|
|
3359
|
+
nicknameCandidates: profile.nicknameCandidates,
|
|
3360
|
+
developerInstructions: profile.instructions
|
|
3361
|
+
});
|
|
3362
|
+
};
|
|
3363
|
+
var renderTruthmarkCopilotRouteAuditorAgent = () => {
|
|
3364
|
+
return renderCopilotReadOnlyAgent(
|
|
3365
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor
|
|
3366
|
+
);
|
|
3367
|
+
};
|
|
3368
|
+
var renderTruthmarkCopilotClaimVerifierAgent = () => {
|
|
3369
|
+
return renderCopilotReadOnlyAgent(
|
|
3370
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier
|
|
3371
|
+
);
|
|
3372
|
+
};
|
|
3373
|
+
var renderTruthmarkCopilotDocReviewerAgent = () => {
|
|
3374
|
+
return renderCopilotReadOnlyAgent(
|
|
3375
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer
|
|
3376
|
+
);
|
|
3377
|
+
};
|
|
3378
|
+
var renderTruthmarkCopilotDocWriterAgent = () => {
|
|
3379
|
+
return renderCopilotWriteAgent(
|
|
3380
|
+
TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer
|
|
3381
|
+
);
|
|
3382
|
+
};
|
|
3383
|
+
var renderTruthmarkGeminiRouteAuditorAgent = () => {
|
|
3384
|
+
return renderGeminiReadOnlyAgent(
|
|
3385
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor
|
|
3386
|
+
);
|
|
3387
|
+
};
|
|
3388
|
+
var renderTruthmarkGeminiClaimVerifierAgent = () => {
|
|
3389
|
+
return renderGeminiReadOnlyAgent(
|
|
3390
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier
|
|
3391
|
+
);
|
|
3392
|
+
};
|
|
3393
|
+
var renderTruthmarkGeminiDocReviewerAgent = () => {
|
|
3394
|
+
return renderGeminiReadOnlyAgent(
|
|
3395
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer
|
|
3396
|
+
);
|
|
3397
|
+
};
|
|
3398
|
+
var renderTruthmarkGeminiDocWriterAgent = () => {
|
|
3399
|
+
return renderGeminiWriteAgent(
|
|
3400
|
+
TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer
|
|
3401
|
+
);
|
|
3402
|
+
};
|
|
3403
|
+
var renderTruthmarkClaudeRouteAuditorAgent = () => {
|
|
3404
|
+
return renderClaudeReadOnlyAgent(
|
|
3405
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor
|
|
3406
|
+
);
|
|
3407
|
+
};
|
|
3408
|
+
var renderTruthmarkClaudeClaimVerifierAgent = () => {
|
|
3409
|
+
return renderClaudeReadOnlyAgent(
|
|
3410
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier
|
|
3411
|
+
);
|
|
2220
3412
|
};
|
|
2221
|
-
var
|
|
2222
|
-
return
|
|
3413
|
+
var renderTruthmarkClaudeDocReviewerAgent = () => {
|
|
3414
|
+
return renderClaudeReadOnlyAgent(
|
|
3415
|
+
TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer
|
|
3416
|
+
);
|
|
3417
|
+
};
|
|
3418
|
+
var renderTruthmarkClaudeDocWriterAgent = () => {
|
|
3419
|
+
return renderClaudeWriteAgent(
|
|
3420
|
+
TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer
|
|
3421
|
+
);
|
|
3422
|
+
};
|
|
3423
|
+
var renderOpenCodeReadOnlyAgent = ({
|
|
3424
|
+
invocation,
|
|
3425
|
+
description,
|
|
3426
|
+
instructions
|
|
3427
|
+
}) => {
|
|
3428
|
+
const agentInstructions = renderReadOnlySubagentInstructions(instructions);
|
|
3429
|
+
return `---
|
|
3430
|
+
description: ${description}
|
|
3431
|
+
mode: subagent
|
|
3432
|
+
permission:
|
|
3433
|
+
edit: deny
|
|
3434
|
+
task: deny
|
|
3435
|
+
webfetch: deny
|
|
3436
|
+
websearch: deny
|
|
3437
|
+
external_directory: deny
|
|
3438
|
+
bash:
|
|
3439
|
+
"*": ask
|
|
3440
|
+
"git status*": allow
|
|
3441
|
+
"git diff*": allow
|
|
3442
|
+
"git log*": allow
|
|
3443
|
+
"rg *": allow
|
|
3444
|
+
"grep *": allow
|
|
3445
|
+
---
|
|
3446
|
+
|
|
3447
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3448
|
+
|
|
3449
|
+
Manual invocation: @${invocation}
|
|
3450
|
+
|
|
3451
|
+
${agentInstructions}
|
|
3452
|
+
`;
|
|
3453
|
+
};
|
|
3454
|
+
var renderOpenCodeWriteAgent = ({
|
|
3455
|
+
invocation,
|
|
3456
|
+
description,
|
|
3457
|
+
instructions,
|
|
3458
|
+
config
|
|
3459
|
+
}) => {
|
|
3460
|
+
const editAllowRules = renderOpenCodeWriterEditAllowRules(config);
|
|
3461
|
+
return `---
|
|
3462
|
+
description: ${description}
|
|
3463
|
+
mode: subagent
|
|
3464
|
+
permission:
|
|
3465
|
+
read: allow
|
|
3466
|
+
list: allow
|
|
3467
|
+
grep: allow
|
|
3468
|
+
glob: allow
|
|
3469
|
+
edit:
|
|
3470
|
+
"*": deny
|
|
3471
|
+
${editAllowRules}
|
|
3472
|
+
task: deny
|
|
3473
|
+
webfetch: deny
|
|
3474
|
+
websearch: deny
|
|
3475
|
+
external_directory: deny
|
|
3476
|
+
bash:
|
|
3477
|
+
"*": ask
|
|
3478
|
+
"git status*": allow
|
|
3479
|
+
"git diff*": allow
|
|
3480
|
+
---
|
|
3481
|
+
|
|
3482
|
+
# Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun truthmark init after upgrades.
|
|
3483
|
+
|
|
3484
|
+
Manual invocation: @${invocation}
|
|
3485
|
+
|
|
3486
|
+
${instructions}
|
|
3487
|
+
`;
|
|
3488
|
+
};
|
|
3489
|
+
var renderTruthmarkOpenCodeRouteAuditorAgent = () => {
|
|
3490
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor;
|
|
3491
|
+
return renderOpenCodeReadOnlyAgent({
|
|
3492
|
+
invocation: profile.copilotName,
|
|
3493
|
+
description: profile.description,
|
|
3494
|
+
instructions: profile.instructions
|
|
3495
|
+
});
|
|
3496
|
+
};
|
|
3497
|
+
var renderTruthmarkOpenCodeClaimVerifierAgent = () => {
|
|
3498
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier;
|
|
3499
|
+
return renderOpenCodeReadOnlyAgent({
|
|
3500
|
+
invocation: profile.copilotName,
|
|
3501
|
+
description: profile.description,
|
|
3502
|
+
instructions: profile.instructions
|
|
3503
|
+
});
|
|
3504
|
+
};
|
|
3505
|
+
var renderTruthmarkOpenCodeDocReviewerAgent = () => {
|
|
3506
|
+
const profile = TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer;
|
|
3507
|
+
return renderOpenCodeReadOnlyAgent({
|
|
3508
|
+
invocation: profile.copilotName,
|
|
3509
|
+
description: profile.description,
|
|
3510
|
+
instructions: profile.instructions
|
|
3511
|
+
});
|
|
3512
|
+
};
|
|
3513
|
+
var renderTruthmarkOpenCodeDocWriterAgent = (config = defaultAgentConfig()) => {
|
|
3514
|
+
const profile = TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer;
|
|
3515
|
+
return renderOpenCodeWriteAgent({
|
|
3516
|
+
invocation: profile.copilotName,
|
|
3517
|
+
description: profile.description,
|
|
3518
|
+
instructions: profile.instructions,
|
|
3519
|
+
config
|
|
3520
|
+
});
|
|
2223
3521
|
};
|
|
2224
3522
|
var renderTruthmarkStructureSkillMetadata = () => {
|
|
2225
3523
|
const workflow = getTruthmarkWorkflow("truthmark-structure");
|
|
@@ -2236,12 +3534,6 @@ truthmark:
|
|
|
2236
3534
|
refresh_command: "truthmark init"
|
|
2237
3535
|
`;
|
|
2238
3536
|
};
|
|
2239
|
-
var renderTruthmarkDocumentSkill = (config = defaultAgentConfig()) => {
|
|
2240
|
-
return renderTruthDocumentSkillBody(config);
|
|
2241
|
-
};
|
|
2242
|
-
var renderTruthmarkDocumentLocalSkill = (config = defaultAgentConfig()) => {
|
|
2243
|
-
return renderTruthDocumentSkillBody(config);
|
|
2244
|
-
};
|
|
2245
3537
|
var renderTruthmarkDocumentSkillMetadata = () => {
|
|
2246
3538
|
const workflow = getTruthmarkWorkflow("truthmark-document");
|
|
2247
3539
|
return `interface:
|
|
@@ -2257,12 +3549,6 @@ truthmark:
|
|
|
2257
3549
|
refresh_command: "truthmark init"
|
|
2258
3550
|
`;
|
|
2259
3551
|
};
|
|
2260
|
-
var renderTruthmarkSyncSkill = (config = defaultAgentConfig()) => {
|
|
2261
|
-
return renderTruthSyncSkillBody(config);
|
|
2262
|
-
};
|
|
2263
|
-
var renderTruthmarkSyncLocalSkill = (config = defaultAgentConfig()) => {
|
|
2264
|
-
return renderTruthSyncSkillBody(config);
|
|
2265
|
-
};
|
|
2266
3552
|
var renderTruthmarkSyncSkillMetadata = () => {
|
|
2267
3553
|
const workflow = getTruthmarkWorkflow("truthmark-sync");
|
|
2268
3554
|
return `interface:
|
|
@@ -2338,14 +3624,23 @@ Verification:
|
|
|
2338
3624
|
\`\`\`
|
|
2339
3625
|
`;
|
|
2340
3626
|
};
|
|
2341
|
-
var
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
3627
|
+
var renderTruthmarkRealizeSkillMetadata = () => {
|
|
3628
|
+
const workflow = getTruthmarkWorkflow("truthmark-realize");
|
|
3629
|
+
return `interface:
|
|
3630
|
+
display_name: "${workflow.displayName}"
|
|
3631
|
+
short_description: "${workflow.shortDescription}"
|
|
3632
|
+
default_prompt: "${workflow.defaultPrompt}"
|
|
3633
|
+
|
|
3634
|
+
policy:
|
|
3635
|
+
allow_implicit_invocation: ${workflow.allowImplicitInvocation}
|
|
3636
|
+
|
|
3637
|
+
truthmark:
|
|
3638
|
+
version: "${TRUTHMARK_VERSION}"
|
|
3639
|
+
refresh_command: "truthmark init"
|
|
3640
|
+
`;
|
|
2346
3641
|
};
|
|
2347
|
-
var
|
|
2348
|
-
const workflow = getTruthmarkWorkflow("truthmark-
|
|
3642
|
+
var renderTruthmarkPreviewSkillMetadata = () => {
|
|
3643
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
2349
3644
|
return `interface:
|
|
2350
3645
|
display_name: "${workflow.displayName}"
|
|
2351
3646
|
short_description: "${workflow.shortDescription}"
|
|
@@ -2359,12 +3654,6 @@ truthmark:
|
|
|
2359
3654
|
refresh_command: "truthmark init"
|
|
2360
3655
|
`;
|
|
2361
3656
|
};
|
|
2362
|
-
var renderTruthmarkCheckSkill = (config = defaultAgentConfig()) => {
|
|
2363
|
-
return renderTruthCheckSkillBody(config);
|
|
2364
|
-
};
|
|
2365
|
-
var renderTruthmarkCheckLocalSkill = (config = defaultAgentConfig()) => {
|
|
2366
|
-
return renderTruthCheckSkillBody(config);
|
|
2367
|
-
};
|
|
2368
3657
|
var renderTruthmarkCheckSkillMetadata = () => {
|
|
2369
3658
|
const workflow = getTruthmarkWorkflow("truthmark-check");
|
|
2370
3659
|
return `interface:
|
|
@@ -2415,25 +3704,38 @@ var renderTruthmarkGeminiCheckCommand = (config = defaultAgentConfig()) => {
|
|
|
2415
3704
|
renderTruthCheckSkillBody(config)
|
|
2416
3705
|
);
|
|
2417
3706
|
};
|
|
3707
|
+
var renderTruthmarkGeminiPreviewCommand = (config = defaultAgentConfig()) => {
|
|
3708
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
3709
|
+
return renderGeminiCommand(
|
|
3710
|
+
workflow.description,
|
|
3711
|
+
renderTruthPreviewSkillBody(config)
|
|
3712
|
+
);
|
|
3713
|
+
};
|
|
2418
3714
|
var renderTruthmarkCopilotStructurePrompt = (config = defaultAgentConfig()) => {
|
|
2419
3715
|
const workflow = getTruthmarkWorkflow("truthmark-structure");
|
|
2420
3716
|
return renderCopilotPromptFile(
|
|
2421
3717
|
workflow.description,
|
|
2422
|
-
renderTruthStructureSkillBody(config
|
|
3718
|
+
renderTruthStructureSkillBody(config, {
|
|
3719
|
+
includeCopilotCustomAgentMode: true
|
|
3720
|
+
})
|
|
2423
3721
|
);
|
|
2424
3722
|
};
|
|
2425
3723
|
var renderTruthmarkCopilotDocumentPrompt = (config = defaultAgentConfig()) => {
|
|
2426
3724
|
const workflow = getTruthmarkWorkflow("truthmark-document");
|
|
2427
3725
|
return renderCopilotPromptFile(
|
|
2428
3726
|
workflow.description,
|
|
2429
|
-
renderTruthDocumentSkillBody(config
|
|
3727
|
+
renderTruthDocumentSkillBody(config, {
|
|
3728
|
+
includeCopilotCustomAgentMode: true
|
|
3729
|
+
})
|
|
2430
3730
|
);
|
|
2431
3731
|
};
|
|
2432
3732
|
var renderTruthmarkCopilotSyncPrompt = (config = defaultAgentConfig()) => {
|
|
2433
3733
|
const workflow = getTruthmarkWorkflow("truthmark-sync");
|
|
2434
3734
|
return renderCopilotPromptFile(
|
|
2435
3735
|
workflow.description,
|
|
2436
|
-
renderTruthSyncSkillBody(config
|
|
3736
|
+
renderTruthSyncSkillBody(config, {
|
|
3737
|
+
includeCopilotCustomAgentMode: true
|
|
3738
|
+
})
|
|
2437
3739
|
);
|
|
2438
3740
|
};
|
|
2439
3741
|
var renderTruthmarkCopilotRealizePrompt = (config = defaultAgentConfig()) => {
|
|
@@ -2447,84 +3749,253 @@ var renderTruthmarkCopilotCheckPrompt = (config = defaultAgentConfig()) => {
|
|
|
2447
3749
|
const workflow = getTruthmarkWorkflow("truthmark-check");
|
|
2448
3750
|
return renderCopilotPromptFile(
|
|
2449
3751
|
workflow.description,
|
|
2450
|
-
renderTruthCheckSkillBody(config
|
|
3752
|
+
renderTruthCheckSkillBody(config, {
|
|
3753
|
+
includeCopilotCustomAgentMode: true
|
|
3754
|
+
})
|
|
3755
|
+
);
|
|
3756
|
+
};
|
|
3757
|
+
var renderTruthmarkCopilotPreviewPrompt = (config = defaultAgentConfig()) => {
|
|
3758
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
3759
|
+
return renderCopilotPromptFile(
|
|
3760
|
+
workflow.description,
|
|
3761
|
+
renderTruthPreviewSkillBody(config)
|
|
2451
3762
|
);
|
|
2452
3763
|
};
|
|
2453
3764
|
|
|
2454
3765
|
// src/templates/generated-surfaces.ts
|
|
2455
|
-
var
|
|
3766
|
+
var codexFiles = (config) => {
|
|
2456
3767
|
const files = [
|
|
3768
|
+
...renderTruthmarkSkillPackage({
|
|
3769
|
+
skillPath: TRUTHMARK_STRUCTURE_SKILL_PATH,
|
|
3770
|
+
workflowId: "truthmark-structure",
|
|
3771
|
+
host: "codex",
|
|
3772
|
+
config
|
|
3773
|
+
}),
|
|
2457
3774
|
{
|
|
2458
|
-
path:
|
|
2459
|
-
content:
|
|
3775
|
+
path: TRUTHMARK_STRUCTURE_SKILL_METADATA_PATH,
|
|
3776
|
+
content: renderTruthmarkStructureSkillMetadata()
|
|
2460
3777
|
},
|
|
3778
|
+
...renderTruthmarkSkillPackage({
|
|
3779
|
+
skillPath: TRUTHMARK_DOCUMENT_SKILL_PATH,
|
|
3780
|
+
workflowId: "truthmark-document",
|
|
3781
|
+
host: "codex",
|
|
3782
|
+
config
|
|
3783
|
+
}),
|
|
2461
3784
|
{
|
|
2462
|
-
path:
|
|
2463
|
-
content:
|
|
3785
|
+
path: TRUTHMARK_DOCUMENT_SKILL_METADATA_PATH,
|
|
3786
|
+
content: renderTruthmarkDocumentSkillMetadata()
|
|
2464
3787
|
},
|
|
3788
|
+
...renderTruthmarkSkillPackage({
|
|
3789
|
+
skillPath: TRUTHMARK_SYNC_SKILL_PATH,
|
|
3790
|
+
workflowId: "truthmark-sync",
|
|
3791
|
+
host: "codex",
|
|
3792
|
+
config
|
|
3793
|
+
}),
|
|
2465
3794
|
{
|
|
2466
|
-
path:
|
|
2467
|
-
content:
|
|
3795
|
+
path: TRUTHMARK_SYNC_SKILL_METADATA_PATH,
|
|
3796
|
+
content: renderTruthmarkSyncSkillMetadata()
|
|
2468
3797
|
},
|
|
3798
|
+
...renderTruthmarkSkillPackage({
|
|
3799
|
+
skillPath: TRUTHMARK_PREVIEW_SKILL_PATH,
|
|
3800
|
+
workflowId: "truthmark-preview",
|
|
3801
|
+
host: "codex",
|
|
3802
|
+
config
|
|
3803
|
+
}),
|
|
2469
3804
|
{
|
|
2470
|
-
path:
|
|
2471
|
-
content:
|
|
3805
|
+
path: TRUTHMARK_PREVIEW_SKILL_METADATA_PATH,
|
|
3806
|
+
content: renderTruthmarkPreviewSkillMetadata()
|
|
2472
3807
|
},
|
|
3808
|
+
...renderTruthmarkSkillPackage({
|
|
3809
|
+
skillPath: TRUTHMARK_CHECK_SKILL_PATH,
|
|
3810
|
+
workflowId: "truthmark-check",
|
|
3811
|
+
host: "codex",
|
|
3812
|
+
config
|
|
3813
|
+
}),
|
|
2473
3814
|
{
|
|
2474
|
-
path:
|
|
2475
|
-
content:
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
3815
|
+
path: TRUTHMARK_CHECK_SKILL_METADATA_PATH,
|
|
3816
|
+
content: renderTruthmarkCheckSkillMetadata()
|
|
3817
|
+
},
|
|
3818
|
+
...renderTruthmarkSkillPackage({
|
|
3819
|
+
skillPath: TRUTHMARK_REALIZE_SKILL_PATH,
|
|
3820
|
+
workflowId: "truthmark-realize",
|
|
3821
|
+
host: "codex",
|
|
3822
|
+
config
|
|
3823
|
+
}),
|
|
2482
3824
|
{
|
|
2483
|
-
path:
|
|
2484
|
-
content:
|
|
3825
|
+
path: TRUTHMARK_REALIZE_SKILL_METADATA_PATH,
|
|
3826
|
+
content: renderTruthmarkRealizeSkillMetadata()
|
|
2485
3827
|
},
|
|
2486
3828
|
{
|
|
2487
|
-
path:
|
|
2488
|
-
content:
|
|
3829
|
+
path: TRUTHMARK_ROUTE_AUDITOR_AGENT_PATH,
|
|
3830
|
+
content: renderTruthmarkRouteAuditorAgent()
|
|
2489
3831
|
},
|
|
2490
3832
|
{
|
|
2491
|
-
path:
|
|
2492
|
-
content:
|
|
3833
|
+
path: TRUTHMARK_CLAIM_VERIFIER_AGENT_PATH,
|
|
3834
|
+
content: renderTruthmarkClaimVerifierAgent()
|
|
2493
3835
|
},
|
|
2494
3836
|
{
|
|
2495
|
-
path:
|
|
2496
|
-
content:
|
|
3837
|
+
path: TRUTHMARK_DOC_REVIEWER_AGENT_PATH,
|
|
3838
|
+
content: renderTruthmarkDocReviewerAgent()
|
|
3839
|
+
},
|
|
3840
|
+
{
|
|
3841
|
+
path: TRUTHMARK_DOC_WRITER_AGENT_PATH,
|
|
3842
|
+
content: renderTruthmarkDocWriterAgent()
|
|
3843
|
+
}
|
|
3844
|
+
];
|
|
3845
|
+
return files;
|
|
3846
|
+
};
|
|
3847
|
+
var opencodeFiles = (config) => {
|
|
3848
|
+
return [
|
|
3849
|
+
...renderTruthmarkSkillPackage({
|
|
3850
|
+
skillPath: ".opencode/skills/truthmark-structure/SKILL.md",
|
|
3851
|
+
workflowId: "truthmark-structure",
|
|
3852
|
+
host: "opencode",
|
|
3853
|
+
config
|
|
3854
|
+
}),
|
|
3855
|
+
...renderTruthmarkSkillPackage({
|
|
3856
|
+
skillPath: ".opencode/skills/truthmark-document/SKILL.md",
|
|
3857
|
+
workflowId: "truthmark-document",
|
|
3858
|
+
host: "opencode",
|
|
3859
|
+
config
|
|
3860
|
+
}),
|
|
3861
|
+
...renderTruthmarkSkillPackage({
|
|
3862
|
+
skillPath: ".opencode/skills/truthmark-sync/SKILL.md",
|
|
3863
|
+
workflowId: "truthmark-sync",
|
|
3864
|
+
host: "opencode",
|
|
3865
|
+
config
|
|
3866
|
+
}),
|
|
3867
|
+
...renderTruthmarkSkillPackage({
|
|
3868
|
+
skillPath: ".opencode/skills/truthmark-preview/SKILL.md",
|
|
3869
|
+
workflowId: "truthmark-preview",
|
|
3870
|
+
host: "opencode",
|
|
3871
|
+
config
|
|
3872
|
+
}),
|
|
3873
|
+
...renderTruthmarkSkillPackage({
|
|
3874
|
+
skillPath: ".opencode/skills/truthmark-check/SKILL.md",
|
|
3875
|
+
workflowId: "truthmark-check",
|
|
3876
|
+
host: "opencode",
|
|
3877
|
+
config
|
|
3878
|
+
}),
|
|
3879
|
+
...renderTruthmarkSkillPackage({
|
|
3880
|
+
skillPath: ".opencode/skills/truthmark-realize/SKILL.md",
|
|
3881
|
+
workflowId: "truthmark-realize",
|
|
3882
|
+
host: "opencode",
|
|
3883
|
+
config
|
|
3884
|
+
}),
|
|
3885
|
+
{
|
|
3886
|
+
path: TRUTHMARK_OPENCODE_ROUTE_AUDITOR_AGENT_PATH,
|
|
3887
|
+
content: renderTruthmarkOpenCodeRouteAuditorAgent()
|
|
2497
3888
|
},
|
|
2498
3889
|
{
|
|
2499
|
-
path:
|
|
2500
|
-
content:
|
|
3890
|
+
path: TRUTHMARK_OPENCODE_CLAIM_VERIFIER_AGENT_PATH,
|
|
3891
|
+
content: renderTruthmarkOpenCodeClaimVerifierAgent()
|
|
2501
3892
|
},
|
|
2502
3893
|
{
|
|
2503
|
-
path:
|
|
2504
|
-
content:
|
|
3894
|
+
path: TRUTHMARK_OPENCODE_DOC_REVIEWER_AGENT_PATH,
|
|
3895
|
+
content: renderTruthmarkOpenCodeDocReviewerAgent()
|
|
2505
3896
|
},
|
|
2506
3897
|
{
|
|
2507
|
-
path:
|
|
2508
|
-
content:
|
|
3898
|
+
path: TRUTHMARK_OPENCODE_DOC_WRITER_AGENT_PATH,
|
|
3899
|
+
content: renderTruthmarkOpenCodeDocWriterAgent(config)
|
|
3900
|
+
}
|
|
3901
|
+
];
|
|
3902
|
+
};
|
|
3903
|
+
var claudeFiles = (config, block) => {
|
|
3904
|
+
return [
|
|
3905
|
+
...instructionBlockFiles(["CLAUDE.md"], block),
|
|
3906
|
+
...renderTruthmarkSkillPackage({
|
|
3907
|
+
skillPath: ".claude/skills/truthmark-structure/SKILL.md",
|
|
3908
|
+
workflowId: "truthmark-structure",
|
|
3909
|
+
host: "claude-code",
|
|
3910
|
+
config
|
|
3911
|
+
}),
|
|
3912
|
+
...renderTruthmarkSkillPackage({
|
|
3913
|
+
skillPath: ".claude/skills/truthmark-document/SKILL.md",
|
|
3914
|
+
workflowId: "truthmark-document",
|
|
3915
|
+
host: "claude-code",
|
|
3916
|
+
config
|
|
3917
|
+
}),
|
|
3918
|
+
...renderTruthmarkSkillPackage({
|
|
3919
|
+
skillPath: ".claude/skills/truthmark-sync/SKILL.md",
|
|
3920
|
+
workflowId: "truthmark-sync",
|
|
3921
|
+
host: "claude-code",
|
|
3922
|
+
config
|
|
3923
|
+
}),
|
|
3924
|
+
...renderTruthmarkSkillPackage({
|
|
3925
|
+
skillPath: ".claude/skills/truthmark-preview/SKILL.md",
|
|
3926
|
+
workflowId: "truthmark-preview",
|
|
3927
|
+
host: "claude-code",
|
|
3928
|
+
config
|
|
3929
|
+
}),
|
|
3930
|
+
...renderTruthmarkSkillPackage({
|
|
3931
|
+
skillPath: ".claude/skills/truthmark-check/SKILL.md",
|
|
3932
|
+
workflowId: "truthmark-check",
|
|
3933
|
+
host: "claude-code",
|
|
3934
|
+
config
|
|
3935
|
+
}),
|
|
3936
|
+
...renderTruthmarkSkillPackage({
|
|
3937
|
+
skillPath: ".claude/skills/truthmark-realize/SKILL.md",
|
|
3938
|
+
workflowId: "truthmark-realize",
|
|
3939
|
+
host: "claude-code",
|
|
3940
|
+
config
|
|
3941
|
+
}),
|
|
3942
|
+
{
|
|
3943
|
+
path: TRUTHMARK_CLAUDE_ROUTE_AUDITOR_AGENT_PATH,
|
|
3944
|
+
content: renderTruthmarkClaudeRouteAuditorAgent()
|
|
2509
3945
|
},
|
|
2510
3946
|
{
|
|
2511
|
-
path:
|
|
2512
|
-
content:
|
|
3947
|
+
path: TRUTHMARK_CLAUDE_CLAIM_VERIFIER_AGENT_PATH,
|
|
3948
|
+
content: renderTruthmarkClaudeClaimVerifierAgent()
|
|
2513
3949
|
},
|
|
2514
3950
|
{
|
|
2515
|
-
path:
|
|
2516
|
-
content:
|
|
3951
|
+
path: TRUTHMARK_CLAUDE_DOC_REVIEWER_AGENT_PATH,
|
|
3952
|
+
content: renderTruthmarkClaudeDocReviewerAgent()
|
|
2517
3953
|
},
|
|
2518
3954
|
{
|
|
2519
|
-
path:
|
|
2520
|
-
content:
|
|
3955
|
+
path: TRUTHMARK_CLAUDE_DOC_WRITER_AGENT_PATH,
|
|
3956
|
+
content: renderTruthmarkClaudeDocWriterAgent()
|
|
2521
3957
|
}
|
|
2522
3958
|
];
|
|
2523
|
-
return files;
|
|
2524
3959
|
};
|
|
2525
3960
|
var copilotFiles = (config, block) => {
|
|
2526
3961
|
const files = [
|
|
2527
3962
|
...instructionBlockFiles([".github/copilot-instructions.md"], block),
|
|
3963
|
+
...renderTruthmarkSkillPackage({
|
|
3964
|
+
skillPath: ".github/skills/truthmark-structure/SKILL.md",
|
|
3965
|
+
workflowId: "truthmark-structure",
|
|
3966
|
+
host: "github-copilot",
|
|
3967
|
+
config
|
|
3968
|
+
}),
|
|
3969
|
+
...renderTruthmarkSkillPackage({
|
|
3970
|
+
skillPath: ".github/skills/truthmark-document/SKILL.md",
|
|
3971
|
+
workflowId: "truthmark-document",
|
|
3972
|
+
host: "github-copilot",
|
|
3973
|
+
config
|
|
3974
|
+
}),
|
|
3975
|
+
...renderTruthmarkSkillPackage({
|
|
3976
|
+
skillPath: ".github/skills/truthmark-sync/SKILL.md",
|
|
3977
|
+
workflowId: "truthmark-sync",
|
|
3978
|
+
host: "github-copilot",
|
|
3979
|
+
config
|
|
3980
|
+
}),
|
|
3981
|
+
...renderTruthmarkSkillPackage({
|
|
3982
|
+
skillPath: ".github/skills/truthmark-preview/SKILL.md",
|
|
3983
|
+
workflowId: "truthmark-preview",
|
|
3984
|
+
host: "github-copilot",
|
|
3985
|
+
config
|
|
3986
|
+
}),
|
|
3987
|
+
...renderTruthmarkSkillPackage({
|
|
3988
|
+
skillPath: ".github/skills/truthmark-check/SKILL.md",
|
|
3989
|
+
workflowId: "truthmark-check",
|
|
3990
|
+
host: "github-copilot",
|
|
3991
|
+
config
|
|
3992
|
+
}),
|
|
3993
|
+
...renderTruthmarkSkillPackage({
|
|
3994
|
+
skillPath: ".github/skills/truthmark-realize/SKILL.md",
|
|
3995
|
+
workflowId: "truthmark-realize",
|
|
3996
|
+
host: "github-copilot",
|
|
3997
|
+
config
|
|
3998
|
+
}),
|
|
2528
3999
|
{
|
|
2529
4000
|
path: TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH,
|
|
2530
4001
|
content: renderTruthmarkCopilotStructurePrompt(config)
|
|
@@ -2537,6 +4008,10 @@ var copilotFiles = (config, block) => {
|
|
|
2537
4008
|
path: TRUTHMARK_COPILOT_SYNC_PROMPT_PATH,
|
|
2538
4009
|
content: renderTruthmarkCopilotSyncPrompt(config)
|
|
2539
4010
|
},
|
|
4011
|
+
{
|
|
4012
|
+
path: TRUTHMARK_COPILOT_PREVIEW_PROMPT_PATH,
|
|
4013
|
+
content: renderTruthmarkCopilotPreviewPrompt(config)
|
|
4014
|
+
},
|
|
2540
4015
|
{
|
|
2541
4016
|
path: TRUTHMARK_COPILOT_CHECK_PROMPT_PATH,
|
|
2542
4017
|
content: renderTruthmarkCopilotCheckPrompt(config)
|
|
@@ -2544,10 +4019,107 @@ var copilotFiles = (config, block) => {
|
|
|
2544
4019
|
{
|
|
2545
4020
|
path: TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH,
|
|
2546
4021
|
content: renderTruthmarkCopilotRealizePrompt(config)
|
|
4022
|
+
},
|
|
4023
|
+
{
|
|
4024
|
+
path: TRUTHMARK_COPILOT_ROUTE_AUDITOR_AGENT_PATH,
|
|
4025
|
+
content: renderTruthmarkCopilotRouteAuditorAgent()
|
|
4026
|
+
},
|
|
4027
|
+
{
|
|
4028
|
+
path: TRUTHMARK_COPILOT_CLAIM_VERIFIER_AGENT_PATH,
|
|
4029
|
+
content: renderTruthmarkCopilotClaimVerifierAgent()
|
|
4030
|
+
},
|
|
4031
|
+
{
|
|
4032
|
+
path: TRUTHMARK_COPILOT_DOC_REVIEWER_AGENT_PATH,
|
|
4033
|
+
content: renderTruthmarkCopilotDocReviewerAgent()
|
|
4034
|
+
},
|
|
4035
|
+
{
|
|
4036
|
+
path: TRUTHMARK_COPILOT_DOC_WRITER_AGENT_PATH,
|
|
4037
|
+
content: renderTruthmarkCopilotDocWriterAgent()
|
|
2547
4038
|
}
|
|
2548
4039
|
];
|
|
2549
4040
|
return files;
|
|
2550
4041
|
};
|
|
4042
|
+
var geminiFiles = (config, block) => {
|
|
4043
|
+
return [
|
|
4044
|
+
...instructionBlockFiles(["GEMINI.md"], block),
|
|
4045
|
+
...renderTruthmarkSkillPackage({
|
|
4046
|
+
skillPath: ".gemini/skills/truthmark-structure/SKILL.md",
|
|
4047
|
+
workflowId: "truthmark-structure",
|
|
4048
|
+
host: "gemini-cli",
|
|
4049
|
+
config
|
|
4050
|
+
}),
|
|
4051
|
+
...renderTruthmarkSkillPackage({
|
|
4052
|
+
skillPath: ".gemini/skills/truthmark-document/SKILL.md",
|
|
4053
|
+
workflowId: "truthmark-document",
|
|
4054
|
+
host: "gemini-cli",
|
|
4055
|
+
config
|
|
4056
|
+
}),
|
|
4057
|
+
...renderTruthmarkSkillPackage({
|
|
4058
|
+
skillPath: ".gemini/skills/truthmark-sync/SKILL.md",
|
|
4059
|
+
workflowId: "truthmark-sync",
|
|
4060
|
+
host: "gemini-cli",
|
|
4061
|
+
config
|
|
4062
|
+
}),
|
|
4063
|
+
...renderTruthmarkSkillPackage({
|
|
4064
|
+
skillPath: ".gemini/skills/truthmark-preview/SKILL.md",
|
|
4065
|
+
workflowId: "truthmark-preview",
|
|
4066
|
+
host: "gemini-cli",
|
|
4067
|
+
config
|
|
4068
|
+
}),
|
|
4069
|
+
...renderTruthmarkSkillPackage({
|
|
4070
|
+
skillPath: ".gemini/skills/truthmark-check/SKILL.md",
|
|
4071
|
+
workflowId: "truthmark-check",
|
|
4072
|
+
host: "gemini-cli",
|
|
4073
|
+
config
|
|
4074
|
+
}),
|
|
4075
|
+
...renderTruthmarkSkillPackage({
|
|
4076
|
+
skillPath: ".gemini/skills/truthmark-realize/SKILL.md",
|
|
4077
|
+
workflowId: "truthmark-realize",
|
|
4078
|
+
host: "gemini-cli",
|
|
4079
|
+
config
|
|
4080
|
+
}),
|
|
4081
|
+
{
|
|
4082
|
+
path: TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH,
|
|
4083
|
+
content: renderTruthmarkGeminiStructureCommand(config)
|
|
4084
|
+
},
|
|
4085
|
+
{
|
|
4086
|
+
path: TRUTHMARK_GEMINI_DOCUMENT_COMMAND_PATH,
|
|
4087
|
+
content: renderTruthmarkGeminiDocumentCommand(config)
|
|
4088
|
+
},
|
|
4089
|
+
{
|
|
4090
|
+
path: TRUTHMARK_GEMINI_SYNC_COMMAND_PATH,
|
|
4091
|
+
content: renderTruthmarkGeminiSyncCommand(config)
|
|
4092
|
+
},
|
|
4093
|
+
{
|
|
4094
|
+
path: TRUTHMARK_GEMINI_PREVIEW_COMMAND_PATH,
|
|
4095
|
+
content: renderTruthmarkGeminiPreviewCommand(config)
|
|
4096
|
+
},
|
|
4097
|
+
{
|
|
4098
|
+
path: TRUTHMARK_GEMINI_CHECK_COMMAND_PATH,
|
|
4099
|
+
content: renderTruthmarkGeminiCheckCommand(config)
|
|
4100
|
+
},
|
|
4101
|
+
{
|
|
4102
|
+
path: TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH,
|
|
4103
|
+
content: renderTruthmarkGeminiRealizeCommand(config)
|
|
4104
|
+
},
|
|
4105
|
+
{
|
|
4106
|
+
path: TRUTHMARK_GEMINI_ROUTE_AUDITOR_AGENT_PATH,
|
|
4107
|
+
content: renderTruthmarkGeminiRouteAuditorAgent()
|
|
4108
|
+
},
|
|
4109
|
+
{
|
|
4110
|
+
path: TRUTHMARK_GEMINI_CLAIM_VERIFIER_AGENT_PATH,
|
|
4111
|
+
content: renderTruthmarkGeminiClaimVerifierAgent()
|
|
4112
|
+
},
|
|
4113
|
+
{
|
|
4114
|
+
path: TRUTHMARK_GEMINI_DOC_REVIEWER_AGENT_PATH,
|
|
4115
|
+
content: renderTruthmarkGeminiDocReviewerAgent()
|
|
4116
|
+
},
|
|
4117
|
+
{
|
|
4118
|
+
path: TRUTHMARK_GEMINI_DOC_WRITER_AGENT_PATH,
|
|
4119
|
+
content: renderTruthmarkGeminiDocWriterAgent()
|
|
4120
|
+
}
|
|
4121
|
+
];
|
|
4122
|
+
};
|
|
2551
4123
|
var instructionBlockFiles = (paths, block) => {
|
|
2552
4124
|
return paths.map((path12) => ({
|
|
2553
4125
|
path: path12,
|
|
@@ -2560,48 +4132,25 @@ var filesForPlatform = (platform, config, block) => {
|
|
|
2560
4132
|
case "codex":
|
|
2561
4133
|
return codexFiles(config);
|
|
2562
4134
|
case "opencode":
|
|
2563
|
-
return
|
|
4135
|
+
return opencodeFiles(config);
|
|
2564
4136
|
case "claude-code":
|
|
2565
|
-
return
|
|
2566
|
-
...instructionBlockFiles(["CLAUDE.md"], block),
|
|
2567
|
-
...workflowSkillFiles(".claude/skills", config)
|
|
2568
|
-
];
|
|
4137
|
+
return claudeFiles(config, block);
|
|
2569
4138
|
case "github-copilot":
|
|
2570
4139
|
return copilotFiles(config, block);
|
|
2571
4140
|
case "gemini-cli":
|
|
2572
|
-
return
|
|
2573
|
-
...instructionBlockFiles(["GEMINI.md"], block),
|
|
2574
|
-
{
|
|
2575
|
-
path: TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH,
|
|
2576
|
-
content: renderTruthmarkGeminiStructureCommand(config)
|
|
2577
|
-
},
|
|
2578
|
-
{
|
|
2579
|
-
path: TRUTHMARK_GEMINI_DOCUMENT_COMMAND_PATH,
|
|
2580
|
-
content: renderTruthmarkGeminiDocumentCommand(config)
|
|
2581
|
-
},
|
|
2582
|
-
{
|
|
2583
|
-
path: TRUTHMARK_GEMINI_SYNC_COMMAND_PATH,
|
|
2584
|
-
content: renderTruthmarkGeminiSyncCommand(config)
|
|
2585
|
-
},
|
|
2586
|
-
{
|
|
2587
|
-
path: TRUTHMARK_GEMINI_CHECK_COMMAND_PATH,
|
|
2588
|
-
content: renderTruthmarkGeminiCheckCommand(config)
|
|
2589
|
-
},
|
|
2590
|
-
{
|
|
2591
|
-
path: TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH,
|
|
2592
|
-
content: renderTruthmarkGeminiRealizeCommand(config)
|
|
2593
|
-
}
|
|
2594
|
-
];
|
|
4141
|
+
return geminiFiles(config, block);
|
|
2595
4142
|
}
|
|
2596
4143
|
};
|
|
2597
4144
|
var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
|
|
2598
4145
|
const files = [
|
|
2599
4146
|
...instructionBlockFiles(config.instructionTargets, block),
|
|
2600
|
-
...config.platforms.flatMap(
|
|
4147
|
+
...config.platforms.flatMap(
|
|
4148
|
+
(platform) => filesForPlatform(platform, config, block)
|
|
4149
|
+
)
|
|
2601
4150
|
];
|
|
2602
|
-
return Array.from(
|
|
2603
|
-
(
|
|
2604
|
-
);
|
|
4151
|
+
return Array.from(
|
|
4152
|
+
new Map(files.map((file) => [file.path, file])).values()
|
|
4153
|
+
).sort((left, right) => left.path.localeCompare(right.path));
|
|
2605
4154
|
};
|
|
2606
4155
|
|
|
2607
4156
|
// src/init/init.ts
|
|
@@ -2733,7 +4282,7 @@ var diagnosticCategoryForPath = (filePath, config) => {
|
|
|
2733
4282
|
if (filePath === "AGENTS.md") {
|
|
2734
4283
|
return "truth-sync";
|
|
2735
4284
|
}
|
|
2736
|
-
if (filePath === "CLAUDE.md" || filePath === "GEMINI.md" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".github/prompts/truthmark-") || filePath.startsWith(".claude/skills/truthmark-") || filePath.startsWith(".opencode/skills/truthmark-")) {
|
|
4285
|
+
if (filePath === "CLAUDE.md" || filePath === "GEMINI.md" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".github/prompts/truthmark-") || filePath.startsWith(".github/agents/truth-") || filePath.startsWith(".claude/agents/truth-") || filePath.startsWith(".claude/skills/truthmark-") || filePath.startsWith(".opencode/skills/truthmark-") || filePath.startsWith(".opencode/agents/") || filePath.startsWith(".codex/agents/")) {
|
|
2737
4286
|
return "truth-sync";
|
|
2738
4287
|
}
|
|
2739
4288
|
if (filePath.startsWith(".codex/skills/truthmark-structure/")) {
|
|
@@ -2745,6 +4294,9 @@ var diagnosticCategoryForPath = (filePath, config) => {
|
|
|
2745
4294
|
if (filePath.startsWith(".codex/skills/truthmark-sync/")) {
|
|
2746
4295
|
return "truth-sync";
|
|
2747
4296
|
}
|
|
4297
|
+
if (filePath.startsWith(".codex/skills/truthmark-preview/")) {
|
|
4298
|
+
return "truth-sync";
|
|
4299
|
+
}
|
|
2748
4300
|
if (filePath.startsWith(".codex/skills/truthmark-realize/")) {
|
|
2749
4301
|
return "realization";
|
|
2750
4302
|
}
|
|
@@ -3176,12 +4728,12 @@ var checkLinks = async (rootDir, markdownPaths) => {
|
|
|
3176
4728
|
// src/checks/areas.ts
|
|
3177
4729
|
import fs13 from "fs/promises";
|
|
3178
4730
|
import fg5 from "fast-glob";
|
|
3179
|
-
import
|
|
4731
|
+
import micromatch4 from "micromatch";
|
|
3180
4732
|
|
|
3181
4733
|
// src/routing/area-resolver.ts
|
|
3182
4734
|
import fs12 from "fs/promises";
|
|
3183
4735
|
import fg4 from "fast-glob";
|
|
3184
|
-
import
|
|
4736
|
+
import micromatch2 from "micromatch";
|
|
3185
4737
|
var unique = (values) => {
|
|
3186
4738
|
return [...new Set(values)];
|
|
3187
4739
|
};
|
|
@@ -3200,7 +4752,7 @@ var isCodeSurfaceWithinParent = (childPattern, parentPatterns) => {
|
|
|
3200
4752
|
return false;
|
|
3201
4753
|
}
|
|
3202
4754
|
return parentPatterns.some((parentPattern) => {
|
|
3203
|
-
return
|
|
4755
|
+
return micromatch2.isMatch(childPrefix, parentPattern) || micromatch2.isMatch(childPattern, parentPattern);
|
|
3204
4756
|
});
|
|
3205
4757
|
};
|
|
3206
4758
|
var ensureChildPath = async (rootDir, areaFilesRoot, filePath) => {
|
|
@@ -3387,7 +4939,7 @@ var resolveAreaRouting = async (rootDir, config) => {
|
|
|
3387
4939
|
};
|
|
3388
4940
|
|
|
3389
4941
|
// src/sync/classify.ts
|
|
3390
|
-
import
|
|
4942
|
+
import micromatch3 from "micromatch";
|
|
3391
4943
|
var CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
3392
4944
|
".c",
|
|
3393
4945
|
".cc",
|
|
@@ -3507,10 +5059,10 @@ var classifyPath = (filePath, ignorePatterns) => {
|
|
|
3507
5059
|
if (normalizedPath.startsWith(".truthmark/")) {
|
|
3508
5060
|
return "derived";
|
|
3509
5061
|
}
|
|
3510
|
-
if (normalizedPath.startsWith(".claude/") || normalizedPath.startsWith(".codex/") || normalizedPath.startsWith(".gemini/commands/") || normalizedPath.startsWith(".opencode/") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath.startsWith(".github/prompts/truthmark-") || normalizedPath === "AGENTS.md" || normalizedPath === "CLAUDE.md" || normalizedPath === "GEMINI.md" || normalizedPath.startsWith(".gemini/commands/truthmark/")) {
|
|
5062
|
+
if (normalizedPath.startsWith(".claude/") || normalizedPath.startsWith(".codex/") || normalizedPath.startsWith(".gemini/commands/") || normalizedPath.startsWith(".opencode/") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath.startsWith(".github/agents/truth-") || normalizedPath.startsWith(".github/prompts/truthmark-") || normalizedPath === "AGENTS.md" || normalizedPath === "CLAUDE.md" || normalizedPath === "GEMINI.md" || normalizedPath.startsWith(".gemini/commands/truthmark/")) {
|
|
3511
5063
|
return "derived";
|
|
3512
5064
|
}
|
|
3513
|
-
if (ignorePatterns.length > 0 &&
|
|
5065
|
+
if (ignorePatterns.length > 0 && micromatch3.isMatch(normalizedPath, ignorePatterns)) {
|
|
3514
5066
|
return "ignored";
|
|
3515
5067
|
}
|
|
3516
5068
|
if (normalizedPath.toLowerCase().endsWith(".md")) {
|
|
@@ -3806,7 +5358,7 @@ var checkAreas = async (rootDir, config) => {
|
|
|
3806
5358
|
}
|
|
3807
5359
|
for (const codeFile of codeFiles.sort()) {
|
|
3808
5360
|
const matched = areaCoverage.some(
|
|
3809
|
-
(entry) => entry.valid && entry.patterns.some((pattern) =>
|
|
5361
|
+
(entry) => entry.valid && entry.patterns.some((pattern) => micromatch4.isMatch(codeFile, pattern))
|
|
3810
5362
|
);
|
|
3811
5363
|
if (!matched) {
|
|
3812
5364
|
diagnostics.push({
|
|
@@ -3837,7 +5389,7 @@ var checkAreas = async (rootDir, config) => {
|
|
|
3837
5389
|
|
|
3838
5390
|
// src/checks/decisions.ts
|
|
3839
5391
|
import fs14 from "fs/promises";
|
|
3840
|
-
import
|
|
5392
|
+
import micromatch5 from "micromatch";
|
|
3841
5393
|
var REQUIRED_DECISION_HEADINGS = ["Scope", "Product Decisions", "Rationale"];
|
|
3842
5394
|
var isTruthDocumentKind3 = (value) => {
|
|
3843
5395
|
return TRUTH_DOCUMENT_KINDS.includes(value);
|
|
@@ -3901,7 +5453,7 @@ var decisionTruthGlobs = (config) => {
|
|
|
3901
5453
|
].filter((root) => Boolean(root)).map((root) => `${root}/**/*.md`);
|
|
3902
5454
|
};
|
|
3903
5455
|
var isDecisionTruthCandidate = (config, filePath) => {
|
|
3904
|
-
return !filePath.endsWith("/README.md") &&
|
|
5456
|
+
return !filePath.endsWith("/README.md") && micromatch5.isMatch(filePath, decisionTruthGlobs(config));
|
|
3905
5457
|
};
|
|
3906
5458
|
var checkDecisionSections = async (rootDir, config, markdownPaths, truthDocumentEntries = []) => {
|
|
3907
5459
|
const diagnostics = [];
|
|
@@ -4020,7 +5572,7 @@ var checkGeneratedSurfaces = async (rootDir, config) => {
|
|
|
4020
5572
|
|
|
4021
5573
|
// src/impact/build.ts
|
|
4022
5574
|
import path9 from "path";
|
|
4023
|
-
import
|
|
5575
|
+
import micromatch7 from "micromatch";
|
|
4024
5576
|
|
|
4025
5577
|
// src/repo-index/build.ts
|
|
4026
5578
|
import fs18 from "fs/promises";
|
|
@@ -4032,7 +5584,7 @@ import path5 from "path";
|
|
|
4032
5584
|
import { execa as execa2 } from "execa";
|
|
4033
5585
|
import fg6 from "fast-glob";
|
|
4034
5586
|
import matter2 from "gray-matter";
|
|
4035
|
-
import
|
|
5587
|
+
import micromatch6 from "micromatch";
|
|
4036
5588
|
var languageByExtension = /* @__PURE__ */ new Map([
|
|
4037
5589
|
[".ts", "typescript"],
|
|
4038
5590
|
[".tsx", "typescript"],
|
|
@@ -4109,7 +5661,7 @@ var gitDiscoverableFiles = async (rootDir) => {
|
|
|
4109
5661
|
return result.stdout.split("\n").map((line) => normalizePath2(line.trim())).filter((line) => line.length > 0);
|
|
4110
5662
|
};
|
|
4111
5663
|
var isIgnoredPath = (filePath, ignore) => {
|
|
4112
|
-
return
|
|
5664
|
+
return micromatch6.isMatch(filePath, [...defaultIgnore, ...ignore]);
|
|
4113
5665
|
};
|
|
4114
5666
|
var discoverRepoFiles = async (rootDir, ignore) => {
|
|
4115
5667
|
const discoveredFiles = await gitDiscoverableFiles(rootDir) ?? await fg6(["**/*"], {
|
|
@@ -4123,6 +5675,18 @@ var discoverRepoFiles = async (rootDir, ignore) => {
|
|
|
4123
5675
|
const docs = [];
|
|
4124
5676
|
const tests = [];
|
|
4125
5677
|
for (const filePath of discoveredFiles.filter((entry) => !isIgnoredPath(entry, ignore)).sort()) {
|
|
5678
|
+
let stat;
|
|
5679
|
+
try {
|
|
5680
|
+
stat = await fs16.stat(path5.join(rootDir, filePath));
|
|
5681
|
+
} catch (error) {
|
|
5682
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
5683
|
+
continue;
|
|
5684
|
+
}
|
|
5685
|
+
throw error;
|
|
5686
|
+
}
|
|
5687
|
+
if (!stat.isFile()) {
|
|
5688
|
+
continue;
|
|
5689
|
+
}
|
|
4126
5690
|
const extension = path5.posix.extname(filePath);
|
|
4127
5691
|
const kind = fileKind(filePath, ignore);
|
|
4128
5692
|
files.push({
|
|
@@ -4528,7 +6092,7 @@ var readBaseFile = async (cwd, base, filePath) => {
|
|
|
4528
6092
|
// src/impact/build.ts
|
|
4529
6093
|
var uniqueSorted = (values) => [...new Set(values)].sort();
|
|
4530
6094
|
var routeMatchesFile = (route, filePath) => {
|
|
4531
|
-
return route.codeSurface.some((pattern) =>
|
|
6095
|
+
return route.codeSurface.some((pattern) => micromatch7.isMatch(filePath, pattern));
|
|
4532
6096
|
};
|
|
4533
6097
|
var routeOwnsTruthDoc = (route, filePath) => {
|
|
4534
6098
|
return route.truthDocs.includes(filePath);
|
|
@@ -5149,6 +6713,319 @@ var renderContextPackMarkdown = (pack) => {
|
|
|
5149
6713
|
`;
|
|
5150
6714
|
};
|
|
5151
6715
|
|
|
6716
|
+
// src/cli/handlers.ts
|
|
6717
|
+
import fs23 from "fs/promises";
|
|
6718
|
+
|
|
6719
|
+
// src/agents/workflow-helper-validation.ts
|
|
6720
|
+
import { parse as parseYaml2 } from "yaml";
|
|
6721
|
+
var escapeRegex = (value) => value.split("").map((char) => ".+*?^$()[]{}|\\".includes(char) ? `\\${char}` : char).join("");
|
|
6722
|
+
var hasLabel = (text, label) => {
|
|
6723
|
+
const escaped = escapeRegex(label);
|
|
6724
|
+
return new RegExp(String.raw`(^|\n)\s*(?:#{1,6}\s*)?${escaped}\s*:?\s*(\n|$)`, "iu").test(
|
|
6725
|
+
text
|
|
6726
|
+
);
|
|
6727
|
+
};
|
|
6728
|
+
var getSection = (text, label) => {
|
|
6729
|
+
const lines = text.split(/\r?\n/u);
|
|
6730
|
+
const labelPattern = new RegExp(String.raw`^(?:#{1,6}\s*)?${escapeRegex(label)}\s*:?\s*$`, "iu");
|
|
6731
|
+
const sectionHeaderPattern = /^(?:#{1,6}\s*)?[A-Z][A-Za-z0-9 ]+:\s*$/u;
|
|
6732
|
+
const startIndex = lines.findIndex((line) => labelPattern.test(line));
|
|
6733
|
+
if (startIndex === -1) {
|
|
6734
|
+
return null;
|
|
6735
|
+
}
|
|
6736
|
+
const nextSectionOffset = lines.slice(startIndex + 1).findIndex((line) => sectionHeaderPattern.test(line));
|
|
6737
|
+
const endIndex = nextSectionOffset === -1 ? lines.length : startIndex + 1 + nextSectionOffset;
|
|
6738
|
+
return lines.slice(startIndex + 1, endIndex).join("\n").trim();
|
|
6739
|
+
};
|
|
6740
|
+
var requireBulletSection = (text, label, errors, checks) => {
|
|
6741
|
+
const section = getSection(text, label);
|
|
6742
|
+
if (section === null) {
|
|
6743
|
+
errors.push(`missing required section: ${label}`);
|
|
6744
|
+
return;
|
|
6745
|
+
}
|
|
6746
|
+
if (!/^-\s+\S/mu.test(section)) {
|
|
6747
|
+
errors.push(`${label} must include at least one bullet`);
|
|
6748
|
+
return;
|
|
6749
|
+
}
|
|
6750
|
+
checks.push(label);
|
|
6751
|
+
};
|
|
6752
|
+
var validateEvidenceChecked = (text, errors, checks) => {
|
|
6753
|
+
const section = getSection(text, "Evidence checked");
|
|
6754
|
+
if (section === null || section === "") {
|
|
6755
|
+
errors.push("Evidence checked must include at least one structured entry");
|
|
6756
|
+
return;
|
|
6757
|
+
}
|
|
6758
|
+
const entries = section.split(/\n(?=-\s+)/u).map((entry) => entry.trim()).filter(Boolean);
|
|
6759
|
+
if (entries.length === 0) {
|
|
6760
|
+
errors.push("Evidence checked must include at least one structured entry");
|
|
6761
|
+
return;
|
|
6762
|
+
}
|
|
6763
|
+
const entryPattern = /^- Claim:\s*\S[^\n]*\n {2,}Evidence:\s*\S[^\n]*\n {2,}Result:\s*(supported|narrowed|removed|blocked)\s*$/iu;
|
|
6764
|
+
for (const [index, entry] of entries.entries()) {
|
|
6765
|
+
if (!entryPattern.test(entry)) {
|
|
6766
|
+
errors.push(
|
|
6767
|
+
`Evidence checked entry ${index + 1} must match '- Claim: ...' followed by indented 'Evidence: ...' and 'Result: supported | narrowed | removed | blocked'`
|
|
6768
|
+
);
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6771
|
+
if (errors.length === 0) {
|
|
6772
|
+
checks.push(
|
|
6773
|
+
"Evidence checked entries include Claim:, Evidence:, and Result: supported | narrowed | removed | blocked"
|
|
6774
|
+
);
|
|
6775
|
+
}
|
|
6776
|
+
};
|
|
6777
|
+
var validateHelperScriptEntries = (entries, requiredHelpers, errors, checks) => {
|
|
6778
|
+
if (entries === void 0 || entries.length === 0) {
|
|
6779
|
+
errors.push("Helper scripts must include status for optional helpers");
|
|
6780
|
+
return;
|
|
6781
|
+
}
|
|
6782
|
+
const statusPattern = /^(?:-\s*)?([a-z0-9-]+):\s*(?:ran,\s*passed|skipped,\s*\S.*)$/iu;
|
|
6783
|
+
const validHelperIds = /* @__PURE__ */ new Set();
|
|
6784
|
+
for (const entry of entries) {
|
|
6785
|
+
const match = entry.trim().match(statusPattern);
|
|
6786
|
+
if (match === null) {
|
|
6787
|
+
errors.push(
|
|
6788
|
+
"Helper scripts entries must match '- helper-id: ran, passed' or '- helper-id: skipped, reason'; ran, failed is not valid for completed reports"
|
|
6789
|
+
);
|
|
6790
|
+
continue;
|
|
6791
|
+
}
|
|
6792
|
+
validHelperIds.add(match[1].toLowerCase());
|
|
6793
|
+
}
|
|
6794
|
+
for (const helperId of requiredHelpers) {
|
|
6795
|
+
if (!validHelperIds.has(helperId.toLowerCase())) {
|
|
6796
|
+
errors.push(`missing Helper scripts status: ${helperId}`);
|
|
6797
|
+
}
|
|
6798
|
+
}
|
|
6799
|
+
if (errors.length === 0) {
|
|
6800
|
+
checks.push(`Helper scripts statuses include ${requiredHelpers.join(", ")}`);
|
|
6801
|
+
}
|
|
6802
|
+
};
|
|
6803
|
+
var validateHelperScripts = (text, requiredHelpers, errors, checks) => {
|
|
6804
|
+
const section = getSection(text, "Helper scripts");
|
|
6805
|
+
const entries = section?.split(/\n/u).map((entry) => entry.trim()).filter(Boolean);
|
|
6806
|
+
validateHelperScriptEntries(entries, requiredHelpers, errors, checks);
|
|
6807
|
+
};
|
|
6808
|
+
var validateTruthSyncReportText = (text) => {
|
|
6809
|
+
const helper = "validate-sync-report";
|
|
6810
|
+
const statusMatch = text.match(/^\s*Truth Sync:\s*(completed|blocked|skipped)\b/imu);
|
|
6811
|
+
if (statusMatch === null) {
|
|
6812
|
+
return {
|
|
6813
|
+
ok: false,
|
|
6814
|
+
helper,
|
|
6815
|
+
errors: ["missing Truth Sync status: expected completed, blocked, or skipped"]
|
|
6816
|
+
};
|
|
6817
|
+
}
|
|
6818
|
+
const status = statusMatch[1].toLowerCase();
|
|
6819
|
+
const checks = [`status: ${status}`];
|
|
6820
|
+
const errors = [];
|
|
6821
|
+
if (status === "completed") {
|
|
6822
|
+
try {
|
|
6823
|
+
const report = parseTruthSyncReport(text.trimStart());
|
|
6824
|
+
for (const [label, items] of [
|
|
6825
|
+
["Changed code reviewed", report.changedCode],
|
|
6826
|
+
["Ownership reviewed", report.ownershipReviewed],
|
|
6827
|
+
["Truth docs updated", report.truthDocsUpdated],
|
|
6828
|
+
["Notes", report.notes]
|
|
6829
|
+
]) {
|
|
6830
|
+
if (items.length === 0) {
|
|
6831
|
+
errors.push(`${label} must include at least one bullet`);
|
|
6832
|
+
} else {
|
|
6833
|
+
checks.push(label);
|
|
6834
|
+
}
|
|
6835
|
+
}
|
|
6836
|
+
if (report.evidenceChecked.length === 0) {
|
|
6837
|
+
errors.push("Evidence checked must include at least one structured entry");
|
|
6838
|
+
} else {
|
|
6839
|
+
checks.push(
|
|
6840
|
+
"Evidence checked entries include Claim:, Evidence:, and Result: supported | narrowed | removed | blocked"
|
|
6841
|
+
);
|
|
6842
|
+
}
|
|
6843
|
+
validateHelperScriptEntries(
|
|
6844
|
+
report.helperScripts,
|
|
6845
|
+
["validate-write-lease"],
|
|
6846
|
+
errors,
|
|
6847
|
+
checks
|
|
6848
|
+
);
|
|
6849
|
+
} catch (error) {
|
|
6850
|
+
errors.push(error instanceof Error ? error.message : "invalid Truth Sync report");
|
|
6851
|
+
}
|
|
6852
|
+
} else if (status === "skipped") {
|
|
6853
|
+
requireBulletSection(text, "Reason", errors, checks);
|
|
6854
|
+
} else if (status === "blocked") {
|
|
6855
|
+
requireBulletSection(text, "Reason", errors, checks);
|
|
6856
|
+
requireBulletSection(text, "Files requiring manual review", errors, checks);
|
|
6857
|
+
requireBulletSection(text, "Next action", errors, checks);
|
|
6858
|
+
}
|
|
6859
|
+
return errors.length > 0 ? { ok: false, helper, errors } : { ok: true, helper, checks };
|
|
6860
|
+
};
|
|
6861
|
+
var validateTruthDocumentReportText = (text) => {
|
|
6862
|
+
const helper = "validate-document-report";
|
|
6863
|
+
const statusMatch = text.match(/^\s*Truth Document:\s*(completed|blocked)\b/imu);
|
|
6864
|
+
if (statusMatch === null) {
|
|
6865
|
+
return {
|
|
6866
|
+
ok: false,
|
|
6867
|
+
helper,
|
|
6868
|
+
errors: ["missing Truth Document status: expected completed or blocked"]
|
|
6869
|
+
};
|
|
6870
|
+
}
|
|
6871
|
+
const status = statusMatch[1].toLowerCase();
|
|
6872
|
+
const checks = [`status: ${status}`];
|
|
6873
|
+
const errors = [];
|
|
6874
|
+
if (status === "completed") {
|
|
6875
|
+
for (const label of ["Implementation reviewed", "Ownership reviewed", "Notes"]) {
|
|
6876
|
+
requireBulletSection(text, label, errors, checks);
|
|
6877
|
+
}
|
|
6878
|
+
if (hasLabel(text, "Evidence checked")) {
|
|
6879
|
+
checks.push("Evidence checked");
|
|
6880
|
+
} else {
|
|
6881
|
+
errors.push("missing required section: Evidence checked");
|
|
6882
|
+
}
|
|
6883
|
+
if (hasLabel(text, "Helper scripts")) {
|
|
6884
|
+
checks.push("Helper scripts");
|
|
6885
|
+
} else {
|
|
6886
|
+
errors.push("missing required section: Helper scripts");
|
|
6887
|
+
}
|
|
6888
|
+
const truthDocsUpdated = getSection(text, "Truth docs updated");
|
|
6889
|
+
const truthDocsCreated = getSection(text, "Truth docs created");
|
|
6890
|
+
if (truthDocsUpdated === null && truthDocsCreated === null) {
|
|
6891
|
+
errors.push("missing required section: Truth docs updated or Truth docs created");
|
|
6892
|
+
} else if (![truthDocsUpdated, truthDocsCreated].some(
|
|
6893
|
+
(section) => section !== null && /^-\s+\S/mu.test(section)
|
|
6894
|
+
)) {
|
|
6895
|
+
errors.push("Truth docs updated or Truth docs created must include at least one bullet");
|
|
6896
|
+
} else {
|
|
6897
|
+
checks.push("Truth docs updated or created");
|
|
6898
|
+
}
|
|
6899
|
+
validateEvidenceChecked(text, errors, checks);
|
|
6900
|
+
validateHelperScripts(text, ["validate-write-lease"], errors, checks);
|
|
6901
|
+
} else if (status === "blocked") {
|
|
6902
|
+
requireBulletSection(text, "Reason", errors, checks);
|
|
6903
|
+
}
|
|
6904
|
+
return errors.length > 0 ? { ok: false, helper, errors } : { ok: true, helper, checks };
|
|
6905
|
+
};
|
|
6906
|
+
var cleanPathValue = (value) => value.trim().replace(/^["']|["']$/gu, "");
|
|
6907
|
+
var normalizePath5 = (value) => cleanPathValue(value).replace(/^\.\//u, "");
|
|
6908
|
+
var windowsDriveAbsolutePattern = /^[A-Za-z]:[\\/]/u;
|
|
6909
|
+
var uncPathPattern = /^[/\\]{2}[^/\\]+[/\\]+[^/\\]+/u;
|
|
6910
|
+
var isUnsafePathValue = (value) => {
|
|
6911
|
+
const cleanValue = cleanPathValue(value);
|
|
6912
|
+
const pathValue = cleanValue.endsWith("/**") ? cleanValue.slice(0, -3) : cleanValue;
|
|
6913
|
+
return pathValue.startsWith("/") || pathValue.startsWith("\\") || windowsDriveAbsolutePattern.test(pathValue) || uncPathPattern.test(pathValue) || pathValue.split(/[\\/]+/u).includes("..");
|
|
6914
|
+
};
|
|
6915
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6916
|
+
var findWriteLeaseRecord = (value) => {
|
|
6917
|
+
if (!isRecord(value)) {
|
|
6918
|
+
return null;
|
|
6919
|
+
}
|
|
6920
|
+
if (Object.prototype.hasOwnProperty.call(value, "allowedWrites") || Object.prototype.hasOwnProperty.call(value, "forbiddenWrites")) {
|
|
6921
|
+
return value;
|
|
6922
|
+
}
|
|
6923
|
+
for (const nestedKey of ["writeLease", "lease"]) {
|
|
6924
|
+
const nested = value[nestedKey];
|
|
6925
|
+
if (isRecord(nested)) {
|
|
6926
|
+
return nested;
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6929
|
+
return value;
|
|
6930
|
+
};
|
|
6931
|
+
var readStringArray = (record, field, errors) => {
|
|
6932
|
+
const value = record[field];
|
|
6933
|
+
if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
|
|
6934
|
+
errors.push(`${field} must be an array of strings`);
|
|
6935
|
+
return [];
|
|
6936
|
+
}
|
|
6937
|
+
return value;
|
|
6938
|
+
};
|
|
6939
|
+
var parseListFields = (text) => {
|
|
6940
|
+
const errors = [];
|
|
6941
|
+
let parsed;
|
|
6942
|
+
try {
|
|
6943
|
+
parsed = parseYaml2(text);
|
|
6944
|
+
} catch (error) {
|
|
6945
|
+
return {
|
|
6946
|
+
allowedWrites: [],
|
|
6947
|
+
forbiddenWrites: [],
|
|
6948
|
+
errors: [
|
|
6949
|
+
`manual-validation required: invalid write lease YAML${error instanceof Error ? `: ${error.message}` : ""}`
|
|
6950
|
+
]
|
|
6951
|
+
};
|
|
6952
|
+
}
|
|
6953
|
+
const record = findWriteLeaseRecord(parsed);
|
|
6954
|
+
if (record === null) {
|
|
6955
|
+
return {
|
|
6956
|
+
allowedWrites: [],
|
|
6957
|
+
forbiddenWrites: [],
|
|
6958
|
+
errors: ["write lease YAML must be an object"]
|
|
6959
|
+
};
|
|
6960
|
+
}
|
|
6961
|
+
return {
|
|
6962
|
+
allowedWrites: readStringArray(record, "allowedWrites", errors),
|
|
6963
|
+
forbiddenWrites: readStringArray(record, "forbiddenWrites", errors),
|
|
6964
|
+
errors
|
|
6965
|
+
};
|
|
6966
|
+
};
|
|
6967
|
+
var isSupportedPattern = (pattern) => {
|
|
6968
|
+
const withoutTrailingGlob = pattern.endsWith("/**") ? pattern.slice(0, -3) : pattern;
|
|
6969
|
+
return !/[?*[\]{}]/u.test(withoutTrailingGlob);
|
|
6970
|
+
};
|
|
6971
|
+
var matchesPattern = (filePath, pattern) => {
|
|
6972
|
+
if (pattern.endsWith("/**")) {
|
|
6973
|
+
const prefix = pattern.slice(0, -3).replace(/\/+$/u, "");
|
|
6974
|
+
return filePath === prefix || filePath.startsWith(`${prefix}/`);
|
|
6975
|
+
}
|
|
6976
|
+
return filePath === pattern;
|
|
6977
|
+
};
|
|
6978
|
+
var validateWriteLeaseText = (leaseText, changedText) => {
|
|
6979
|
+
const helper = "validate-write-lease";
|
|
6980
|
+
const parsed = parseListFields(leaseText);
|
|
6981
|
+
const rawAllowedWrites = parsed.allowedWrites.map(cleanPathValue).filter(Boolean);
|
|
6982
|
+
const rawForbiddenWrites = parsed.forbiddenWrites.map(cleanPathValue).filter(Boolean);
|
|
6983
|
+
const rawChangedFiles = changedText.split(/\r?\n/u).map(cleanPathValue).filter(Boolean);
|
|
6984
|
+
const allowedWrites = rawAllowedWrites.map(normalizePath5).filter(Boolean);
|
|
6985
|
+
const forbiddenWrites = rawForbiddenWrites.map(normalizePath5).filter(Boolean);
|
|
6986
|
+
const changedFiles = rawChangedFiles.map(normalizePath5).filter(Boolean);
|
|
6987
|
+
const checks = [];
|
|
6988
|
+
const errors = [...parsed.errors];
|
|
6989
|
+
for (const pattern of rawAllowedWrites) {
|
|
6990
|
+
if (isUnsafePathValue(pattern)) {
|
|
6991
|
+
errors.push(`invalid allowedWrites path: ${pattern}`);
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6994
|
+
for (const pattern of rawForbiddenWrites) {
|
|
6995
|
+
if (isUnsafePathValue(pattern)) {
|
|
6996
|
+
errors.push(`invalid forbiddenWrites path: ${pattern}`);
|
|
6997
|
+
}
|
|
6998
|
+
}
|
|
6999
|
+
for (const filePath of rawChangedFiles) {
|
|
7000
|
+
if (isUnsafePathValue(filePath)) {
|
|
7001
|
+
errors.push(`invalid changed file path: ${filePath}`);
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
for (const pattern of [...allowedWrites, ...forbiddenWrites]) {
|
|
7005
|
+
if (!isSupportedPattern(pattern)) {
|
|
7006
|
+
errors.push(`manual-validation required: unsupported write pattern ${pattern}`);
|
|
7007
|
+
}
|
|
7008
|
+
}
|
|
7009
|
+
if (allowedWrites.length === 0) {
|
|
7010
|
+
errors.push("manual-validation required: no allowedWrites entries found");
|
|
7011
|
+
}
|
|
7012
|
+
if (errors.length === 0) {
|
|
7013
|
+
for (const filePath of changedFiles) {
|
|
7014
|
+
if (!allowedWrites.some((pattern) => matchesPattern(filePath, pattern))) {
|
|
7015
|
+
errors.push(`${filePath} is outside allowedWrites`);
|
|
7016
|
+
continue;
|
|
7017
|
+
}
|
|
7018
|
+
const forbiddenPattern = forbiddenWrites.find((pattern) => matchesPattern(filePath, pattern));
|
|
7019
|
+
if (forbiddenPattern !== void 0) {
|
|
7020
|
+
errors.push(`${filePath} matches forbiddenWrites pattern ${forbiddenPattern}`);
|
|
7021
|
+
continue;
|
|
7022
|
+
}
|
|
7023
|
+
checks.push(filePath);
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
return errors.length > 0 ? { ok: false, helper, errors } : { ok: true, helper, checks };
|
|
7027
|
+
};
|
|
7028
|
+
|
|
5152
7029
|
// src/cli/handlers.ts
|
|
5153
7030
|
var runConfig2 = async (options) => {
|
|
5154
7031
|
return runConfig(process.cwd(), options);
|
|
@@ -5205,6 +7082,33 @@ var isContextPackWorkflow = (value) => {
|
|
|
5205
7082
|
var isContextPackFormat = (value) => {
|
|
5206
7083
|
return value === void 0 || value === "json" || value === "markdown";
|
|
5207
7084
|
};
|
|
7085
|
+
var readHelperFile = async (filePath, helper) => {
|
|
7086
|
+
try {
|
|
7087
|
+
return await fs23.readFile(filePath, "utf8");
|
|
7088
|
+
} catch (error) {
|
|
7089
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7090
|
+
return { ok: false, helper, errors: [`could not read file: ${message}`] };
|
|
7091
|
+
}
|
|
7092
|
+
};
|
|
7093
|
+
var runValidateSyncReport = async (reportFile) => {
|
|
7094
|
+
const text = await readHelperFile(reportFile, "validate-sync-report");
|
|
7095
|
+
return typeof text === "string" ? validateTruthSyncReportText(text) : text;
|
|
7096
|
+
};
|
|
7097
|
+
var runValidateDocumentReport = async (reportFile) => {
|
|
7098
|
+
const text = await readHelperFile(reportFile, "validate-document-report");
|
|
7099
|
+
return typeof text === "string" ? validateTruthDocumentReportText(text) : text;
|
|
7100
|
+
};
|
|
7101
|
+
var runValidateWriteLease = async (leaseFile, changedFilesFile) => {
|
|
7102
|
+
const leaseText = await readHelperFile(leaseFile, "validate-write-lease");
|
|
7103
|
+
if (typeof leaseText !== "string") {
|
|
7104
|
+
return leaseText;
|
|
7105
|
+
}
|
|
7106
|
+
const changedText = await readHelperFile(changedFilesFile, "validate-write-lease");
|
|
7107
|
+
if (typeof changedText !== "string") {
|
|
7108
|
+
return changedText;
|
|
7109
|
+
}
|
|
7110
|
+
return validateWriteLeaseText(leaseText, changedText);
|
|
7111
|
+
};
|
|
5208
7112
|
var runContext = async (options) => {
|
|
5209
7113
|
if (!isContextPackWorkflow(options.workflow)) {
|
|
5210
7114
|
return {
|
|
@@ -5261,6 +7165,28 @@ var writeContextResult = (result, options) => {
|
|
|
5261
7165
|
}
|
|
5262
7166
|
writeResult(result, options);
|
|
5263
7167
|
};
|
|
7168
|
+
var renderValidationHuman = (result) => {
|
|
7169
|
+
if (result.ok === true) {
|
|
7170
|
+
return [`${result.helper}: ok`, ...result.checks.map((check) => `- ${check}`)].join("\n");
|
|
7171
|
+
}
|
|
7172
|
+
return [`${result.helper}: failed`, ...result.errors.map((error) => `- ${error}`)].join("\n");
|
|
7173
|
+
};
|
|
7174
|
+
var toValidationCommandResult = (command, result) => ({
|
|
7175
|
+
command,
|
|
7176
|
+
summary: result.ok ? "Validation passed" : "Validation failed",
|
|
7177
|
+
diagnostics: [],
|
|
7178
|
+
data: {
|
|
7179
|
+
validation: result
|
|
7180
|
+
}
|
|
7181
|
+
});
|
|
7182
|
+
var writeValidationResult = (command, result, options) => {
|
|
7183
|
+
const output = options.json ? renderJson(toValidationCommandResult(command, result)) : renderValidationHuman(result);
|
|
7184
|
+
process.stdout.write(`${output}
|
|
7185
|
+
`);
|
|
7186
|
+
if (!result.ok) {
|
|
7187
|
+
process.exitCode = 1;
|
|
7188
|
+
}
|
|
7189
|
+
};
|
|
5264
7190
|
var addJsonOption = (command) => {
|
|
5265
7191
|
return command.option("--json", "Render command output as JSON");
|
|
5266
7192
|
};
|
|
@@ -5304,6 +7230,32 @@ var buildProgram = () => {
|
|
|
5304
7230
|
options
|
|
5305
7231
|
);
|
|
5306
7232
|
});
|
|
7233
|
+
const validate = program.command("validate").description("Run optional Truthmark workflow helper validators from the installed CLI.");
|
|
7234
|
+
addJsonOption(
|
|
7235
|
+
validate.command("sync-report").description("Validate a Truth Sync report file.").argument("<report-file>", "Truth Sync report file")
|
|
7236
|
+
).action(async (reportFile, options) => {
|
|
7237
|
+
writeValidationResult("validate sync-report", await runValidateSyncReport(reportFile), options);
|
|
7238
|
+
});
|
|
7239
|
+
addJsonOption(
|
|
7240
|
+
validate.command("document-report").description("Validate a Truth Document report file.").argument("<report-file>", "Truth Document report file")
|
|
7241
|
+
).action(async (reportFile, options) => {
|
|
7242
|
+
writeValidationResult(
|
|
7243
|
+
"validate document-report",
|
|
7244
|
+
await runValidateDocumentReport(reportFile),
|
|
7245
|
+
options
|
|
7246
|
+
);
|
|
7247
|
+
});
|
|
7248
|
+
addJsonOption(
|
|
7249
|
+
validate.command("write-lease").description("Validate a workflow write lease or worker report against changed files.").argument("<lease-or-report-file>", "Lease or worker report file").argument("<changed-files-file>", "Newline-separated changed file list")
|
|
7250
|
+
).action(
|
|
7251
|
+
async (leaseOrReportFile, changedFilesFile, options) => {
|
|
7252
|
+
writeValidationResult(
|
|
7253
|
+
"validate write-lease",
|
|
7254
|
+
await runValidateWriteLease(leaseOrReportFile, changedFilesFile),
|
|
7255
|
+
options
|
|
7256
|
+
);
|
|
7257
|
+
}
|
|
7258
|
+
);
|
|
5307
7259
|
return program;
|
|
5308
7260
|
};
|
|
5309
7261
|
|