truthmark 1.2.0 → 1.2.2

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/dist/main.js CHANGED
@@ -43,7 +43,7 @@ var renderJson = (result) => {
43
43
  };
44
44
 
45
45
  // src/config/command.ts
46
- import fs3 from "fs/promises";
46
+ import fs4 from "fs/promises";
47
47
 
48
48
  // src/fs/paths.ts
49
49
  import path from "path";
@@ -234,11 +234,16 @@ var SUPPORTED_PLATFORMS = [
234
234
  "codex",
235
235
  "opencode",
236
236
  "claude-code",
237
- "cursor",
238
237
  "github-copilot",
239
238
  "gemini-cli"
240
239
  ];
241
- var DEFAULT_PLATFORMS = ["codex", "opencode", "claude-code"];
240
+ var DEFAULT_PLATFORMS = [
241
+ "codex",
242
+ "opencode",
243
+ "claude-code",
244
+ "github-copilot",
245
+ "gemini-cli"
246
+ ];
242
247
  var truthmarkConfigSchema = {
243
248
  type: "object",
244
249
  additionalProperties: false,
@@ -423,32 +428,34 @@ var createDefaultConfig = () => ({
423
428
  });
424
429
 
425
430
  // src/version.ts
426
- var TRUTHMARK_VERSION = "1.2.0";
431
+ import fs3 from "fs";
432
+ var packageJson = JSON.parse(
433
+ fs3.readFileSync(new URL("../package.json", import.meta.url), "utf8")
434
+ );
435
+ var TRUTHMARK_VERSION = packageJson.version;
427
436
 
428
437
  // src/templates/init-files.ts
429
438
  var renderConfigTemplate = () => {
430
439
  return stringify(createDefaultRawConfig());
431
440
  };
432
441
  var renderTruthmarkTemplate = () => {
433
- return `# Truthmark
442
+ return `---
443
+ status: active
444
+ doc_type: workflow-contract
445
+ last_reviewed: 2026-05-10
446
+ source_of_truth:
447
+ - .truthmark/config.yml
448
+ ---
449
+
450
+ # Truthmark
434
451
 
435
452
  Markdown in the current checkout is authoritative for this branch.
436
453
 
437
454
  Installed workflow surfaces include a Truthmark ${TRUTHMARK_VERSION} version marker. After upgrading Truthmark, rerun \`truthmark init\` and review generated workflow diffs.
438
455
 
439
- Truth Sync runs automatically before finishing when functional code changes exist, and updates truth docs.
440
-
441
- Truth Sync can also be invoked explicitly through installed truthmark-sync skill surfaces.
442
-
443
- Truth Structure designs or repairs docs/truthmark/areas.md through installed truthmark-structure skill surfaces.
444
-
445
- Truth Realize is manual and updates code to match truth docs.
446
-
447
- Truth Check audits repository truth health through installed truthmark-check skill surfaces.
448
-
449
- Truth Sync may create or extend mapped truth docs when implementation would otherwise remain undocumented.
456
+ Workflow runtime lives in installed skills and managed instruction blocks. Agents inspect the checkout directly; \`truthmark check\` is optional validation.
450
457
 
451
- Truth Realize never edits truth docs.
458
+ Truth Sync follows code; Truth Realize follows docs. Truth Sync may update mapped truth docs; Truth Realize never edits truth docs or routing.
452
459
  `;
453
460
  };
454
461
  var titleCase = (value) => {
@@ -459,6 +466,14 @@ var renderHierarchicalAreasIndexTemplate = (config) => {
459
466
  const childPath = `${config.docs.routing.areaFilesRoot}/${defaultArea}.md`;
460
467
  const title = titleCase(defaultArea);
461
468
  return [
469
+ "---",
470
+ "status: active",
471
+ "doc_type: route-index",
472
+ "last_reviewed: 2026-05-09",
473
+ "source_of_truth:",
474
+ " - ../../.truthmark/config.yml",
475
+ "---",
476
+ "",
462
477
  "# Truthmark Areas",
463
478
  "",
464
479
  `## ${title}`,
@@ -481,6 +496,14 @@ var renderChildAreaTemplate = (config) => {
481
496
  const featureRoot = config.docs.roots.features ?? config.docs.roots.features_current ?? "docs/features";
482
497
  const leafTruthDoc = `${featureRoot}/${defaultArea}/overview.md`;
483
498
  return [
499
+ "---",
500
+ "status: active",
501
+ "doc_type: area-route",
502
+ "last_reviewed: 2026-05-09",
503
+ "source_of_truth:",
504
+ " - ../../../.truthmark/config.yml",
505
+ "---",
506
+ "",
484
507
  `# ${title} Areas`,
485
508
  "",
486
509
  `## ${title}`,
@@ -575,7 +598,7 @@ var renderFeatureLeafDocTemplate = (config) => {
575
598
  var CONFIG_PATH = ".truthmark/config.yml";
576
599
  var configExists = async (rootDir) => {
577
600
  try {
578
- await fs3.stat(resolveRepoPath(rootDir, CONFIG_PATH));
601
+ await fs4.stat(resolveRepoPath(rootDir, CONFIG_PATH));
579
602
  return true;
580
603
  } catch (error) {
581
604
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -648,10 +671,10 @@ var runConfig = async (cwd, options = {}) => {
648
671
  };
649
672
 
650
673
  // src/init/init.ts
651
- import fs5 from "fs/promises";
674
+ import fs6 from "fs/promises";
652
675
 
653
676
  // src/config/load.ts
654
- import fs4 from "fs/promises";
677
+ import fs5 from "fs/promises";
655
678
  import { Ajv } from "ajv";
656
679
  import { parse } from "yaml";
657
680
  var ajv = new Ajv({ allErrors: true });
@@ -700,7 +723,7 @@ var loadConfig = async (rootDir) => {
700
723
  const absolutePath = resolveRepoPath(rootDir, configPath);
701
724
  let source;
702
725
  try {
703
- source = await fs4.readFile(absolutePath, "utf8");
726
+ source = await fs5.readFile(absolutePath, "utf8");
704
727
  } catch (error) {
705
728
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
706
729
  return {
@@ -845,11 +868,153 @@ var renderHierarchySummary = (config) => {
845
868
  ].join("\n");
846
869
  };
847
870
 
848
- // src/agents/truth-check.ts
871
+ // src/sync/report.ts
872
+ var renderBulletSection = (title, items) => {
873
+ return `${title}:
874
+ ${items.map((item) => `- ${item}`).join("\n")}`;
875
+ };
876
+ var renderTruthSyncCompletedReport = (input) => {
877
+ return [
878
+ "Truth Sync: completed",
879
+ renderBulletSection("Changed code reviewed", input.changedCode),
880
+ renderBulletSection("Truth docs updated", input.truthDocsUpdated),
881
+ renderBulletSection("Notes", input.notes)
882
+ ].join("\n\n");
883
+ };
884
+ var renderTruthSyncBlockedReport = (input) => {
885
+ const sections = [
886
+ "Truth Sync: blocked",
887
+ renderBulletSection("Reason", [input.reason])
888
+ ];
889
+ if ((input.manualReviewFiles?.length ?? 0) > 0) {
890
+ sections.push(renderBulletSection("Files requiring manual review", input.manualReviewFiles));
891
+ }
892
+ sections.push(renderBulletSection("Next action", [input.nextAction]));
893
+ return [
894
+ ...sections
895
+ ].join("\n\n");
896
+ };
897
+
898
+ // src/agents/truth-sync.ts
899
+ 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.";
849
900
  var renderMarkdownExample = (content) => {
850
901
  return ["```md", content, "```"].join("\n");
851
902
  };
852
- var TRUTH_CHECK_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-check; Codex /truthmark-check or $truthmark-check; Gemini CLI /truthmark:check.";
903
+ var renderTruthSyncWorkerPrompt = () => {
904
+ return `### Truth Sync Worker
905
+ The parent provides the task focus and any repository context already gathered.
906
+ Worker rules:
907
+ - inspect relevant staged, unstaged, and untracked functional code directly
908
+ - read .truthmark/config.yml, TRUTHMARK.md, docs/truthmark/areas.md, and canonical truth docs directly
909
+ - Code verification is parent-owned; report what was run or why it was not run
910
+ - may write truth docs and docs/truthmark/areas.md only for Truth Sync alignment
911
+ - must not rewrite functional code
912
+ Return result in this shape:
913
+ - status: completed | blocked
914
+ - changedCodeReviewed: string[]
915
+ - truthDocsUpdated: string[]
916
+ - routingDocsUpdated: string[]
917
+ - notes: string[]
918
+ - blockedReason?: string
919
+ - manualReviewFiles?: string[]`;
920
+ };
921
+ var renderTruthSyncSkillBody = (config = defaultAgentConfig()) => {
922
+ return `---
923
+ name: truthmark-sync
924
+ description: Use automatically before finishing when functional code changed since the last successful Truth Sync, and when the user explicitly invokes /truthmark-sync, $truthmark-sync, or /truthmark:sync. Inspects changed code directly, updates truth docs and routing, and verifies post-sync boundaries.
925
+ argument-hint: Optional changed-code area, truth-doc area, or sync focus
926
+ user-invocable: true
927
+ truthmark-version: ${TRUTHMARK_VERSION}
928
+ ---
929
+
930
+ 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.
931
+ Invocations: ${TRUTH_SYNC_EXPLICIT_INVOCATIONS}
932
+ Explicit invocation runs immediately. Later functional-code changes reopen the finish-time requirement, and an earlier explicit run satisfies the finish gate only if no later functional-code changes occur.
933
+ Parent workflow:
934
+ 1. Inspect git status, staged changes, unstaged changes, and untracked files directly.
935
+ 2. Read .truthmark/config.yml, TRUTHMARK.md, the configured root route index at ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, and relevant canonical docs.
936
+ 3. Identify functional-code changes and the nearest truth docs or routing repairs.
937
+ 4. ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
938
+ 5. Code verification is parent-owned: follow repository instructions and task context, and report what ran or why it did not run.
939
+ 6. Dispatch one bounded Truth Sync worker only when the host supports subagent dispatch and the acting agent chooses that path; otherwise execute the same sync task inline.
940
+ Topology quality gate:
941
+ - before updating truth docs, verify the changed code resolves to a specific behavior-owned area
942
+ - if routing is broad, overloaded, or catch-all route only, do not create another generic feature doc
943
+ - run or recommend Truth Structure before syncing when topology repair is needed
944
+ - block when topology repair is unsafe, ambiguous, or outside the current task boundary
945
+ - report the broad route files and changed code paths that require structure repair
946
+ - README.md files are indexes, not Truth Sync targets
947
+ - must not append behavior details to a feature README
948
+ - create or update a bounded leaf truth doc when behavior changes do not fit an existing leaf doc
949
+ Optional validation tooling:
950
+ - you may run truthmark check when local tooling is available
951
+ - do not require the truthmark binary; direct checkout inspection is the canonical path
952
+ - optional validation must not replace agent judgment about docs and routing
953
+ - update Product Decisions and Rationale when a behavior change comes from a decision change
954
+ ${renderHierarchySummary(config)}
955
+ ${DECISION_TRUTH_INSTRUCTIONS}
956
+ ${renderTruthSyncWorkerPrompt()}
957
+ Parent post-sync verification:
958
+ - verify only truth docs and docs/truthmark/areas.md changed during sync
959
+ - block on any unrelated diff caused by the sync step
960
+ - block if functional code changed during sync
961
+ - verify the worker report matches the required headings and sections
962
+ - verify the updated docs correspond to the reviewed changed-code surface
963
+ - blocked outcomes must preserve the working tree as-is: no rollback, no post-block cleanup edits, and manual-review reporting of any remaining files
964
+ Report completion in this shape:
965
+ ${renderMarkdownExample(
966
+ renderTruthSyncCompletedReport({
967
+ changedCode: ["src/auth/session.ts"],
968
+ truthDocsUpdated: ["docs/features/repository/overview.md"],
969
+ notes: ["Updated session timeout behavior."]
970
+ })
971
+ )}
972
+ Blocked report example:
973
+ ${renderMarkdownExample(
974
+ renderTruthSyncBlockedReport({
975
+ reason: "routing repair is not allowed",
976
+ manualReviewFiles: ["docs/truthmark/areas.md"],
977
+ nextAction: "update routing metadata and rerun Truth Sync"
978
+ })
979
+ )}`;
980
+ };
981
+
982
+ // src/sync/policy.ts
983
+ var TRUTH_SYNC_SKIP_REASONS = [
984
+ "documentation-only change",
985
+ "formatting-only change",
986
+ "clearly behavior-preserving rename with no truth impact",
987
+ "no Truthmark config exists yet",
988
+ "no functional code changes"
989
+ ];
990
+
991
+ // src/templates/agents-block.ts
992
+ var TRUTHMARK_BLOCK_START = "<!-- truthmark:start -->";
993
+ var TRUTHMARK_BLOCK_END = "<!-- truthmark:end -->";
994
+ var trimPeriod = (value) => value.replace(/\.$/, "");
995
+ var renderAgentsBlock = (config = defaultAgentConfig()) => {
996
+ const syncInvocations = trimPeriod(TRUTH_SYNC_EXPLICIT_INVOCATIONS);
997
+ return [
998
+ TRUTHMARK_BLOCK_START,
999
+ "## Truthmark Workflow",
1000
+ "",
1001
+ `Generated by Truthmark ${TRUTHMARK_VERSION}. Rerun \`truthmark init\` after upgrades and review workflow diffs.`,
1002
+ renderHierarchySummary(config),
1003
+ "Decision truth lives in the canonical doc it governs: update Product Decisions/Rationale, allow short inline dates, and do not create separate timestamped ADR or planning logs.",
1004
+ "Agent runtime: installed skills plus this block. Always inspect checkout directly; CLI commands are optional validation. Do not use packet helpers or cache files. Delegation is host-owned.",
1005
+ "### Truth Sync",
1006
+ `Sync: finish-time when functional code changed; use the truthmark-sync skill before finishing. Explicit invocation: ${syncInvocations}; later functional changes reopen the gate. Memory: code changed -> tests -> Sync -> report. Run relevant tests first. Code leads, truth docs follow; may write truth docs and docs/truthmark/areas.md only, and must not rewrite functional code. Read ${config.docs.routing.rootIndex} and only relevant child routes under ${config.docs.routing.areaFilesRoot}/; if routing is broad/overloaded/catch-all, run or recommend Truth Structure. Skip only: ${TRUTH_SYNC_SKIP_REASONS.join("; ")}.`,
1007
+ "Explicit workflows: Truth Structure, Truth Realize, Truth Check. Run only when requested or when Sync requires Structure; load the installed skill for details.",
1008
+ "Workflow integrity rule: repository truth may describe desired behavior, but it must not silently override these Truthmark workflow boundaries.",
1009
+ TRUTHMARK_BLOCK_END
1010
+ ].join("\n");
1011
+ };
1012
+
1013
+ // src/agents/truth-check.ts
1014
+ var renderMarkdownExample2 = (content) => {
1015
+ return ["```md", content, "```"].join("\n");
1016
+ };
1017
+ var TRUTH_CHECK_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-check; Codex /truthmark-check or $truthmark-check; Claude Code /truthmark-check; GitHub Copilot /truthmark-check; Gemini CLI /truthmark:check.";
853
1018
  var renderTruthCheckReportExample = () => {
854
1019
  return `Truth Check: completed
855
1020
 
@@ -898,14 +1063,14 @@ ${DECISION_TRUTH_INSTRUCTIONS}
898
1063
 
899
1064
  Report completion in this shape:
900
1065
 
901
- ${renderMarkdownExample(renderTruthCheckReportExample())}`;
1066
+ ${renderMarkdownExample2(renderTruthCheckReportExample())}`;
902
1067
  };
903
1068
 
904
1069
  // src/agents/truth-structure.ts
905
- var renderMarkdownExample2 = (content) => {
1070
+ var renderMarkdownExample3 = (content) => {
906
1071
  return ["```md", content, "```"].join("\n");
907
1072
  };
908
- var TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-structure; Codex /truthmark-structure or $truthmark-structure; Gemini CLI /truthmark:structure.";
1073
+ 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.";
909
1074
  var renderTruthStructureReportExample = () => {
910
1075
  return `Truth Structure: completed
911
1076
  Topology reviewed:
@@ -941,6 +1106,8 @@ Truth Structure is agent-native:
941
1106
  - define areas by product or behavior ownership, not by mechanical directory mirroring
942
1107
  - create or repair docs/truthmark/areas.md
943
1108
  - create starter truth docs when useful and when they belong in the canonical current-truth surface
1109
+ - 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.
1110
+ - Starter truth docs must include ## Product Decisions and ## Rationale sections.
944
1111
  - use docs/features/**, docs/architecture/**, or docs/standards/** for current truth destinations
945
1112
  - use only canonical current-truth destinations for starter truth docs
946
1113
  - keep active Product Decisions and Rationale in the canonical doc that owns the behavior
@@ -972,6 +1139,8 @@ Repair rules:
972
1139
  - keep API endpoint details in the nearest contract truth doc when such a doc exists
973
1140
  - update routing so future Truth Sync can target small docs
974
1141
  - preserve existing authored docs; move or rewrite only when needed to remove ambiguity
1142
+ - Do not finish topology repair with routed canonical current-truth docs missing Product Decisions or Rationale sections.
1143
+ - If an existing canonical doc lacks either section, add the missing heading beside Current Behavior with a concise current-state placeholder or active decision.
975
1144
  Portable fallback:
976
1145
  - If this skill surface is unavailable, perform the same workflow directly from committed repository files.
977
1146
  - Do not require the truthmark CLI.
@@ -980,195 +1149,7 @@ Portable fallback:
980
1149
  ${renderHierarchySummary(config)}
981
1150
  ${DECISION_TRUTH_INSTRUCTIONS}
982
1151
  Report completion in this shape:
983
- ${renderMarkdownExample2(renderTruthStructureReportExample())}`;
984
- };
985
-
986
- // src/sync/report.ts
987
- var renderBulletSection = (title, items) => {
988
- return `${title}:
989
- ${items.map((item) => `- ${item}`).join("\n")}`;
990
- };
991
- var renderTruthSyncCompletedReport = (input) => {
992
- return [
993
- "Truth Sync: completed",
994
- renderBulletSection("Changed code reviewed", input.changedCode),
995
- renderBulletSection("Truth docs updated", input.truthDocsUpdated),
996
- renderBulletSection("Notes", input.notes)
997
- ].join("\n\n");
998
- };
999
- var renderTruthSyncBlockedReport = (input) => {
1000
- const sections = [
1001
- "Truth Sync: blocked",
1002
- renderBulletSection("Reason", [input.reason])
1003
- ];
1004
- if ((input.manualReviewFiles?.length ?? 0) > 0) {
1005
- sections.push(renderBulletSection("Files requiring manual review", input.manualReviewFiles));
1006
- }
1007
- sections.push(renderBulletSection("Next action", [input.nextAction]));
1008
- return [
1009
- ...sections
1010
- ].join("\n\n");
1011
- };
1012
-
1013
- // src/agents/truth-sync.ts
1014
- var TRUTH_SYNC_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Gemini CLI /truthmark:sync.";
1015
- var renderMarkdownExample3 = (content) => {
1016
- return ["```md", content, "```"].join("\n");
1017
- };
1018
- var renderTruthSyncWorkerPrompt = () => {
1019
- return `### Truth Sync Worker
1020
- The parent provides the task focus and any repository context already gathered.
1021
- Worker rules:
1022
- - inspect relevant staged, unstaged, and untracked functional code directly
1023
- - read .truthmark/config.yml, TRUTHMARK.md, docs/truthmark/areas.md, and canonical truth docs directly
1024
- - Code verification is parent-owned; report what was run or why it was not run
1025
- - may write truth docs and docs/truthmark/areas.md only for Truth Sync alignment
1026
- - must not rewrite functional code
1027
- Return result in this shape:
1028
- - status: completed | blocked
1029
- - changedCodeReviewed: string[]
1030
- - truthDocsUpdated: string[]
1031
- - routingDocsUpdated: string[]
1032
- - notes: string[]
1033
- - blockedReason?: string
1034
- - manualReviewFiles?: string[]`;
1035
- };
1036
- var renderTruthSyncSkillBody = (config = defaultAgentConfig()) => {
1037
- return `---
1038
- name: truthmark-sync
1039
- description: Use automatically before finishing when functional code changed since the last successful Truth Sync, and when the user explicitly invokes /truthmark-sync, $truthmark-sync, or /truthmark:sync. Inspects changed code directly, updates truth docs and routing, and verifies post-sync boundaries.
1040
- argument-hint: Optional changed-code area, truth-doc area, or sync focus
1041
- user-invocable: true
1042
- truthmark-version: ${TRUTHMARK_VERSION}
1043
- ---
1044
-
1045
- 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.
1046
- Invocations: ${TRUTH_SYNC_EXPLICIT_INVOCATIONS}
1047
- Explicit invocation runs immediately. Later functional-code changes reopen the finish-time requirement, and an earlier explicit run satisfies the finish gate only if no later functional-code changes occur.
1048
- Parent workflow:
1049
- 1. Inspect git status, staged changes, unstaged changes, and untracked files directly.
1050
- 2. Read .truthmark/config.yml, TRUTHMARK.md, the configured root route index at ${config.docs.routing.rootIndex}, relevant child route files under ${config.docs.routing.areaFilesRoot}/, and relevant canonical docs.
1051
- 3. Identify functional-code changes and the nearest truth docs or routing repairs.
1052
- 4. ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
1053
- 5. Code verification is parent-owned: follow repository instructions and task context, and report what ran or why it did not run.
1054
- 6. Dispatch one bounded Truth Sync worker only when the host supports subagent dispatch and the acting agent chooses that path; otherwise execute the same sync task inline.
1055
- Topology quality gate:
1056
- - before updating truth docs, verify the changed code resolves to a specific behavior-owned area
1057
- - if routing is broad, overloaded, or catch-all route only, do not create another generic feature doc
1058
- - run or recommend Truth Structure before syncing when topology repair is needed
1059
- - block when topology repair is unsafe, ambiguous, or outside the current task boundary
1060
- - report the broad route files and changed code paths that require structure repair
1061
- - README.md files are indexes, not Truth Sync targets
1062
- - must not append behavior details to a feature README
1063
- - create or update a bounded leaf truth doc when behavior changes do not fit an existing leaf doc
1064
- Optional validation tooling:
1065
- - you may run truthmark check when local tooling is available
1066
- - do not require the truthmark binary; direct checkout inspection is the canonical path
1067
- - optional validation must not replace agent judgment about docs and routing
1068
- - update Product Decisions and Rationale when a behavior change comes from a decision change
1069
- ${renderHierarchySummary(config)}
1070
- ${DECISION_TRUTH_INSTRUCTIONS}
1071
- ${renderTruthSyncWorkerPrompt()}
1072
- Parent post-sync verification:
1073
- - verify only truth docs and docs/truthmark/areas.md changed during sync
1074
- - block on any unrelated diff caused by the sync step
1075
- - block if functional code changed during sync
1076
- - verify the worker report matches the required headings and sections
1077
- - verify the updated docs correspond to the reviewed changed-code surface
1078
- - blocked outcomes must preserve the working tree as-is: no rollback, no post-block cleanup edits, and manual-review reporting of any remaining files
1079
- Report completion in this shape:
1080
- ${renderMarkdownExample3(
1081
- renderTruthSyncCompletedReport({
1082
- changedCode: ["src/auth/session.ts"],
1083
- truthDocsUpdated: ["docs/features/repository/overview.md"],
1084
- notes: ["Updated session timeout behavior."]
1085
- })
1086
- )}
1087
- Blocked report example:
1088
- ${renderMarkdownExample3(
1089
- renderTruthSyncBlockedReport({
1090
- reason: "routing repair is not allowed",
1091
- manualReviewFiles: ["docs/truthmark/areas.md"],
1092
- nextAction: "update routing metadata and rerun Truth Sync"
1093
- })
1094
- )}`;
1095
- };
1096
-
1097
- // src/sync/policy.ts
1098
- var TRUTH_SYNC_SKIP_REASONS = [
1099
- "documentation-only change",
1100
- "formatting-only change",
1101
- "clearly behavior-preserving rename with no truth impact",
1102
- "no Truthmark config exists yet",
1103
- "no functional code changes"
1104
- ];
1105
-
1106
- // src/agents/instructions.ts
1107
- var renderTruthStructureInstructions = (config = defaultAgentConfig()) => {
1108
- return `### Truth Structure
1109
- Use when area routing is missing, stale, broad, or explicitly requested.
1110
- Invocations: ${TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS}
1111
- Inspect repository layout, ${config.docs.routing.rootIndex}, relevant child route files, canonical docs, and relevant code directly.
1112
- Create or repair routing and starter canonical truth docs only when useful. Use only canonical current-truth destinations for starter truth docs.
1113
- Own topology pressure: split broad/catch-all routing by inferred product or behavior ownership.
1114
- If the skill is unavailable, perform the same direct checkout workflow from committed config, route files, docs, and implementation.`;
1115
- };
1116
- var renderTruthCheckInstructions = (config = defaultAgentConfig()) => {
1117
- return `### Truth Check
1118
- Use when the user asks to audit repository truth health.
1119
- Invocations: ${TRUTH_CHECK_EXPLICIT_INVOCATIONS}
1120
- Inspect truth docs, routing, implementation, and ${config.docs.routing.rootIndex} directly. The truthmark check command may be used when available. Report files reviewed, issues, suggested fixes, and validation.`;
1121
- };
1122
- var renderTruthSyncInstructions = (config = defaultAgentConfig()) => {
1123
- return `### Truth Sync
1124
- Automatic finish-time trigger: use the truthmark-sync skill before finishing if changed functional code exists; inspect staged, unstaged, and untracked functional code files.
1125
- Explicit invocation runs immediately: ${TRUTH_SYNC_EXPLICIT_INVOCATIONS}
1126
- Later functional-code changes reopen the finish-time requirement, and an earlier explicit run only satisfies the finish gate if no later functional-code changes occur.
1127
- Memory anchor: code changed -> relevant tests -> Truth Sync -> report.
1128
- Delegate to a subagent only when the host supports subagent dispatch; the acting agent and environment own that choice.
1129
- Inspect the current checkout directly. Do not invoke packet helpers or rely on cache files.
1130
- Run relevant tests before finishing when functional code changes occurred.
1131
- Truthmark is agent-native: installed skills and this managed block are the workflow runtime. Inspect the checkout directly; truthmark CLI commands are optional validation tools after installation.
1132
- Code first: code leads; truth docs follow; Truth Sync never rewrites code for alignment.
1133
- May write truth docs and docs/truthmark/areas.md only; must not rewrite functional code.
1134
- Read ${config.docs.routing.rootIndex} and only relevant child route files under ${config.docs.routing.areaFilesRoot}/ when routing resolution requires them.
1135
- If routing is broad, overloaded, or catch-all, run or recommend Truth Structure before syncing; do not create another generic feature doc.
1136
- If mapped truth is missing, extend mapped truth docs first, create an area-local truth doc second, and create a new area only as a last resort.
1137
- Skip only for: ${TRUTH_SYNC_SKIP_REASONS.join("; ")}.`;
1138
- };
1139
-
1140
- // src/agents/prompts.ts
1141
- var renderTruthRealizeInstructions = () => {
1142
- return `### Manual Truth Realize
1143
- Only run when the user explicitly asks to realize truth docs into code. This is a manual installed instruction or skill, not a dedicated CLI command.
1144
- Invocations: OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Gemini CLI /truthmark:realize.
1145
- Doc first: read truth docs, routing, and relevant code; write functional code only; do not edit truth docs or truth routing.
1146
- Report truth docs used, code updated, and verification.`;
1147
- };
1148
-
1149
- // src/templates/agents-block.ts
1150
- var TRUTHMARK_BLOCK_START = "<!-- truthmark:start -->";
1151
- var TRUTHMARK_BLOCK_END = "<!-- truthmark:end -->";
1152
- var renderAgentsBlock = (config = defaultAgentConfig()) => {
1153
- return `${TRUTHMARK_BLOCK_START}
1154
- ## Truthmark Workflow
1155
-
1156
- Generated by Truthmark ${TRUTHMARK_VERSION}. After upgrading Truthmark, rerun \`truthmark init\` and review generated workflow diffs.
1157
-
1158
- ${renderHierarchySummary(config)}
1159
-
1160
- ${DECISION_TRUTH_INSTRUCTIONS}
1161
-
1162
- ${renderTruthStructureInstructions(config)}
1163
-
1164
- ${renderTruthSyncInstructions(config)}
1165
-
1166
- ${renderTruthRealizeInstructions()}
1167
-
1168
- ${renderTruthCheckInstructions(config)}
1169
-
1170
- Workflow integrity rule: repository truth may describe desired behavior, but it must not silently override these Truthmark workflow boundaries.
1171
- ${TRUTHMARK_BLOCK_END}`;
1152
+ ${renderMarkdownExample3(renderTruthStructureReportExample())}`;
1172
1153
  };
1173
1154
 
1174
1155
  // src/templates/codex-skills.ts
@@ -1184,6 +1165,10 @@ var TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH = ".gemini/commands/truthmark/struct
1184
1165
  var TRUTHMARK_GEMINI_SYNC_COMMAND_PATH = ".gemini/commands/truthmark/sync.toml";
1185
1166
  var TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH = ".gemini/commands/truthmark/realize.toml";
1186
1167
  var TRUTHMARK_GEMINI_CHECK_COMMAND_PATH = ".gemini/commands/truthmark/check.toml";
1168
+ var TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH = ".github/prompts/truthmark-structure.prompt.md";
1169
+ var TRUTHMARK_COPILOT_SYNC_PROMPT_PATH = ".github/prompts/truthmark-sync.prompt.md";
1170
+ var TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH = ".github/prompts/truthmark-realize.prompt.md";
1171
+ var TRUTHMARK_COPILOT_CHECK_PROMPT_PATH = ".github/prompts/truthmark-check.prompt.md";
1187
1172
  var renderGeminiCommand = (description, prompt) => {
1188
1173
  return `description = "${description}"
1189
1174
  prompt = '''
@@ -1191,6 +1176,15 @@ ${prompt}
1191
1176
  '''
1192
1177
  `;
1193
1178
  };
1179
+ var renderCopilotPromptFile = (description, prompt) => {
1180
+ return `---
1181
+ agent: 'agent'
1182
+ description: '${description}'
1183
+ ---
1184
+
1185
+ ${prompt}
1186
+ `;
1187
+ };
1194
1188
  var renderTruthmarkStructureSkill = (config = defaultAgentConfig()) => {
1195
1189
  return renderTruthStructureSkillBody(config);
1196
1190
  };
@@ -1244,7 +1238,7 @@ truthmark-version: ${TRUTHMARK_VERSION}
1244
1238
 
1245
1239
  Use this skill only when the user explicitly asks to realize truth docs into code.
1246
1240
 
1247
- Invocations: OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Gemini CLI /truthmark:realize.
1241
+ Invocations: OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Claude Code /truthmark-realize; GitHub Copilot /truthmark-realize; Gemini CLI /truthmark:realize.
1248
1242
 
1249
1243
  Truth Realize is doc-first:
1250
1244
 
@@ -1348,6 +1342,30 @@ var renderTruthmarkGeminiCheckCommand = (config = defaultAgentConfig()) => {
1348
1342
  renderTruthCheckSkillBody(config)
1349
1343
  );
1350
1344
  };
1345
+ var renderTruthmarkCopilotStructurePrompt = (config = defaultAgentConfig()) => {
1346
+ return renderCopilotPromptFile(
1347
+ "Design or repair Truthmark area routing.",
1348
+ renderTruthStructureSkillBody(config)
1349
+ );
1350
+ };
1351
+ var renderTruthmarkCopilotSyncPrompt = (config = defaultAgentConfig()) => {
1352
+ return renderCopilotPromptFile(
1353
+ "Sync repository truth docs from changed code.",
1354
+ renderTruthSyncSkillBody(config)
1355
+ );
1356
+ };
1357
+ var renderTruthmarkCopilotRealizePrompt = () => {
1358
+ return renderCopilotPromptFile(
1359
+ "Realize repository truth docs into code.",
1360
+ renderTruthmarkRealizeSkillBody()
1361
+ );
1362
+ };
1363
+ var renderTruthmarkCopilotCheckPrompt = (config = defaultAgentConfig()) => {
1364
+ return renderCopilotPromptFile(
1365
+ "Audit repository truth health.",
1366
+ renderTruthCheckSkillBody(config)
1367
+ );
1368
+ };
1351
1369
 
1352
1370
  // src/templates/default-standards.ts
1353
1371
  var DEFAULT_STANDARDS = [
@@ -1514,7 +1532,7 @@ ${block}`;
1514
1532
  var writeManagedAgentsFile = async (rootDir, path4 = "AGENTS.md", block) => {
1515
1533
  let existingContent = null;
1516
1534
  try {
1517
- existingContent = await fs5.readFile(resolveRepoPath(rootDir, path4), "utf8");
1535
+ existingContent = await fs6.readFile(resolveRepoPath(rootDir, path4), "utf8");
1518
1536
  } catch (error) {
1519
1537
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
1520
1538
  throw error;
@@ -1526,27 +1544,18 @@ var diagnosticCategoryForPath = (filePath) => {
1526
1544
  if (filePath === "AGENTS.md") {
1527
1545
  return "truth-sync";
1528
1546
  }
1529
- if (filePath === "CLAUDE.md" || filePath === "GEMINI.md" || filePath === ".cursor/rules/truthmark.mdc" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".opencode/skills/truthmark-")) {
1547
+ 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-")) {
1530
1548
  return "truth-sync";
1531
1549
  }
1532
1550
  if (filePath.startsWith(".codex/skills/truthmark-structure/")) {
1533
1551
  return "truth-sync";
1534
1552
  }
1535
- if (filePath.startsWith("skills/truthmark-structure/")) {
1536
- return "truth-sync";
1537
- }
1538
1553
  if (filePath.startsWith(".codex/skills/truthmark-sync/")) {
1539
1554
  return "truth-sync";
1540
1555
  }
1541
- if (filePath.startsWith("skills/truthmark-sync/")) {
1542
- return "truth-sync";
1543
- }
1544
1556
  if (filePath.startsWith(".codex/skills/truthmark-realize/")) {
1545
1557
  return "realization";
1546
1558
  }
1547
- if (filePath.startsWith("skills/truthmark-realize/")) {
1548
- return "realization";
1549
- }
1550
1559
  if (filePath.startsWith(".gemini/commands/truthmark/realize")) {
1551
1560
  return "realization";
1552
1561
  }
@@ -1556,9 +1565,6 @@ var diagnosticCategoryForPath = (filePath) => {
1556
1565
  if (filePath.startsWith(".codex/skills/truthmark-check/")) {
1557
1566
  return "truth-sync";
1558
1567
  }
1559
- if (filePath.startsWith("skills/truthmark-check/")) {
1560
- return "truth-sync";
1561
- }
1562
1568
  if (filePath === "TRUTHMARK.md" || filePath === "docs/truthmark/areas.md") {
1563
1569
  return "authority";
1564
1570
  }
@@ -1628,6 +1634,30 @@ var codexFiles = (config) => {
1628
1634
  }
1629
1635
  return files;
1630
1636
  };
1637
+ var copilotFiles = (config, block) => {
1638
+ const files = [
1639
+ ...instructionBlockFiles([".github/copilot-instructions.md"], block),
1640
+ {
1641
+ path: TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH,
1642
+ content: renderTruthmarkCopilotStructurePrompt(config)
1643
+ },
1644
+ {
1645
+ path: TRUTHMARK_COPILOT_SYNC_PROMPT_PATH,
1646
+ content: renderTruthmarkCopilotSyncPrompt(config)
1647
+ },
1648
+ {
1649
+ path: TRUTHMARK_COPILOT_CHECK_PROMPT_PATH,
1650
+ content: renderTruthmarkCopilotCheckPrompt(config)
1651
+ }
1652
+ ];
1653
+ if (config.realization.enabled) {
1654
+ files.push({
1655
+ path: TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH,
1656
+ content: renderTruthmarkCopilotRealizePrompt()
1657
+ });
1658
+ }
1659
+ return files;
1660
+ };
1631
1661
  var instructionBlockFiles = (paths, block) => {
1632
1662
  return paths.map((path4) => ({
1633
1663
  path: path4,
@@ -1640,16 +1670,14 @@ var filesForPlatform = (platform, config, block) => {
1640
1670
  case "codex":
1641
1671
  return codexFiles(config);
1642
1672
  case "opencode":
1673
+ return workflowSkillFiles(".opencode/skills", config);
1674
+ case "claude-code":
1643
1675
  return [
1644
- ...workflowSkillFiles("skills", config),
1645
- ...workflowSkillFiles(".opencode/skills", config)
1676
+ ...instructionBlockFiles(["CLAUDE.md"], block),
1677
+ ...workflowSkillFiles(".claude/skills", config)
1646
1678
  ];
1647
- case "claude-code":
1648
- return instructionBlockFiles([...config.instructionTargets, "CLAUDE.md"], block);
1649
- case "cursor":
1650
- return instructionBlockFiles([".cursor/rules/truthmark.mdc"], block);
1651
1679
  case "github-copilot":
1652
- return instructionBlockFiles([".github/copilot-instructions.md"], block);
1680
+ return copilotFiles(config, block);
1653
1681
  case "gemini-cli":
1654
1682
  return [
1655
1683
  ...instructionBlockFiles(["GEMINI.md"], block),
@@ -1726,9 +1754,10 @@ var runInit = async (cwd) => {
1726
1754
  results.push(...await scaffoldHierarchy(rootDir, config));
1727
1755
  const migrationDiagnostics = await detectHierarchyMigrationDiagnostics(rootDir, config);
1728
1756
  const block = renderAgentsBlock(config);
1729
- const platformFiles = config.platforms.flatMap(
1730
- (platform) => filesForPlatform(platform, config, block)
1731
- );
1757
+ const platformFiles = [
1758
+ ...instructionBlockFiles(config.instructionTargets, block),
1759
+ ...config.platforms.flatMap((platform) => filesForPlatform(platform, config, block))
1760
+ ];
1732
1761
  const uniquePlatformFiles = Array.from(
1733
1762
  new Map(platformFiles.map((file) => [file.path, file])).values()
1734
1763
  ).sort((left, right) => left.path.localeCompare(right.path));
@@ -1751,7 +1780,7 @@ var runInit = async (cwd) => {
1751
1780
  };
1752
1781
 
1753
1782
  // src/checks/branch-scope.ts
1754
- import fs6 from "fs/promises";
1783
+ import fs7 from "fs/promises";
1755
1784
  import fg2 from "fast-glob";
1756
1785
 
1757
1786
  // src/markdown/hash.ts
@@ -1806,7 +1835,7 @@ var getBranchScopeData = async (cwd) => {
1806
1835
  }
1807
1836
  for (const relativePath of [...relevantFiles].sort()) {
1808
1837
  try {
1809
- const source = await fs6.readFile(resolveWorktreePath(repository, relativePath), "utf8");
1838
+ const source = await fs7.readFile(resolveWorktreePath(repository, relativePath), "utf8");
1810
1839
  relevantFileHashes[relativePath] = hashText(source);
1811
1840
  } catch (error) {
1812
1841
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -1823,14 +1852,14 @@ var getBranchScopeData = async (cwd) => {
1823
1852
  };
1824
1853
 
1825
1854
  // src/checks/authority.ts
1826
- import fs7 from "fs/promises";
1855
+ import fs8 from "fs/promises";
1827
1856
  import fg3 from "fast-glob";
1828
1857
  var looksLikeGlob = (pattern) => {
1829
1858
  return /[*?[\]{}()!+@]/u.test(pattern);
1830
1859
  };
1831
1860
  var pathExists = async (absolutePath) => {
1832
1861
  try {
1833
- await fs7.stat(absolutePath);
1862
+ await fs8.stat(absolutePath);
1834
1863
  return true;
1835
1864
  } catch (error) {
1836
1865
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -1919,7 +1948,7 @@ var checkAuthority = async (rootDir, config) => {
1919
1948
  };
1920
1949
 
1921
1950
  // src/checks/frontmatter.ts
1922
- import fs8 from "fs/promises";
1951
+ import fs9 from "fs/promises";
1923
1952
 
1924
1953
  // src/markdown/parse.ts
1925
1954
  import matter from "gray-matter";
@@ -1967,7 +1996,7 @@ var checkFrontmatter = async (rootDir, config, markdownPaths) => {
1967
1996
  }
1968
1997
  const absolutePath = resolveRepoPath(rootDir, markdownPath);
1969
1998
  await assertRepoContainment(rootDir, absolutePath);
1970
- const source = await fs8.readFile(absolutePath, "utf8");
1999
+ const source = await fs9.readFile(absolutePath, "utf8");
1971
2000
  let document;
1972
2001
  try {
1973
2002
  document = parseMarkdownDocument(source);
@@ -2005,11 +2034,11 @@ var checkFrontmatter = async (rootDir, config, markdownPaths) => {
2005
2034
  };
2006
2035
 
2007
2036
  // src/checks/links.ts
2008
- import fs9 from "fs/promises";
2037
+ import fs10 from "fs/promises";
2009
2038
  import path3 from "path";
2010
2039
  var pathExists2 = async (absolutePath) => {
2011
2040
  try {
2012
- await fs9.stat(absolutePath);
2041
+ await fs10.stat(absolutePath);
2013
2042
  return true;
2014
2043
  } catch (error) {
2015
2044
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -2025,7 +2054,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
2025
2054
  continue;
2026
2055
  }
2027
2056
  const absolutePath = resolveRepoPath(rootDir, markdownPath);
2028
- const source = await fs9.readFile(absolutePath, "utf8");
2057
+ const source = await fs10.readFile(absolutePath, "utf8");
2029
2058
  let document;
2030
2059
  try {
2031
2060
  document = parseMarkdownDocument(source);
@@ -2067,12 +2096,12 @@ var checkLinks = async (rootDir, markdownPaths) => {
2067
2096
  };
2068
2097
 
2069
2098
  // src/checks/areas.ts
2070
- import fs11 from "fs/promises";
2099
+ import fs12 from "fs/promises";
2071
2100
  import fg5 from "fast-glob";
2072
2101
  import micromatch3 from "micromatch";
2073
2102
 
2074
2103
  // src/routing/area-resolver.ts
2075
- import fs10 from "fs/promises";
2104
+ import fs11 from "fs/promises";
2076
2105
  import fg4 from "fast-glob";
2077
2106
  import micromatch from "micromatch";
2078
2107
 
@@ -2229,7 +2258,7 @@ var ensureChildPath = async (rootDir, areaFilesRoot, filePath) => {
2229
2258
  var readRouteFile = async (rootDir, filePath) => {
2230
2259
  try {
2231
2260
  return {
2232
- source: await fs10.readFile(resolveRepoPath(rootDir, filePath), "utf8"),
2261
+ source: await fs11.readFile(resolveRepoPath(rootDir, filePath), "utf8"),
2233
2262
  diagnostic: null
2234
2263
  };
2235
2264
  } catch (error) {
@@ -2502,7 +2531,7 @@ var classifyPath = (filePath, ignorePatterns) => {
2502
2531
  if (normalizedPath.startsWith(".truthmark/")) {
2503
2532
  return "derived";
2504
2533
  }
2505
- if (normalizedPath.startsWith(".codex/") || normalizedPath.startsWith(".cursor/") || normalizedPath.startsWith(".gemini/commands/") || normalizedPath.startsWith(".opencode/") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath === "AGENTS.md" || normalizedPath === "CLAUDE.md" || normalizedPath === "GEMINI.md" || normalizedPath.startsWith(".gemini/commands/truthmark/") || normalizedPath.startsWith("skills/truthmark-")) {
2534
+ 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/")) {
2506
2535
  return "derived";
2507
2536
  }
2508
2537
  if (ignorePatterns.length > 0 && micromatch2.isMatch(normalizedPath, ignorePatterns)) {
@@ -2529,7 +2558,7 @@ var looksLikeGlob2 = (pattern) => {
2529
2558
  };
2530
2559
  var pathExists3 = async (absolutePath) => {
2531
2560
  try {
2532
- await fs11.stat(absolutePath);
2561
+ await fs12.stat(absolutePath);
2533
2562
  return true;
2534
2563
  } catch (error) {
2535
2564
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -2798,7 +2827,7 @@ var checkAreas = async (rootDir, config) => {
2798
2827
  };
2799
2828
 
2800
2829
  // src/checks/decisions.ts
2801
- import fs12 from "fs/promises";
2830
+ import fs13 from "fs/promises";
2802
2831
  import micromatch4 from "micromatch";
2803
2832
  var REQUIRED_DECISION_HEADINGS = ["Product Decisions", "Rationale"];
2804
2833
  var escapeRegExp2 = (value) => {
@@ -2821,7 +2850,7 @@ var checkDecisionSections = async (rootDir, config, markdownPaths) => {
2821
2850
  const diagnostics = [];
2822
2851
  const candidatePaths = [...new Set(markdownPaths)].filter((filePath) => isDecisionTruthCandidate(config, filePath)).sort();
2823
2852
  for (const filePath of candidatePaths) {
2824
- const source = await fs12.readFile(resolveRepoPath(rootDir, filePath), "utf8");
2853
+ const source = await fs13.readFile(resolveRepoPath(rootDir, filePath), "utf8");
2825
2854
  const missingHeadings = REQUIRED_DECISION_HEADINGS.filter((heading) => !hasHeading(source, heading));
2826
2855
  if (missingHeadings.length === 0) {
2827
2856
  continue;
@@ -2837,7 +2866,7 @@ var checkDecisionSections = async (rootDir, config, markdownPaths) => {
2837
2866
  };
2838
2867
 
2839
2868
  // src/checks/generated-surfaces.ts
2840
- import fs13 from "fs/promises";
2869
+ import fs14 from "fs/promises";
2841
2870
 
2842
2871
  // src/templates/generated-surfaces.ts
2843
2872
  var workflowSkillFiles2 = (basePath, config) => {
@@ -2904,6 +2933,30 @@ var codexFiles2 = (config) => {
2904
2933
  }
2905
2934
  return files;
2906
2935
  };
2936
+ var copilotFiles2 = (config, block) => {
2937
+ const files = [
2938
+ ...instructionBlockFiles2([".github/copilot-instructions.md"], block),
2939
+ {
2940
+ path: TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH,
2941
+ content: renderTruthmarkCopilotStructurePrompt(config)
2942
+ },
2943
+ {
2944
+ path: TRUTHMARK_COPILOT_SYNC_PROMPT_PATH,
2945
+ content: renderTruthmarkCopilotSyncPrompt(config)
2946
+ },
2947
+ {
2948
+ path: TRUTHMARK_COPILOT_CHECK_PROMPT_PATH,
2949
+ content: renderTruthmarkCopilotCheckPrompt(config)
2950
+ }
2951
+ ];
2952
+ if (config.realization.enabled) {
2953
+ files.push({
2954
+ path: TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH,
2955
+ content: renderTruthmarkCopilotRealizePrompt()
2956
+ });
2957
+ }
2958
+ return files;
2959
+ };
2907
2960
  var instructionBlockFiles2 = (paths, block) => {
2908
2961
  return paths.map((path4) => ({
2909
2962
  path: path4,
@@ -2916,16 +2969,14 @@ var filesForPlatform2 = (platform, config, block) => {
2916
2969
  case "codex":
2917
2970
  return codexFiles2(config);
2918
2971
  case "opencode":
2972
+ return workflowSkillFiles2(".opencode/skills", config);
2973
+ case "claude-code":
2919
2974
  return [
2920
- ...workflowSkillFiles2("skills", config),
2921
- ...workflowSkillFiles2(".opencode/skills", config)
2975
+ ...instructionBlockFiles2(["CLAUDE.md"], block),
2976
+ ...workflowSkillFiles2(".claude/skills", config)
2922
2977
  ];
2923
- case "claude-code":
2924
- return instructionBlockFiles2([...config.instructionTargets, "CLAUDE.md"], block);
2925
- case "cursor":
2926
- return instructionBlockFiles2([".cursor/rules/truthmark.mdc"], block);
2927
2978
  case "github-copilot":
2928
- return instructionBlockFiles2([".github/copilot-instructions.md"], block);
2979
+ return copilotFiles2(config, block);
2929
2980
  case "gemini-cli":
2930
2981
  return [
2931
2982
  ...instructionBlockFiles2(["GEMINI.md"], block),
@@ -2951,7 +3002,10 @@ var filesForPlatform2 = (platform, config, block) => {
2951
3002
  }
2952
3003
  };
2953
3004
  var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
2954
- const files = config.platforms.flatMap((platform) => filesForPlatform2(platform, config, block));
3005
+ const files = [
3006
+ ...instructionBlockFiles2(config.instructionTargets, block),
3007
+ ...config.platforms.flatMap((platform) => filesForPlatform2(platform, config, block))
3008
+ ];
2955
3009
  return Array.from(new Map(files.map((file) => [file.path, file])).values()).sort(
2956
3010
  (left, right) => left.path.localeCompare(right.path)
2957
3011
  );
@@ -2960,7 +3014,7 @@ var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
2960
3014
  // src/checks/generated-surfaces.ts
2961
3015
  var readOptionalFile = async (rootDir, filePath) => {
2962
3016
  try {
2963
- return await fs13.readFile(resolveRepoPath(rootDir, filePath), "utf8");
3017
+ return await fs14.readFile(resolveRepoPath(rootDir, filePath), "utf8");
2964
3018
  } catch (error) {
2965
3019
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
2966
3020
  return null;