truthmark 2.2.2 → 2.2.5

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
@@ -254,15 +254,10 @@ var SUPPORTED_PLATFORMS = [
254
254
  "opencode",
255
255
  "claude-code",
256
256
  "github-copilot",
257
- "gemini-cli"
258
- ];
259
- var DEFAULT_PLATFORMS = [
260
- "codex",
261
- "opencode",
262
- "claude-code",
263
- "github-copilot",
264
- "gemini-cli"
257
+ "antigravity",
258
+ "cursor"
265
259
  ];
260
+ var DEFAULT_PLATFORMS = [];
266
261
  var truthmarkConfigSchema = {
267
262
  type: "object",
268
263
  additionalProperties: false,
@@ -368,7 +363,6 @@ var DERIVED_TRUTHMARK_PATHS = {
368
363
  var DEFAULT_INSTRUCTION_TARGETS = ["AGENTS.md"];
369
364
  var createDefaultRawConfig = () => ({
370
365
  version: 2,
371
- platforms: [...DEFAULT_PLATFORMS],
372
366
  truthmark: {
373
367
  workspace: DEFAULT_TRUTHMARK_WORKSPACE.workspace,
374
368
  generated: {
@@ -1661,7 +1655,7 @@ var runConfig = async (cwd, options = {}) => {
1661
1655
  };
1662
1656
 
1663
1657
  // src/init/init.ts
1664
- import fs6 from "fs/promises";
1658
+ import fs7 from "fs/promises";
1665
1659
 
1666
1660
  // src/config/load.ts
1667
1661
  import fs4 from "fs/promises";
@@ -2031,6 +2025,9 @@ var scaffoldHierarchy = async (rootDir, config) => {
2031
2025
  return results;
2032
2026
  };
2033
2027
 
2028
+ // src/checks/generated-surfaces.ts
2029
+ import fs6 from "fs/promises";
2030
+
2034
2031
  // src/truth/evidence.ts
2035
2032
  var renderClaimEvidenceCheckedSection = (items) => {
2036
2033
  return [
@@ -2121,6 +2118,7 @@ var FEATURE_DOC_TEMPLATE_INSTRUCTIONS = [
2121
2118
  "If the template is missing, use lane-specific sections: product truth says what must be true and why; engineering truth says how the repository currently realizes it.",
2122
2119
  "Teams may edit template files under the configured Truthmark templates root to define their local truth-doc standards."
2123
2120
  ].join("\n");
2121
+ var TRUTH_DOC_AUTHORING_STYLE_INSTRUCTIONS = "Prefer diff-friendly Markdown: one durable claim per bullet or line, paragraphs no longer than one or two short sentences, and bullets or tables for rules, criteria, fields, files, and lists.";
2124
2122
  var renderTruthDocOwnershipGateSection = (subject, outcome) => {
2125
2123
  return [
2126
2124
  "Truth-doc ownership review:",
@@ -2270,29 +2268,6 @@ var renderCopilotCustomAgentModeSection = (agents, parentRule, writeAgents = [])
2270
2268
  `- ${parentRule}`
2271
2269
  ].join("\n");
2272
2270
  };
2273
- var renderGeminiSubagentModeSection = (agents, parentRule, writeAgents = []) => {
2274
- const mentions = agents.map((agent) => `@${agent.replace(/_/gu, "-")}`);
2275
- const writeMentions = writeAgents.map(
2276
- (agent) => `@${agent.replace(/_/gu, "-")}`
2277
- );
2278
- const writeAgentLines = writeMentions.length > 0 ? [
2279
- `- dispatch write-capable project subagents only with explicit write leases: ${writeMentions.join(", ")}`,
2280
- "- each write lease must name objective, required reads, allowed writes, forbidden writes, evidence, verification, and report fields",
2281
- "- write workers must stop when a required edit is off-lease and report status, filesChanged, evidence, offLeaseChanges, blockers, and notes",
2282
- "- parent must inspect the actual checkout diff against each lease before accepting a worker report"
2283
- ] : [];
2284
- const readOnlyScope = writeAgents.length > 0 ? "for verification" : "only";
2285
- const readOnlySubagentLabel = writeAgents.length > 0 ? "read-only subagents" : "subagents";
2286
- return [
2287
- "Gemini CLI subagent mode:",
2288
- "- use automatically when this workflow runs in Gemini CLI and the parent agent chooses bounded project subagent fan-out",
2289
- `- dispatch read-only project subagents ${readOnlyScope}: ${mentions.join(", ")}`,
2290
- `- ${readOnlySubagentLabel} inspect checkout evidence directly, return structured findings, and must not edit files`,
2291
- `- parent supplies bounded evidence shards; ${readOnlySubagentLabel} must not preload host instruction files or repo-wide policy docs unless assigned as evidence`,
2292
- ...writeAgentLines,
2293
- `- ${parentRule}`
2294
- ].join("\n");
2295
- };
2296
2271
  var defaultAgentConfig = () => {
2297
2272
  return createDefaultConfig();
2298
2273
  };
@@ -2334,16 +2309,13 @@ var renderAgentsBlock = (config = defaultAgentConfig()) => {
2334
2309
  "After functional code changes, run relevant tests, then use the truthmark-sync skill before finishing; later functional changes need a fresh Sync review. Memory: code changed -> tests -> Sync -> report.",
2335
2310
  "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.",
2336
2311
  "If routing cannot map changed code to a bounded truth owner, run Truth Structure before syncing when safe; otherwise stop 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.",
2337
- "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.",
2312
+ "Explicit workflows: Truth Structure, Truth Document, Truth Realize, Truth Check. Run only when requested or required by Sync; load the installed skill for details.",
2338
2313
  ...portalLine === null ? [] : [portalLine],
2339
2314
  "Workflow integrity rule: repository truth may describe desired behavior, but it must not override these workflow boundaries.",
2340
2315
  TRUTHMARK_BLOCK_END
2341
2316
  ].join("\n");
2342
2317
  };
2343
2318
 
2344
- // src/templates/workflow-surfaces.ts
2345
- import { stringify as stringify2 } from "yaml";
2346
-
2347
2319
  // src/agents/workflow-manifest.ts
2348
2320
  var TRUTHMARK_CLI_RUNNER = "truthmark";
2349
2321
  var VALIDATE_SYNC_REPORT_HELPER = {
@@ -2435,7 +2407,6 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
2435
2407
  "Truth docs updated",
2436
2408
  "Truth docs split",
2437
2409
  "Evidence checked",
2438
- "Helper scripts",
2439
2410
  "Notes"
2440
2411
  ],
2441
2412
  subagents: ["truth_route_auditor", "truth_claim_verifier"],
@@ -2524,7 +2495,6 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
2524
2495
  "Truth docs restructured",
2525
2496
  "Routing updated",
2526
2497
  "Evidence checked",
2527
- "Helper scripts",
2528
2498
  "Notes"
2529
2499
  ],
2530
2500
  subagents: ["truth_route_auditor", "truth_claim_verifier"],
@@ -2553,46 +2523,6 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
2553
2523
  allowedWrites: ["functional code"],
2554
2524
  reportSections: ["Truth docs used", "Code updated", "Verification"]
2555
2525
  },
2556
- "truthmark-preview": {
2557
- id: "truthmark-preview",
2558
- displayName: "Truthmark Preview",
2559
- 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.",
2560
- shortDescription: "Preview likely workflow routing before edits; read-only and explicit",
2561
- defaultPrompt: "Use $truthmark-preview to preview likely Truthmark routing before edits.",
2562
- allowImplicitInvocation: false,
2563
- positiveTriggers: [
2564
- "explicit request to preview Truthmark workflow routing before edits",
2565
- "explicit request for likely route owner, target docs, expected writes, or subagent plan"
2566
- ],
2567
- negativeTriggers: [
2568
- "normal validation or final correctness audit",
2569
- "automatic preflight or finish-time review",
2570
- "request to mutate truth docs, routing, or code"
2571
- ],
2572
- forbiddenAdjacency: [
2573
- "must not replace Truth Check",
2574
- "must not run Truth Sync automatically",
2575
- "must not authorize later edits or issue write leases"
2576
- ],
2577
- reviewQuestions: [
2578
- "read-only boundary",
2579
- "intended-not-authorized handoff",
2580
- "manual handoff questions"
2581
- ],
2582
- allowedWrites: ["none by default"],
2583
- reportSections: [
2584
- "Requested outcome",
2585
- "Likely workflow",
2586
- "Why this workflow",
2587
- "Likely route owner",
2588
- "Expected write classes",
2589
- "Expected target files",
2590
- "Suggested subagent use",
2591
- "Manual handoff questions",
2592
- "Handoff"
2593
- ],
2594
- subagents: ["truth_route_auditor"]
2595
- },
2596
2526
  "truthmark-check": {
2597
2527
  id: "truthmark-check",
2598
2528
  displayName: "Truthmark Check",
@@ -2681,7 +2611,6 @@ var getTruthmarkWorkflow = (id) => {
2681
2611
  };
2682
2612
 
2683
2613
  // src/agents/truth-check.ts
2684
- 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.";
2685
2614
  var renderTruthCheckReportExample = (config = defaultAgentConfig()) => {
2686
2615
  const rootRouteIndex = config.truthmark.paths.routesIndex;
2687
2616
  return `Truth Check: completed
@@ -2738,8 +2667,6 @@ var renderTruthCheckProcedureBody = (config = defaultAgentConfig(), options = {}
2738
2667
 
2739
2668
  Use this skill to audit repository truth health.
2740
2669
 
2741
- Invocations: ${TRUTH_CHECK_EXPLICIT_INVOCATIONS}
2742
-
2743
2670
  Truth Check is agent-led:
2744
2671
 
2745
2672
  - inspect .truthmark/config.yml and configured route files only when they exist; then inspect canonical docs and relevant implementation directly
@@ -2773,10 +2700,8 @@ ${DECISION_TRUTH_INSTRUCTIONS}`;
2773
2700
  };
2774
2701
 
2775
2702
  // src/agents/truth-document.ts
2776
- 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.";
2777
2703
  var renderTruthDocumentReportExample = (config = defaultAgentConfig()) => {
2778
2704
  const engineeringTruthRoot = resolveEngineeringTruthRoot(config);
2779
- const helperScripts = ["validate-write-lease: skipped, no write lease used"];
2780
2705
  return `Truth Document: completed
2781
2706
 
2782
2707
  Implementation reviewed:
@@ -2808,9 +2733,6 @@ ${renderClaimEvidenceCheckedSection([
2808
2733
  }
2809
2734
  ])}
2810
2735
 
2811
- Helper scripts:
2812
- ${helperScripts.map((helperScript) => `- ${helperScript}`).join("\n")}
2813
-
2814
2736
  Notes:
2815
2737
  - Documented routing and behavior from route handlers and tests.`;
2816
2738
  };
@@ -2844,7 +2766,6 @@ var renderTruthDocumentProcedureBody = (config = defaultAgentConfig(), options =
2844
2766
  return `# Truthmark Document
2845
2767
 
2846
2768
  Use this skill to document existing implemented behavior when no functional-code changes are required for the task.
2847
- Invocations: ${TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS}
2848
2769
 
2849
2770
  Truth Document is manual and implementation-first:
2850
2771
 
@@ -2878,18 +2799,14 @@ ${renderRouteFirstEvidenceGateSection(
2878
2799
  )}
2879
2800
  ${subagentMode}${REPOSITORY_INTELLIGENCE_INSTRUCTIONS}
2880
2801
  ${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
2802
+ ${TRUTH_DOC_AUTHORING_STYLE_INSTRUCTIONS}
2881
2803
  ${renderTruthDocRestructureGateSection(
2882
2804
  "Truth Document may restructure only truth docs for the implemented behavior being documented."
2883
2805
  )}
2884
2806
  ${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
2885
2807
  ${renderHierarchySummary(config)}
2886
2808
  ${DECISION_TRUTH_INSTRUCTIONS}
2887
- Helper status reporting:
2888
- - Validate the report body before adding this validator's own success status; the body may omit \`validate-document-report\` while validation is pending.
2889
- - 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.
2890
- - If the installed Truthmark CLI is unavailable or the helper is skipped, record \`validate-document-report: skipped, <reason>\` and manually validate the report shape.
2891
- - 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\`.
2892
- - Helper output is derived evidence and never replaces direct checkout inspection, evidence review, or parent acceptance.
2809
+ Optional validation: when local tooling is available, you may validate the final report with \`truthmark validate document-report <report-file> --json\`; direct checkout inspection and evidence review remain authoritative.
2893
2810
  Parent post-document verification:
2894
2811
  - verify only truth docs and leased truth routing files changed during document work
2895
2812
  - stop on functional code, generated host surfaces, or unrelated diffs caused by document work
@@ -2897,89 +2814,7 @@ Parent post-document verification:
2897
2814
  - verify the final report records ownership review, structure requirement, restructure, routing update, or manual handoff reason when applicable`;
2898
2815
  };
2899
2816
 
2900
- // src/agents/truth-preview.ts
2901
- 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.";
2902
- var renderTruthPreviewReportExample = (config = defaultAgentConfig()) => {
2903
- return `Truth Preview: completed
2904
-
2905
- Requested outcome:
2906
- - preview likely Truthmark workflow routing before edits
2907
-
2908
- Likely workflow:
2909
- - truthmark-document
2910
-
2911
- Why this workflow:
2912
- - positive trigger: document existing implemented behavior
2913
- - negative triggers considered: functional-code change, doc-first implementation, topology repair, truth audit
2914
- - forbidden adjacency considered: must not edit functional code
2915
-
2916
- Likely route owner:
2917
- - route file: ${config.truthmark.paths.routesIndex}
2918
- - likely lane impact: engineering-lane
2919
- - product target docs: none identified
2920
- - engineering target docs: ${config.truthmark.paths.engineeringTruthRoot}/behaviors/example.md
2921
- - confidence: medium
2922
-
2923
- Expected write classes:
2924
- - truth docs
2925
-
2926
- Expected target files:
2927
- - ${config.truthmark.paths.engineeringTruthRoot}/behaviors/example.md
2928
-
2929
- Suggested subagent use:
2930
- - read-only verifiers: truth_route_auditor
2931
- - write workers: none in Preview
2932
- - leases needed: none in Preview
2933
-
2934
- Manual handoff questions:
2935
- - none identified in preview
2936
-
2937
- Handoff:
2938
- - Run the selected Truthmark workflow after user approval.`;
2939
- };
2940
- var renderTruthPreviewProcedureBody = (config = defaultAgentConfig()) => {
2941
- return `Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.
2942
-
2943
- Invocations: ${TRUTH_PREVIEW_EXPLICIT_INVOCATIONS}
2944
-
2945
- Truth Preview is read-only. Its report is intended, not authorized.
2946
-
2947
- Purpose:
2948
- - preview the likely Truthmark workflow, route owner, target files, expected write classes, suggested subagent use, and manual handoff questions before edits happen
2949
- - report likely product lane impact, engineering lane impact, target docs, and ambiguity before edits
2950
- - hand off to the selected workflow after user approval
2951
- - keep the selector thin so agents can avoid loading or acting through heavier workflows prematurely
2952
-
2953
- Read:
2954
- - .truthmark/config.yml, only when present
2955
- - ${config.truthmark.paths.routesIndex}, first, only when present
2956
- - relevant child route files under ${config.truthmark.paths.routeAreasRoot}/ for the selected scope or changed paths, only when present
2957
- - relevant truth docs and implementation files needed to preview ownership
2958
- - Evidence authority:
2959
- ${renderBulletBlock(EVIDENCE_AUTHORITY_INSTRUCTIONS)}
2960
- - Lane classification:
2961
- ${renderReadOnlyLaneClassificationRuleBlock(config)}
2962
-
2963
- Do not:
2964
- - must not edit files
2965
- - must not create truth docs
2966
- - must not update routing
2967
- - must not run Truth Sync automatically
2968
- - must not replace Truth Check
2969
- - must not claim final correctness
2970
- - must not issue write leases
2971
- - must not mutate code
2972
-
2973
- Suggested subagent use:
2974
- - optional read-only verifier: truth_route_auditor
2975
- - write workers: none
2976
- - leases needed: none
2977
-
2978
- ${renderHierarchySummary(config)}`;
2979
- };
2980
-
2981
2817
  // src/agents/truthmark-portal.ts
2982
- var TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-portal; Codex /truthmark-portal or $truthmark-portal; Claude Code /truthmark-portal; GitHub Copilot /truthmark-portal; Gemini CLI /truthmark:portal.";
2983
2818
  var renderTruthmarkPortalProcedureBody = (config = defaultAgentConfig()) => {
2984
2819
  const output = config.truthmark.paths.portalOutput;
2985
2820
  const template = config.truthmark.paths.portalTemplate;
@@ -2987,8 +2822,6 @@ var renderTruthmarkPortalProcedureBody = (config = defaultAgentConfig()) => {
2987
2822
 
2988
2823
  Truthmark Portal is a manual-only presentation workflow. It is never an automatic completion workflow, never Truth Sync, and runs only when the user explicitly asks to generate, refresh, or update the committed static HTML Portal.
2989
2824
 
2990
- Invocations: ${TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS}
2991
-
2992
2825
  Core rules:
2993
2826
 
2994
2827
  - Markdown remains canonical; generated HTML is presentation only.
@@ -3018,7 +2851,6 @@ ${renderHierarchySummary(config)}`;
3018
2851
  };
3019
2852
 
3020
2853
  // src/agents/truth-structure.ts
3021
- 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.";
3022
2854
  var renderTruthStructureReportExample = (config = defaultAgentConfig()) => {
3023
2855
  const productTruthRoot = resolveProductTruthRoot(config);
3024
2856
  const engineeringTruthRoot = resolveEngineeringTruthRoot(config);
@@ -3073,7 +2905,7 @@ var renderTruthStructureProcedureBody = (config = defaultAgentConfig(), options
3073
2905
  ` : "";
3074
2906
  const subagentMode = `${claudeSubagentMode}${copilotCustomAgentMode}`;
3075
2907
  return `Use this skill to design or repair Truthmark area structure.
3076
- Invocations: ${TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS}
2908
+
3077
2909
  Truth Structure is agent-native:
3078
2910
  - inspect repository layout, current docs, Truthmark config and route files when present, and relevant code directly
3079
2911
  - Evidence authority:
@@ -3083,15 +2915,15 @@ ${renderLaneClassificationRuleBlock(config)}
3083
2915
  - inspect the configured root route index at ${config.truthmark.paths.routesIndex} and relevant child route files under ${config.truthmark.paths.routeAreasRoot}/ when they exist
3084
2916
  - define areas by product or behavior ownership, not by mechanical directory mirroring
3085
2917
  - create or repair ${config.truthmark.paths.routesIndex}
3086
- - create starter truth docs when useful and when they belong in the canonical current-truth surface
2918
+ - create skeletal starter truth docs only when missing ownership would otherwise block future workflows
3087
2919
  - Starter truth docs must use closed YAML frontmatter bounded by opening and closing --- lines; include status, truth_kind, and last_reviewed inside that frontmatter. Put source references in the final ## Source References section, not in frontmatter.
3088
- - Starter truth docs must use lane-specific templates and keep product and engineering truth in separate files.
2920
+ - Starter truth docs are ownership anchors, not behavior writeups: include only the title, bounded area/scope, and Source References needed to make routing explicit.
2921
+ - Starter truth docs must keep product and engineering truth in separate files; leave substantive behavior, contract, architecture, workflow, operations, or test prose to Truth Document.
3089
2922
  ${subagentMode}
3090
- ${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
3091
2923
  - use ${productTruthRoot}/** for product truth destinations
3092
2924
  - use ${engineeringTruthRoot}/** for engineering truth destinations
3093
2925
  - use only canonical current-truth destinations for starter truth docs
3094
- - keep active Product Decisions in product truth and Engineering Decisions in engineering truth
2926
+ - keep Product Decisions in product truth and Engineering Decisions in engineering truth when selecting destinations; report any relocation need instead of rewriting decision prose during topology review
3095
2927
  - preserve unrelated authored content
3096
2928
  ## New area setup
3097
2929
  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.
@@ -3111,12 +2943,11 @@ Do not:
3111
2943
  ## Topology Governance
3112
2944
  Truth Structure owns documentation topology, lane splits, decision relocation, and relationship repair. Do not depend on humans to manually organize ${productTruthRoot} or ${engineeringTruthRoot}. Treat both configured lane roots as managed semantic roots.
3113
2945
  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.
3114
- When topology pressure exists, repair structure before creating or extending truth docs.
2946
+ When topology pressure exists, repair route structure before creating or extending truth ownership anchors.
3115
2947
  ${renderTruthDocOwnershipGateSection(
3116
2948
  "candidate route owners and current truth docs",
3117
- "if a truth doc mixes independent owners, route ownership is broad, or a split is required for bounded ownership, split and reroute into bounded truth docs when safe; otherwise stop with manual-review files"
2949
+ "if a truth doc mixes independent owners, route ownership is broad, or a split is required for bounded ownership, split or reroute only the ownership topology when safe; otherwise stop with manual-review files"
3118
2950
  )}
3119
- ${TRUTH_DOC_DECISION_RATIONALE_PRESERVATION_INSTRUCTIONS}
3120
2951
  Topology pressure signals:
3121
2952
  - one area maps broad code such as src/**, app/**, server/**, services/**, or packages/**
3122
2953
  - one area maps multiple unrelated controllers, route groups, services, or bounded contexts
@@ -3132,10 +2963,10 @@ Use these review thresholds as guidance:
3132
2963
  - more than 5 controllers mapped through one catch-all area
3133
2964
  Repair rules:
3134
2965
  - split broad, overloaded, or catch-all areas into behavior-owned child route files
3135
- - split mixed-owner truth docs into bounded owner docs before adding new behavior claims
2966
+ - split or flag mixed-owner truth docs for bounded owners before any workflow adds new behavior claims
3136
2967
  - create route files under ${config.truthmark.paths.routeAreasRoot}/ when a product/domain boundary is clear
3137
- - create engineering behavior truth docs under ${engineeringTruthRoot} only when behavior lacks a current doc
3138
- - create product truth docs under ${productTruthRoot} only when product promise, boundary, rationale, or user-visible capability truth is in scope
2968
+ - create skeletal engineering ownership anchors under ${engineeringTruthRoot} only when behavior lacks a current owner
2969
+ - create skeletal product ownership anchors under ${productTruthRoot} only when product promise, boundary, rationale, or user-visible capability ownership is in scope
3139
2970
  - README.md files are indexes, not Truth Sync targets
3140
2971
  - prefer bounded product docs under product/capabilities or product/decisions and engineering docs under engineering/<kind>/<surface>.md
3141
2972
  - keep behavior truth docs behavior-oriented, not endpoint-oriented
@@ -3143,13 +2974,9 @@ Repair rules:
3143
2974
  - update routing so future Truth Sync can target small docs
3144
2975
  - preserve existing authored docs; move or rewrite only when needed to remove ambiguity
3145
2976
  - report Truth docs split when one broad or mixed-owner truth doc becomes multiple bounded docs
3146
- ${renderTruthDocRestructureGateSection(
3147
- "Truth Structure may restructure broader routed docs when topology, ownership, or doc-shape repair is already in scope."
3148
- )}
3149
2977
  ${renderTopologyEvidenceGateSection()}
3150
- ${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
3151
2978
  - Do not finish topology repair with mixed product/engineering authority in a single canonical truth doc.
3152
- - If an existing canonical doc has wrong-lane sections, split or move them into the correct product or engineering lane.
2979
+ - If an existing canonical doc has wrong-lane sections, report the lane repair needed and only move content when the topology split explicitly requires it.
3153
2980
  Portable fallback:
3154
2981
  - If this skill surface is unavailable, perform the same workflow directly from committed repository files.
3155
2982
  - Do not require the truthmark CLI.
@@ -3334,7 +3161,6 @@ var renderTruthSyncBlockedReport = (input) => {
3334
3161
  };
3335
3162
 
3336
3163
  // src/agents/truth-sync.ts
3337
- 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.";
3338
3164
  var renderTruthSyncProductDecisionRuleBlock = (config) => {
3339
3165
  return renderBulletBlock(
3340
3166
  [
@@ -3374,8 +3200,7 @@ var renderTruthSyncProcedureBody = (config = defaultAgentConfig(), options = {})
3374
3200
  ` : "";
3375
3201
  const subagentMode = `${claudeSubagentMode}${codexSubagentMode}${copilotCustomAgentMode}${openCodeSubagentMode}`;
3376
3202
  return `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.
3377
- Invocations: ${TRUTH_SYNC_EXPLICIT_INVOCATIONS}
3378
- Explicit invocation runs immediately. Later functional-code changes need a fresh finish-time review, and an earlier explicit run satisfies the finish-time review only if no later functional-code changes occur.
3203
+ Explicit invocation runs immediately when the user directly requests this workflow. Later functional-code changes need a fresh finish-time review, and an earlier explicit run satisfies the finish-time review only if no later functional-code changes occur.
3379
3204
  Skip when changes are documentation-only, formatting-only, clearly behavior-preserving renames with no truth impact, when no Truthmark config exists yet, or when there are no functional code changes.
3380
3205
  Parent workflow:
3381
3206
  1. Inspect git status, staged changes, unstaged changes, and untracked files directly.
@@ -3398,50 +3223,28 @@ ${renderTruthSyncProductDecisionRuleBlock(config)}
3398
3223
  - User-provided decisions/rationale: decisions, rationale, constraints, tradeoffs, rejection reasons, or scope boundaries from the current task conversation, or "none provided"
3399
3224
  - No-update-needed rationale: why mapped truth is already current when no truth doc should change
3400
3225
  - Blockers: missing routing, ambiguous ownership, failed verification, unavailable evidence, or off-boundary write needs
3401
- 11. Only edit allowed truth docs/routes after Sync Intent is clear; if ownership is ambiguous, stop and recommend Truth Structure instead of guessing.
3402
- ${subagentMode}Topology review:
3226
+ 11. Only edit allowed truth docs/routes after Sync Intent is clear; if ownership is ambiguous, repair topology first when the repair is safe and in scope, otherwise stop and recommend Truth Structure instead of guessing.
3227
+ ${subagentMode}Topology review and repair:
3403
3228
  - before updating truth docs, verify the changed code resolves to a specific behavior-owned area and bounded truth owner
3404
- - 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
3405
- - run Truth Structure before syncing when topology repair is safe and in scope
3406
- - stop and recommend Truth Structure when topology repair is unsafe, ambiguous, or outside the current task boundary
3407
- - report the route files and changed code paths that require structure repair
3229
+ - if routing is missing, stale, broad, overloaded, catch-all route only, or cannot map changed code to a bounded truth owner, run Truth Structure before syncing when topology repair is safe and in scope
3230
+ - safe in-scope topology repair may update truth routing files and create or update bounded leaf truth docs needed to map the changed functional code; keep the repair limited to the affected route owner
3231
+ - stop and recommend Truth Structure only when topology repair is unsafe, ambiguous, or outside the current task boundary
3232
+ - report the route files and changed code paths that required structure repair
3233
+ - do not create another generic truth doc
3408
3234
  - README.md files are indexes, not Truth Sync targets
3409
3235
  - must not append behavior details to a README.md index
3410
- - create or update a bounded leaf truth doc when behavior changes do not fit an existing leaf doc
3411
3236
  - write engineering truth under ${config.truthmark.paths.engineeringTruthRoot}; product truth updates under ${config.truthmark.paths.productTruthRoot} are allowed only for explicit current product behavior changes
3412
- ${renderTruthDocOwnershipGateSection(
3413
- "changed functional files and impacted truth docs",
3414
- "if an impacted doc is broad, mixed-owner, index-like, or the update spans independent behavior owners, run Truth Structure before syncing when safe and in scope; otherwise stop and recommend Truth Structure"
3415
- )}
3416
- ${TRUTH_DOC_DECISION_RATIONALE_PRESERVATION_INSTRUCTIONS}
3417
- ${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
3418
- ${renderTruthDocRestructureGateSection(
3419
- "Truth Sync may restructure leased canonical truth docs when the current sync evidence shows repository truth is stale, even when the doc is outside the initially affected route focus."
3420
- )}
3421
- ${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
3422
- ${renderRouteFirstEvidenceGateSection(
3423
- "changed functional files",
3424
- "if no impacted doc changed, report why truth was already current or why sync was skipped"
3425
- )}
3426
- ${REPOSITORY_INTELLIGENCE_INSTRUCTIONS}
3427
3237
  Optional validation tooling:
3428
3238
  - you may run truthmark check when local tooling is available
3239
+ - you may validate the final report with \`truthmark validate sync-report <report-file> --json\` when available
3429
3240
  - do not require the truthmark binary; direct checkout inspection is the canonical path
3430
3241
  - optional validation must not replace agent judgment about docs and routing
3431
3242
  - update Product Decisions only in product truth and Engineering Decisions only in engineering truth when evidence supports the lane-specific decision change
3432
- Helper status reporting:
3433
- - Validate the report body before adding this validator's own success status; the body may omit \`validate-sync-report\` while validation is pending.
3434
- - 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.
3435
- - If the installed Truthmark CLI is unavailable or the helper is skipped, record \`validate-sync-report: skipped, <reason>\` and manually validate the report shape.
3436
- - 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\`.
3437
- - Helper output is derived evidence and never replaces direct checkout inspection, evidence review, or parent acceptance.
3438
3243
  ${renderHierarchySummary(config)}
3439
- ${DECISION_TRUTH_INSTRUCTIONS}
3440
3244
  Parent post-sync verification:
3441
3245
  - verify only truth docs and leased truth routing files changed during sync
3442
3246
  - stop on any unrelated diff caused by the sync step
3443
3247
  - stop if functional code changed during sync
3444
- - for each write lease, validate the worker report against the actual worker diff, allowedWrites, forbiddenWrites, identity fields, filesChanged, offLeaseChanges, blockers, and expected report fields before accepting it
3445
3248
  - 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
3446
3249
  - verify the updated docs correspond to reviewed checkout evidence, changed-code impact, or a recorded stale-truth correction made within the sync write lease
3447
3250
  - verify the final report records ownership review, structure requirement, split, restructure, or manual handoff reason when the ownership review applies
@@ -3475,8 +3278,6 @@ var TRUTHMARK_REALIZE_SKILL_PATH = ".agents/skills/truthmark-realize/SKILL.md";
3475
3278
  var TRUTHMARK_REALIZE_SKILL_METADATA_PATH = ".agents/skills/truthmark-realize/agents/openai.yaml";
3476
3279
  var TRUTHMARK_CHECK_SKILL_PATH = ".agents/skills/truthmark-check/SKILL.md";
3477
3280
  var TRUTHMARK_CHECK_SKILL_METADATA_PATH = ".agents/skills/truthmark-check/agents/openai.yaml";
3478
- var TRUTHMARK_PREVIEW_SKILL_PATH = ".agents/skills/truthmark-preview/SKILL.md";
3479
- var TRUTHMARK_PREVIEW_SKILL_METADATA_PATH = ".agents/skills/truthmark-preview/agents/openai.yaml";
3480
3281
  var TRUTHMARK_PORTAL_SKILL_PATH = ".agents/skills/truthmark-portal/SKILL.md";
3481
3282
  var TRUTHMARK_PORTAL_SKILL_METADATA_PATH = ".agents/skills/truthmark-portal/agents/openai.yaml";
3482
3283
  var TRUTHMARK_ROUTE_AUDITOR_AGENT_PATH = ".codex/agents/truth-route-auditor.toml";
@@ -3491,37 +3292,28 @@ var TRUTHMARK_CLAUDE_ROUTE_AUDITOR_AGENT_PATH = ".claude/agents/truth-route-audi
3491
3292
  var TRUTHMARK_CLAUDE_CLAIM_VERIFIER_AGENT_PATH = ".claude/agents/truth-claim-verifier.md";
3492
3293
  var TRUTHMARK_CLAUDE_DOC_REVIEWER_AGENT_PATH = ".claude/agents/truth-doc-reviewer.md";
3493
3294
  var TRUTHMARK_CLAUDE_DOC_WRITER_AGENT_PATH = ".claude/agents/truth-doc-writer.md";
3494
- var TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH = ".gemini/commands/truthmark/structure.toml";
3495
- var TRUTHMARK_GEMINI_DOCUMENT_COMMAND_PATH = ".gemini/commands/truthmark/document.toml";
3496
- var TRUTHMARK_GEMINI_SYNC_COMMAND_PATH = ".gemini/commands/truthmark/sync.toml";
3497
- var TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH = ".gemini/commands/truthmark/realize.toml";
3498
- var TRUTHMARK_GEMINI_CHECK_COMMAND_PATH = ".gemini/commands/truthmark/check.toml";
3499
- var TRUTHMARK_GEMINI_PREVIEW_COMMAND_PATH = ".gemini/commands/truthmark/preview.toml";
3500
- var TRUTHMARK_GEMINI_PORTAL_COMMAND_PATH = ".gemini/commands/truthmark/portal.toml";
3501
- var TRUTHMARK_GEMINI_ROUTE_AUDITOR_AGENT_PATH = ".gemini/agents/truth-route-auditor.md";
3502
- var TRUTHMARK_GEMINI_CLAIM_VERIFIER_AGENT_PATH = ".gemini/agents/truth-claim-verifier.md";
3503
- var TRUTHMARK_GEMINI_DOC_REVIEWER_AGENT_PATH = ".gemini/agents/truth-doc-reviewer.md";
3504
- var TRUTHMARK_GEMINI_DOC_WRITER_AGENT_PATH = ".gemini/agents/truth-doc-writer.md";
3295
+ var TRUTHMARK_ANTIGRAVITY_STRUCTURE_RULE_PATH = ".antigravity/rules/truthmark-structure.md";
3296
+ var TRUTHMARK_ANTIGRAVITY_DOCUMENT_RULE_PATH = ".antigravity/rules/truthmark-document.md";
3297
+ var TRUTHMARK_ANTIGRAVITY_SYNC_RULE_PATH = ".antigravity/rules/truthmark-sync.md";
3298
+ var TRUTHMARK_ANTIGRAVITY_REALIZE_RULE_PATH = ".antigravity/rules/truthmark-realize.md";
3299
+ var TRUTHMARK_ANTIGRAVITY_CHECK_RULE_PATH = ".antigravity/rules/truthmark-check.md";
3300
+ var TRUTHMARK_ANTIGRAVITY_PORTAL_RULE_PATH = ".antigravity/rules/truthmark-portal.md";
3301
+ var TRUTHMARK_CURSOR_STRUCTURE_SKILL_PATH = ".cursor/skills/truthmark-structure/SKILL.md";
3302
+ var TRUTHMARK_CURSOR_DOCUMENT_SKILL_PATH = ".cursor/skills/truthmark-document/SKILL.md";
3303
+ var TRUTHMARK_CURSOR_SYNC_SKILL_PATH = ".cursor/skills/truthmark-sync/SKILL.md";
3304
+ var TRUTHMARK_CURSOR_REALIZE_SKILL_PATH = ".cursor/skills/truthmark-realize/SKILL.md";
3305
+ var TRUTHMARK_CURSOR_CHECK_SKILL_PATH = ".cursor/skills/truthmark-check/SKILL.md";
3306
+ var TRUTHMARK_CURSOR_PORTAL_SKILL_PATH = ".cursor/skills/truthmark-portal/SKILL.md";
3505
3307
  var TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH = ".github/prompts/truthmark-structure.prompt.md";
3506
3308
  var TRUTHMARK_COPILOT_DOCUMENT_PROMPT_PATH = ".github/prompts/truthmark-document.prompt.md";
3507
3309
  var TRUTHMARK_COPILOT_SYNC_PROMPT_PATH = ".github/prompts/truthmark-sync.prompt.md";
3508
3310
  var TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH = ".github/prompts/truthmark-realize.prompt.md";
3509
3311
  var TRUTHMARK_COPILOT_CHECK_PROMPT_PATH = ".github/prompts/truthmark-check.prompt.md";
3510
- var TRUTHMARK_COPILOT_PREVIEW_PROMPT_PATH = ".github/prompts/truthmark-preview.prompt.md";
3511
3312
  var TRUTHMARK_COPILOT_PORTAL_PROMPT_PATH = ".github/prompts/truthmark-portal.prompt.md";
3512
3313
  var TRUTHMARK_COPILOT_ROUTE_AUDITOR_AGENT_PATH = ".github/agents/truth-route-auditor.md";
3513
3314
  var TRUTHMARK_COPILOT_CLAIM_VERIFIER_AGENT_PATH = ".github/agents/truth-claim-verifier.md";
3514
3315
  var TRUTHMARK_COPILOT_DOC_REVIEWER_AGENT_PATH = ".github/agents/truth-doc-reviewer.md";
3515
3316
  var TRUTHMARK_COPILOT_DOC_WRITER_AGENT_PATH = ".github/agents/truth-doc-writer.md";
3516
- var renderGeminiCommand = (description, prompt) => {
3517
- const promptWithArgs = `${prompt.trimEnd()}
3518
- User focus or arguments: {{args}}`;
3519
- return `description = "${description}"
3520
- prompt = '''
3521
- ${promptWithArgs}
3522
- '''
3523
- `;
3524
- };
3525
3317
  var renderCopilotPromptFile = (description, prompt) => {
3526
3318
  return `---
3527
3319
  agent: 'agent'
@@ -3535,12 +3327,10 @@ var workflowSupportFiles = (workflowId) => {
3535
3327
  const workflow = getTruthmarkWorkflow(workflowId);
3536
3328
  const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
3537
3329
  const hasSubagentSupport = definition.parentRule !== void 0 && ((workflow.subagents?.length ?? 0) > 0 || (workflow.writeSubagents?.length ?? 0) > 0);
3538
- const hasHelperSupport = (workflow.helpers?.length ?? 0) > 0;
3539
3330
  return [
3540
3331
  "support/procedure.md",
3541
3332
  "support/report-template.md",
3542
- ...hasSubagentSupport ? ["support/subagents-and-leases.md"] : [],
3543
- ...hasHelperSupport ? ["helper-manifest.yml", "support/helper-policy.md"] : []
3333
+ ...hasSubagentSupport ? ["support/subagents-and-leases.md"] : []
3544
3334
  ];
3545
3335
  };
3546
3336
  var renderWorkflowCommandAdapterInstructions = (workflowId, root, hostName, surfaceKind) => {
@@ -3561,105 +3351,70 @@ var renderTomlString = (value) => {
3561
3351
  var renderTomlStringArray = (values) => {
3562
3352
  return `[${values.map(renderTomlString).join(", ")}]`;
3563
3353
  };
3564
- 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.";
3565
3354
  var routeFilesHint = (config) => `${config.truthmark.paths.routesIndex}; ${config.truthmark.paths.routeAreasRoot}/`;
3566
3355
  var WORKFLOW_PACKAGE_DEFINITIONS = {
3567
3356
  "truthmark-structure": {
3568
3357
  title: "Truthmark Structure",
3569
3358
  argumentHint: "Optional area, directory, or routing concern",
3570
- invocations: TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS,
3571
3359
  use: () => "Use this skill to design or repair Truthmark area structure.",
3572
3360
  quickRules: (config) => [
3573
3361
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3574
3362
  `Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect current docs and relevant code directly.`,
3575
3363
  "Define areas by product or behavior ownership, not by mechanical directory mirroring.",
3576
- "Do not edit functional code.",
3577
- "Read support/procedure.md before writing route or starter truth-doc changes.",
3578
- "Read support/report-template.md before the final report."
3364
+ "Do not edit functional code."
3579
3365
  ],
3580
3366
  parentRule: "Parent agent owns all Truth Structure writes and final topology decisions"
3581
3367
  },
3582
3368
  "truthmark-document": {
3583
3369
  title: "Truthmark Document",
3584
3370
  argumentHint: "Optional implemented behavior, API endpoint, route, controller, package, or truth-doc area to document",
3585
- invocations: TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS,
3586
3371
  use: () => "Use this skill to document existing implemented behavior when no functional-code changes are required for the task.",
3587
3372
  quickRules: (config) => [
3588
3373
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3589
3374
  `Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect existing canonical docs, implementation code, and tests directly.`,
3590
3375
  "Document current implemented behavior; do not invent future behavior.",
3591
- "May write canonical truth docs and truth routing files only; must not write functional code.",
3592
- "Read support/procedure.md before editing truth docs.",
3593
- "Read support/subagents-and-leases.md only when dispatching or accepting worker output.",
3594
- "Read support/report-template.md before the final report."
3376
+ "May write canonical truth docs and truth routing files only; must not write functional code."
3595
3377
  ],
3596
3378
  parentRule: "Parent agent owns Truth Document acceptance, lease validation, and final report"
3597
3379
  },
3598
3380
  "truthmark-sync": {
3599
3381
  title: "Truthmark Sync",
3600
3382
  argumentHint: "Optional changed-code area, truth-doc area, or sync focus",
3601
- invocations: TRUTH_SYNC_EXPLICIT_INVOCATIONS,
3602
3383
  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.",
3603
3384
  quickRules: (config) => [
3604
3385
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3605
3386
  "Skip docs-only, formatting-only, behavior-preserving renames with no truth impact, missing config, and no-code changes.",
3606
3387
  `Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect relevant canonical docs directly.`,
3607
3388
  "direct checkout inspection is the canonical path; do not require the truthmark binary.",
3608
- "May write canonical truth docs and truth routing files only; must not rewrite functional code.",
3609
- "Read support/procedure.md before editing truth docs.",
3610
- "Read support/subagents-and-leases.md only when dispatching or accepting worker output.",
3611
- "Read support/report-template.md before the final report."
3389
+ "May write canonical truth docs and truth routing files only; must not rewrite functional code."
3612
3390
  ],
3613
3391
  parentRule: "Parent agent owns Truth Sync acceptance, lease validation, and final report"
3614
3392
  },
3615
- "truthmark-preview": {
3616
- title: "Truthmark Preview",
3617
- argumentHint: "Optional requested outcome, code area, doc path, or routing question",
3618
- invocations: TRUTH_PREVIEW_EXPLICIT_INVOCATIONS,
3619
- use: () => "Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.",
3620
- quickRules: (config) => [
3621
- "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3622
- `Inspect .truthmark/config.yml and the root route index (${config.truthmark.paths.routesIndex}) first when present; then inspect only child route files under ${config.truthmark.paths.routeAreasRoot}/ that are relevant to the selected scope or changed paths, plus the truth docs or implementation files needed to preview ownership.`,
3623
- "Truth Preview is read-only; this report is intended, not authorized.",
3624
- "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.",
3625
- "Use optional read-only route-auditor evidence only when it reduces context or clarifies ownership.",
3626
- "Hand off to the selected workflow after user approval."
3627
- ],
3628
- parentRule: "Parent agent owns the final Truth Preview report"
3629
- },
3630
3393
  "truthmark-realize": {
3631
3394
  title: "Truthmark Realize",
3632
3395
  argumentHint: "Optional truth doc path, area, or desired code behavior to realize",
3633
- invocations: TRUTH_REALIZE_EXPLICIT_INVOCATIONS,
3634
3396
  use: () => "Use this skill only when the user explicitly asks to realize truth docs into code.",
3635
3397
  quickRules: (config) => [
3636
3398
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3637
3399
  `Read the source truth docs, inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist, then inspect tests and relevant functional code directly.`,
3638
3400
  "Truth docs lead; code follows.",
3639
- "may write functional code only; must not edit truth docs or truth routing while realizing those docs.",
3640
- "Read support/procedure.md before changing code.",
3641
- "Read support/report-template.md before the final report."
3401
+ "may write functional code only; must not edit truth docs or truth routing while realizing those docs."
3642
3402
  ]
3643
3403
  },
3644
3404
  "truthmark-check": {
3645
3405
  title: "Truthmark Check",
3646
3406
  argumentHint: "Optional area, doc path, or audit focus",
3647
- invocations: TRUTH_CHECK_EXPLICIT_INVOCATIONS,
3648
3407
  use: () => "Use this skill to audit repository truth health.",
3649
3408
  quickRules: (config) => [
3650
3409
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
3651
3410
  `Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect canonical docs and relevant implementation directly.`,
3652
- "Report issues and suggested fixes; do not silently rewrite unrelated files.",
3653
- "Read support/procedure.md before auditing details.",
3654
- "Read support/subagents-and-leases.md only when dispatching verifier subagents.",
3655
- "Read support/report-template.md before the final report."
3411
+ "Report issues and suggested fixes; do not silently rewrite unrelated files."
3656
3412
  ],
3657
3413
  parentRule: "Parent agent owns the final Truth Check report"
3658
3414
  },
3659
3415
  "truthmark-portal": {
3660
3416
  title: "Truthmark Portal",
3661
3417
  argumentHint: "Optional portal generation focus",
3662
- invocations: TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS,
3663
3418
  use: () => "Use this skill only when the user explicitly asks to generate or refresh the committed static HTML Truthmark Portal.",
3664
3419
  quickRules: (config) => [
3665
3420
  "Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
@@ -3669,9 +3424,7 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
3669
3424
  "Generate committed, generated non-canonical static files for humans.",
3670
3425
  `Write only under fixed Portal output ${config.truthmark.paths.portalOutput}.`,
3671
3426
  `Use determined Portal template ${config.truthmark.paths.portalTemplate} when present; no .truthmark/index.json dependency.`,
3672
- "Use no remote dependencies by default and include source provenance on every page.",
3673
- "Read support/procedure.md before generating Portal output.",
3674
- "Read support/report-template.md before the final report."
3427
+ "Use no remote dependencies by default and include source provenance on every page."
3675
3428
  ]
3676
3429
  }
3677
3430
  };
@@ -3699,14 +3452,14 @@ ${renderMarkdownExample(
3699
3452
  changedCode: ["src/auth/session.ts"],
3700
3453
  syncIntent: {
3701
3454
  changedCodeReviewed: ["src/auth/session.ts"],
3702
- affectedRouteOrTruthOwner: [config.truthmark.paths.routesIndex],
3703
- targetTruthDocs: [
3704
- `${engineeringTruthRoot}/repository/bootstrap-routing.md`
3455
+ affectedRouteOrTruthOwner: [
3456
+ `${config.truthmark.paths.routeAreasRoot}/authentication.md`
3705
3457
  ],
3458
+ targetTruthDocs: [`${engineeringTruthRoot}/behaviors/session-timeout.md`],
3706
3459
  intendedUpdate: ["Update session timeout behavior."],
3707
3460
  evidenceToVerify: [
3708
3461
  "src/auth/session.ts:12",
3709
- `${config.truthmark.paths.routesIndex}:11`
3462
+ `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`
3710
3463
  ],
3711
3464
  userProvidedDecisionRationale: [
3712
3465
  "User rationale: session timeout behavior changed for internal implementation consistency"
@@ -3714,40 +3467,37 @@ ${renderMarkdownExample(
3714
3467
  noUpdateNeededRationale: ["not applicable; mapped truth is stale"],
3715
3468
  blockers: ["none"]
3716
3469
  },
3717
- ownershipReviewed: [config.truthmark.paths.routesIndex],
3718
- truthDocsUpdated: [
3719
- `${engineeringTruthRoot}/repository/bootstrap-routing.md`
3470
+ ownershipReviewed: [
3471
+ `${config.truthmark.paths.routeAreasRoot}/authentication.md`
3720
3472
  ],
3473
+ truthDocsUpdated: [`${engineeringTruthRoot}/behaviors/session-timeout.md`],
3721
3474
  evidenceChecked: [
3722
3475
  {
3723
- claim: "Session timeout behavior is documented in the mapped repository truth doc.",
3476
+ claim: "Session timeout behavior is documented in the bounded authentication behavior truth doc.",
3724
3477
  evidence: [
3725
3478
  "src/auth/session.ts:12",
3726
- `${config.truthmark.paths.routesIndex}:11`
3479
+ `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`
3727
3480
  ],
3728
3481
  result: "supported"
3729
3482
  }
3730
3483
  ],
3731
3484
  decisionRationaleCaptured: [
3732
- "Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale."
3485
+ "Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale."
3733
3486
  ],
3734
- helperScripts: ["validate-write-lease: skipped, no write lease used"],
3735
3487
  notes: ["Updated session timeout behavior."]
3736
3488
  })
3737
3489
  )}
3738
3490
  Blocked report example:
3739
3491
  ${renderMarkdownExample(
3740
3492
  renderTruthSyncBlockedReport({
3741
- reason: "routing repair is not allowed",
3742
- manualReviewFiles: [config.truthmark.paths.routesIndex],
3743
- nextAction: "update routing metadata and rerun Truth Sync"
3493
+ reason: "Changed code maps only to the provisional bootstrap route.",
3494
+ manualReviewFiles: [
3495
+ "src/auth/**",
3496
+ `${config.truthmark.paths.routeAreasRoot}/${config.truthmark.routes.defaultArea}.md`
3497
+ ],
3498
+ nextAction: "Run Truth Structure for src/auth/** before updating behavior truth."
3744
3499
  })
3745
3500
  )}`;
3746
- case "truthmark-preview":
3747
- return `Report completion in this shape:
3748
- ${renderMarkdownExample(
3749
- renderTruthPreviewReportExample(config)
3750
- )}`;
3751
3501
  case "truthmark-realize":
3752
3502
  return `Report completion in this shape:
3753
3503
 
@@ -3809,56 +3559,6 @@ Truthmark-managed generated file. Refresh with truthmark init when truthmark che
3809
3559
  ${body}
3810
3560
  `;
3811
3561
  };
3812
- var renderHelperManifest = (helpers) => {
3813
- const manifest = {
3814
- helpers: Object.fromEntries(
3815
- helpers.map((helper) => [
3816
- helper.id,
3817
- {
3818
- optional: helper.optional,
3819
- runner: helper.runner,
3820
- command: helper.command,
3821
- inputs: helper.inputs,
3822
- output: helper.output,
3823
- writes: helper.writes,
3824
- ...helper.allowedWrites === void 0 ? {} : { allowedWrites: helper.allowedWrites },
3825
- fallback: helper.fallback
3826
- }
3827
- ])
3828
- )
3829
- };
3830
- return [
3831
- `# Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces.`,
3832
- stringify2(manifest, { lineWidth: 0 })
3833
- ].join("\n");
3834
- };
3835
- var renderHelperPolicySupport = (helpers) => {
3836
- const reportHelperId = helpers.find((helper) => helper.id.endsWith("-report"))?.id ?? helpers[0]?.id;
3837
- const helperLines = helpers.map(
3838
- (helper) => `- ${helper.id}: optional ${helper.runner}; manual fallback: ${helper.fallback}`
3839
- ).join("\n");
3840
- return renderSkillSupportFile(
3841
- "Optional Helper CLI Policy",
3842
- `Optional helper CLI commands may collect deterministic checkout facts or validate artifacts. If the Truthmark CLI is unavailable or cannot return the declared helper output, 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.
3843
-
3844
- Runner detection:
3845
- - Check that the declared Truthmark CLI runner is available before invoking a helper.
3846
- - Invoke helpers through the installed \`truthmark validate ... --json\` CLI command using argv-style arguments from helper-manifest.yml.
3847
- - If unavailable, failing, or returning incompatible output, treat the helper as skipped and use the manual fallback.
3848
- - Do not fail the workflow solely because a helper cannot run.
3849
-
3850
- Available helpers:
3851
- ${helperLines}
3852
-
3853
- Final reports should include helper status when helpers are declared for this workflow:
3854
-
3855
- \`\`\`md
3856
- Helper scripts:
3857
- - ${reportHelperId}: ran, passed
3858
- - validate-write-lease: skipped, no write lease used
3859
- \`\`\``
3860
- );
3861
- };
3862
3562
  var renderWorkflowProcedure = (workflowId, config) => {
3863
3563
  switch (workflowId) {
3864
3564
  case "truthmark-structure":
@@ -3867,8 +3567,6 @@ var renderWorkflowProcedure = (workflowId, config) => {
3867
3567
  return renderTruthDocumentProcedureBody(config);
3868
3568
  case "truthmark-sync":
3869
3569
  return renderTruthSyncProcedureBody(config);
3870
- case "truthmark-preview":
3871
- return renderTruthPreviewProcedureBody(config);
3872
3570
  case "truthmark-realize":
3873
3571
  return renderTruthmarkRealizeProcedureBody(config);
3874
3572
  case "truthmark-check":
@@ -3890,16 +3588,10 @@ var renderWorkflowEntrypoint = (workflowId, config, supportFiles, host) => {
3890
3588
  if (supportFile === "support/subagents-and-leases.md") {
3891
3589
  return "read only when using subagents, leases, or accepting worker output";
3892
3590
  }
3893
- if (supportFile === "support/helper-policy.md") {
3894
- return "read only when invoking helper validators or reporting helper status";
3895
- }
3896
- if (supportFile === "helper-manifest.yml") {
3897
- return "read only when invoking helper validators or validating helper registration";
3898
- }
3899
3591
  return "available when relevant to the current step";
3900
3592
  };
3901
3593
  const supportFileList = supportFiles.map((supportFile) => `- ${supportFile} \u2014 ${supportFileUsage(supportFile)}`).join("\n");
3902
- 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;
3594
+ 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 === "cursor" ? "Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation." : void 0;
3903
3595
  return `---
3904
3596
  name: ${workflowId}
3905
3597
  description: ${workflow.description}
@@ -3913,8 +3605,6 @@ ${definition.use(config)}${hostUsage === void 0 ? "" : `
3913
3605
 
3914
3606
  ${hostUsage}`}
3915
3607
 
3916
- Invocations: ${definition.invocations}
3917
-
3918
3608
  Quick procedure:
3919
3609
  ${definition.quickRules(config).map((rule) => `- ${rule}`).join("\n")}
3920
3610
 
@@ -3958,12 +3648,8 @@ var renderWorkflowSubagentSupport = (workflowId, host) => {
3958
3648
  definition.parentRule,
3959
3649
  writeAgents
3960
3650
  );
3961
- case "gemini-cli":
3962
- return renderGeminiSubagentModeSection(
3963
- readAgents,
3964
- definition.parentRule,
3965
- writeAgents
3966
- );
3651
+ case "cursor":
3652
+ return void 0;
3967
3653
  }
3968
3654
  };
3969
3655
  var renderTruthmarkSkillPackage = ({
@@ -3979,8 +3665,11 @@ var renderTruthmarkSkillPackage = ({
3979
3665
  config
3980
3666
  );
3981
3667
  const subagents = renderWorkflowSubagentSupport(workflowId, host);
3982
- const helpers = getTruthmarkWorkflow(workflowId).helpers ?? [];
3983
- const supportFiles = workflowSupportFiles(workflowId);
3668
+ const supportFiles = [
3669
+ "support/procedure.md",
3670
+ "support/report-template.md",
3671
+ ...subagents !== void 0 ? ["support/subagents-and-leases.md"] : []
3672
+ ];
3984
3673
  const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
3985
3674
  const files = [
3986
3675
  {
@@ -4011,18 +3700,6 @@ var renderTruthmarkSkillPackage = ({
4011
3700
  )
4012
3701
  });
4013
3702
  }
4014
- if (helpers.length > 0) {
4015
- files.push(
4016
- {
4017
- path: `${skillDirectory}/helper-manifest.yml`,
4018
- content: renderHelperManifest(helpers)
4019
- },
4020
- {
4021
- path: `${supportDirectory}/helper-policy.md`,
4022
- content: renderHelperPolicySupport(helpers)
4023
- }
4024
- );
4025
- }
4026
3703
  return files;
4027
3704
  };
4028
3705
  var normalizeOpenCodePermissionPath = (path12) => {
@@ -4053,7 +3730,7 @@ var renderOpenCodeWriterEditAllowRules = (config) => {
4053
3730
  return [...new Set(allowedPatterns)].map((pattern) => ` ${JSON.stringify(pattern)}: allow`).join("\n");
4054
3731
  };
4055
3732
  var READ_ONLY_SUBAGENT_CONTEXT_BOUNDARY = `Context boundary:
4056
- 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.
3733
+ Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence.
4057
3734
  Use only the parent-assigned shard plus required checkout evidence files.
4058
3735
  Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes.`;
4059
3736
  var renderReadOnlySubagentInstructions = (instructions) => {
@@ -4188,45 +3865,6 @@ tools: [read, search, edit]
4188
3865
 
4189
3866
  # Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces.
4190
3867
 
4191
- ${instructions}
4192
- `;
4193
- };
4194
- var renderGeminiReadOnlyAgent = ({
4195
- copilotName,
4196
- description,
4197
- instructions
4198
- }) => {
4199
- const agentInstructions = renderReadOnlySubagentInstructions(instructions);
4200
- return `---
4201
- name: ${copilotName}
4202
- description: ${description}
4203
- kind: local
4204
- tools: [read_file, grep_search]
4205
- ---
4206
-
4207
- # Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces.
4208
-
4209
- Manual invocation: @${copilotName}
4210
-
4211
- ${agentInstructions}
4212
- `;
4213
- };
4214
- var renderGeminiWriteAgent = ({
4215
- copilotName,
4216
- description,
4217
- instructions
4218
- }) => {
4219
- return `---
4220
- name: ${copilotName}
4221
- description: ${description}
4222
- kind: local
4223
- tools: [read_file, grep_search, write_file]
4224
- ---
4225
-
4226
- # Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces.
4227
-
4228
- Manual invocation: @${copilotName} with an explicit parent write lease.
4229
-
4230
3868
  ${instructions}
4231
3869
  `;
4232
3870
  };
@@ -4329,26 +3967,6 @@ var renderTruthmarkCopilotDocWriterAgent = () => {
4329
3967
  TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer
4330
3968
  );
4331
3969
  };
4332
- var renderTruthmarkGeminiRouteAuditorAgent = () => {
4333
- return renderGeminiReadOnlyAgent(
4334
- TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor
4335
- );
4336
- };
4337
- var renderTruthmarkGeminiClaimVerifierAgent = () => {
4338
- return renderGeminiReadOnlyAgent(
4339
- TRUTHMARK_SUBAGENT_PROFILES.truth_claim_verifier
4340
- );
4341
- };
4342
- var renderTruthmarkGeminiDocReviewerAgent = () => {
4343
- return renderGeminiReadOnlyAgent(
4344
- TRUTHMARK_SUBAGENT_PROFILES.truth_doc_reviewer
4345
- );
4346
- };
4347
- var renderTruthmarkGeminiDocWriterAgent = () => {
4348
- return renderGeminiWriteAgent(
4349
- TRUTHMARK_WRITE_SUBAGENT_PROFILES.truth_doc_writer
4350
- );
4351
- };
4352
3970
  var renderTruthmarkClaudeRouteAuditorAgent = () => {
4353
3971
  return renderClaudeReadOnlyAgent(
4354
3972
  TRUTHMARK_SUBAGENT_PROFILES.truth_route_auditor
@@ -4515,8 +4133,6 @@ var renderTruthmarkRealizeProcedureBody = (config = defaultAgentConfig()) => {
4515
4133
 
4516
4134
  Use this skill only when the user explicitly asks to realize truth docs into code.
4517
4135
 
4518
- Invocations: OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Claude Code /truthmark-realize; GitHub Copilot /truthmark-realize; Gemini CLI /truthmark:realize.
4519
-
4520
4136
  Truth Realize is doc-first:
4521
4137
 
4522
4138
  - truth docs lead
@@ -4554,20 +4170,6 @@ var renderTruthmarkRealizeSkillMetadata = () => {
4554
4170
  policy:
4555
4171
  allow_implicit_invocation: ${workflow.allowImplicitInvocation}
4556
4172
 
4557
- truthmark:
4558
- refresh_command: "truthmark init"
4559
- `;
4560
- };
4561
- var renderTruthmarkPreviewSkillMetadata = () => {
4562
- const workflow = getTruthmarkWorkflow("truthmark-preview");
4563
- return `interface:
4564
- display_name: "${workflow.displayName}"
4565
- short_description: "${workflow.shortDescription}"
4566
- default_prompt: "${workflow.defaultPrompt}"
4567
-
4568
- policy:
4569
- allow_implicit_invocation: ${workflow.allowImplicitInvocation}
4570
-
4571
4173
  truthmark:
4572
4174
  refresh_command: "truthmark init"
4573
4175
  `;
@@ -4600,17 +4202,41 @@ truthmark:
4600
4202
  refresh_command: "truthmark init"
4601
4203
  `;
4602
4204
  };
4603
- var renderGeminiWorkflowCommand = (workflowId, root) => {
4205
+ var renderWorkflowRuleFile = ({
4206
+ workflowId,
4207
+ hostName,
4208
+ ruleName,
4209
+ config = defaultAgentConfig()
4210
+ }) => {
4604
4211
  const workflow = getTruthmarkWorkflow(workflowId);
4605
- return renderGeminiCommand(
4606
- workflow.description,
4607
- renderWorkflowCommandAdapterInstructions(
4608
- workflowId,
4609
- root,
4610
- "Gemini CLI",
4611
- "command"
4612
- )
4212
+ const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
4213
+ const { procedure, reportTemplate } = renderWorkflowSupportParts(
4214
+ workflowId,
4215
+ config
4613
4216
  );
4217
+ const body = `# ${definition.title}
4218
+
4219
+ Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces.
4220
+
4221
+ This rule is the ${hostName} entrypoint for ${definition.title}.
4222
+
4223
+ Do not invoke another Truthmark command from here.
4224
+
4225
+ Manual invocation: @${ruleName}
4226
+
4227
+ If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure.
4228
+
4229
+ Description: ${workflow.description}
4230
+
4231
+ ## Procedure
4232
+
4233
+ ${procedure}
4234
+
4235
+ ## Report Template
4236
+
4237
+ ${reportTemplate}
4238
+ `;
4239
+ return body;
4614
4240
  };
4615
4241
  var renderCopilotWorkflowPrompt = (workflowId, root) => {
4616
4242
  const workflow = getTruthmarkWorkflow(workflowId);
@@ -4624,55 +4250,42 @@ var renderCopilotWorkflowPrompt = (workflowId, root) => {
4624
4250
  )
4625
4251
  );
4626
4252
  };
4627
- var renderTruthmarkGeminiStructureCommand = (config = defaultAgentConfig()) => {
4628
- void config;
4629
- return renderGeminiWorkflowCommand(
4630
- "truthmark-structure",
4631
- ".gemini/skills/truthmark-structure"
4632
- );
4633
- };
4634
- var renderTruthmarkGeminiDocumentCommand = (config = defaultAgentConfig()) => {
4635
- void config;
4636
- return renderGeminiWorkflowCommand(
4637
- "truthmark-document",
4638
- ".gemini/skills/truthmark-document"
4639
- );
4640
- };
4641
- var renderTruthmarkGeminiSyncCommand = (config = defaultAgentConfig()) => {
4642
- void config;
4643
- return renderGeminiWorkflowCommand(
4644
- "truthmark-sync",
4645
- ".gemini/skills/truthmark-sync"
4646
- );
4647
- };
4648
- var renderTruthmarkGeminiRealizeCommand = (config = defaultAgentConfig()) => {
4649
- void config;
4650
- return renderGeminiWorkflowCommand(
4651
- "truthmark-realize",
4652
- ".gemini/skills/truthmark-realize"
4653
- );
4654
- };
4655
- var renderTruthmarkGeminiCheckCommand = (config = defaultAgentConfig()) => {
4656
- void config;
4657
- return renderGeminiWorkflowCommand(
4658
- "truthmark-check",
4659
- ".gemini/skills/truthmark-check"
4660
- );
4661
- };
4662
- var renderTruthmarkGeminiPreviewCommand = (config = defaultAgentConfig()) => {
4663
- void config;
4664
- return renderGeminiWorkflowCommand(
4665
- "truthmark-preview",
4666
- ".gemini/skills/truthmark-preview"
4667
- );
4668
- };
4669
- var renderTruthmarkGeminiPortalCommand = (config = defaultAgentConfig()) => {
4670
- void config;
4671
- return renderGeminiWorkflowCommand(
4672
- "truthmark-portal",
4673
- ".gemini/skills/truthmark-portal"
4674
- );
4675
- };
4253
+ var renderTruthmarkAntigravityStructureRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4254
+ workflowId: "truthmark-structure",
4255
+ hostName: "Antigravity",
4256
+ ruleName: "truthmark-structure",
4257
+ config
4258
+ });
4259
+ var renderTruthmarkAntigravityDocumentRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4260
+ workflowId: "truthmark-document",
4261
+ hostName: "Antigravity",
4262
+ ruleName: "truthmark-document",
4263
+ config
4264
+ });
4265
+ var renderTruthmarkAntigravitySyncRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4266
+ workflowId: "truthmark-sync",
4267
+ hostName: "Antigravity",
4268
+ ruleName: "truthmark-sync",
4269
+ config
4270
+ });
4271
+ var renderTruthmarkAntigravityRealizeRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4272
+ workflowId: "truthmark-realize",
4273
+ hostName: "Antigravity",
4274
+ ruleName: "truthmark-realize",
4275
+ config
4276
+ });
4277
+ var renderTruthmarkAntigravityCheckRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4278
+ workflowId: "truthmark-check",
4279
+ hostName: "Antigravity",
4280
+ ruleName: "truthmark-check",
4281
+ config
4282
+ });
4283
+ var renderTruthmarkAntigravityPortalRule = (config = defaultAgentConfig()) => renderWorkflowRuleFile({
4284
+ workflowId: "truthmark-portal",
4285
+ hostName: "Antigravity",
4286
+ ruleName: "truthmark-portal",
4287
+ config
4288
+ });
4676
4289
  var renderTruthmarkCopilotStructurePrompt = (config = defaultAgentConfig()) => {
4677
4290
  void config;
4678
4291
  return renderCopilotWorkflowPrompt(
@@ -4708,13 +4321,6 @@ var renderTruthmarkCopilotCheckPrompt = (config = defaultAgentConfig()) => {
4708
4321
  ".github/skills/truthmark-check"
4709
4322
  );
4710
4323
  };
4711
- var renderTruthmarkCopilotPreviewPrompt = (config = defaultAgentConfig()) => {
4712
- void config;
4713
- return renderCopilotWorkflowPrompt(
4714
- "truthmark-preview",
4715
- ".github/skills/truthmark-preview"
4716
- );
4717
- };
4718
4324
  var renderTruthmarkCopilotPortalPrompt = (config = defaultAgentConfig()) => {
4719
4325
  void config;
4720
4326
  return renderCopilotWorkflowPrompt(
@@ -4757,24 +4363,14 @@ var codexFiles = (config) => {
4757
4363
  content: renderTruthmarkSyncSkillMetadata()
4758
4364
  },
4759
4365
  ...renderTruthmarkSkillPackage({
4760
- skillPath: TRUTHMARK_PREVIEW_SKILL_PATH,
4761
- workflowId: "truthmark-preview",
4366
+ skillPath: TRUTHMARK_CHECK_SKILL_PATH,
4367
+ workflowId: "truthmark-check",
4762
4368
  host: "codex",
4763
4369
  config
4764
4370
  }),
4765
4371
  {
4766
- path: TRUTHMARK_PREVIEW_SKILL_METADATA_PATH,
4767
- content: renderTruthmarkPreviewSkillMetadata()
4768
- },
4769
- ...renderTruthmarkSkillPackage({
4770
- skillPath: TRUTHMARK_CHECK_SKILL_PATH,
4771
- workflowId: "truthmark-check",
4772
- host: "codex",
4773
- config
4774
- }),
4775
- {
4776
- path: TRUTHMARK_CHECK_SKILL_METADATA_PATH,
4777
- content: renderTruthmarkCheckSkillMetadata()
4372
+ path: TRUTHMARK_CHECK_SKILL_METADATA_PATH,
4373
+ content: renderTruthmarkCheckSkillMetadata()
4778
4374
  },
4779
4375
  ...renderTruthmarkSkillPackage({
4780
4376
  skillPath: TRUTHMARK_REALIZE_SKILL_PATH,
@@ -4839,12 +4435,6 @@ var opencodeFiles = (config) => {
4839
4435
  host: "opencode",
4840
4436
  config
4841
4437
  }),
4842
- ...renderTruthmarkSkillPackage({
4843
- skillPath: ".opencode/skills/truthmark-preview/SKILL.md",
4844
- workflowId: "truthmark-preview",
4845
- host: "opencode",
4846
- config
4847
- }),
4848
4438
  ...renderTruthmarkSkillPackage({
4849
4439
  skillPath: ".opencode/skills/truthmark-check/SKILL.md",
4850
4440
  workflowId: "truthmark-check",
@@ -4907,12 +4497,6 @@ var claudeFiles = (config, block) => {
4907
4497
  host: "claude-code",
4908
4498
  config
4909
4499
  }),
4910
- ...renderTruthmarkSkillPackage({
4911
- skillPath: ".claude/skills/truthmark-preview/SKILL.md",
4912
- workflowId: "truthmark-preview",
4913
- host: "claude-code",
4914
- config
4915
- }),
4916
4500
  ...renderTruthmarkSkillPackage({
4917
4501
  skillPath: ".claude/skills/truthmark-check/SKILL.md",
4918
4502
  workflowId: "truthmark-check",
@@ -4975,12 +4559,6 @@ var copilotFiles = (config, block) => {
4975
4559
  host: "github-copilot",
4976
4560
  config
4977
4561
  }),
4978
- ...renderTruthmarkSkillPackage({
4979
- skillPath: ".github/skills/truthmark-preview/SKILL.md",
4980
- workflowId: "truthmark-preview",
4981
- host: "github-copilot",
4982
- config
4983
- }),
4984
4562
  ...renderTruthmarkSkillPackage({
4985
4563
  skillPath: ".github/skills/truthmark-check/SKILL.md",
4986
4564
  workflowId: "truthmark-check",
@@ -5005,10 +4583,6 @@ var copilotFiles = (config, block) => {
5005
4583
  path: TRUTHMARK_COPILOT_SYNC_PROMPT_PATH,
5006
4584
  content: renderTruthmarkCopilotSyncPrompt(config)
5007
4585
  },
5008
- {
5009
- path: TRUTHMARK_COPILOT_PREVIEW_PROMPT_PATH,
5010
- content: renderTruthmarkCopilotPreviewPrompt(config)
5011
- },
5012
4586
  {
5013
4587
  path: TRUTHMARK_COPILOT_CHECK_PROMPT_PATH,
5014
4588
  content: renderTruthmarkCopilotCheckPrompt(config)
@@ -5050,98 +4624,78 @@ var copilotFiles = (config, block) => {
5050
4624
  }
5051
4625
  return files;
5052
4626
  };
5053
- var geminiFiles = (config, block) => {
4627
+ var antigravityFiles = (config) => {
4628
+ const files = [
4629
+ {
4630
+ path: TRUTHMARK_ANTIGRAVITY_STRUCTURE_RULE_PATH,
4631
+ content: renderTruthmarkAntigravityStructureRule(config)
4632
+ },
4633
+ {
4634
+ path: TRUTHMARK_ANTIGRAVITY_DOCUMENT_RULE_PATH,
4635
+ content: renderTruthmarkAntigravityDocumentRule(config)
4636
+ },
4637
+ {
4638
+ path: TRUTHMARK_ANTIGRAVITY_SYNC_RULE_PATH,
4639
+ content: renderTruthmarkAntigravitySyncRule(config)
4640
+ },
4641
+ {
4642
+ path: TRUTHMARK_ANTIGRAVITY_CHECK_RULE_PATH,
4643
+ content: renderTruthmarkAntigravityCheckRule(config)
4644
+ },
4645
+ {
4646
+ path: TRUTHMARK_ANTIGRAVITY_REALIZE_RULE_PATH,
4647
+ content: renderTruthmarkAntigravityRealizeRule(config)
4648
+ }
4649
+ ];
4650
+ if (config.truthmark.generated.portal.enabled) {
4651
+ files.push({
4652
+ path: TRUTHMARK_ANTIGRAVITY_PORTAL_RULE_PATH,
4653
+ content: renderTruthmarkAntigravityPortalRule(config)
4654
+ });
4655
+ }
4656
+ return files;
4657
+ };
4658
+ var cursorFiles = (config) => {
5054
4659
  const files = [
5055
- ...instructionBlockFiles(["GEMINI.md"], block),
5056
4660
  ...renderTruthmarkSkillPackage({
5057
- skillPath: ".gemini/skills/truthmark-structure/SKILL.md",
4661
+ skillPath: TRUTHMARK_CURSOR_STRUCTURE_SKILL_PATH,
5058
4662
  workflowId: "truthmark-structure",
5059
- host: "gemini-cli",
4663
+ host: "cursor",
5060
4664
  config
5061
4665
  }),
5062
4666
  ...renderTruthmarkSkillPackage({
5063
- skillPath: ".gemini/skills/truthmark-document/SKILL.md",
4667
+ skillPath: TRUTHMARK_CURSOR_DOCUMENT_SKILL_PATH,
5064
4668
  workflowId: "truthmark-document",
5065
- host: "gemini-cli",
4669
+ host: "cursor",
5066
4670
  config
5067
4671
  }),
5068
4672
  ...renderTruthmarkSkillPackage({
5069
- skillPath: ".gemini/skills/truthmark-sync/SKILL.md",
4673
+ skillPath: TRUTHMARK_CURSOR_SYNC_SKILL_PATH,
5070
4674
  workflowId: "truthmark-sync",
5071
- host: "gemini-cli",
5072
- config
5073
- }),
5074
- ...renderTruthmarkSkillPackage({
5075
- skillPath: ".gemini/skills/truthmark-preview/SKILL.md",
5076
- workflowId: "truthmark-preview",
5077
- host: "gemini-cli",
4675
+ host: "cursor",
5078
4676
  config
5079
4677
  }),
5080
4678
  ...renderTruthmarkSkillPackage({
5081
- skillPath: ".gemini/skills/truthmark-check/SKILL.md",
4679
+ skillPath: TRUTHMARK_CURSOR_CHECK_SKILL_PATH,
5082
4680
  workflowId: "truthmark-check",
5083
- host: "gemini-cli",
4681
+ host: "cursor",
5084
4682
  config
5085
4683
  }),
5086
4684
  ...renderTruthmarkSkillPackage({
5087
- skillPath: ".gemini/skills/truthmark-realize/SKILL.md",
4685
+ skillPath: TRUTHMARK_CURSOR_REALIZE_SKILL_PATH,
5088
4686
  workflowId: "truthmark-realize",
5089
- host: "gemini-cli",
4687
+ host: "cursor",
5090
4688
  config
5091
- }),
5092
- {
5093
- path: TRUTHMARK_GEMINI_STRUCTURE_COMMAND_PATH,
5094
- content: renderTruthmarkGeminiStructureCommand(config)
5095
- },
5096
- {
5097
- path: TRUTHMARK_GEMINI_DOCUMENT_COMMAND_PATH,
5098
- content: renderTruthmarkGeminiDocumentCommand(config)
5099
- },
5100
- {
5101
- path: TRUTHMARK_GEMINI_SYNC_COMMAND_PATH,
5102
- content: renderTruthmarkGeminiSyncCommand(config)
5103
- },
5104
- {
5105
- path: TRUTHMARK_GEMINI_PREVIEW_COMMAND_PATH,
5106
- content: renderTruthmarkGeminiPreviewCommand(config)
5107
- },
5108
- {
5109
- path: TRUTHMARK_GEMINI_CHECK_COMMAND_PATH,
5110
- content: renderTruthmarkGeminiCheckCommand(config)
5111
- },
5112
- {
5113
- path: TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH,
5114
- content: renderTruthmarkGeminiRealizeCommand(config)
5115
- },
5116
- {
5117
- path: TRUTHMARK_GEMINI_ROUTE_AUDITOR_AGENT_PATH,
5118
- content: renderTruthmarkGeminiRouteAuditorAgent()
5119
- },
5120
- {
5121
- path: TRUTHMARK_GEMINI_CLAIM_VERIFIER_AGENT_PATH,
5122
- content: renderTruthmarkGeminiClaimVerifierAgent()
5123
- },
5124
- {
5125
- path: TRUTHMARK_GEMINI_DOC_REVIEWER_AGENT_PATH,
5126
- content: renderTruthmarkGeminiDocReviewerAgent()
5127
- },
5128
- {
5129
- path: TRUTHMARK_GEMINI_DOC_WRITER_AGENT_PATH,
5130
- content: renderTruthmarkGeminiDocWriterAgent()
5131
- }
4689
+ })
5132
4690
  ];
5133
4691
  if (config.truthmark.generated.portal.enabled) {
5134
4692
  files.push(
5135
4693
  ...renderTruthmarkSkillPackage({
5136
- skillPath: ".gemini/skills/truthmark-portal/SKILL.md",
4694
+ skillPath: TRUTHMARK_CURSOR_PORTAL_SKILL_PATH,
5137
4695
  workflowId: "truthmark-portal",
5138
- host: "gemini-cli",
4696
+ host: "cursor",
5139
4697
  config
5140
- }),
5141
- {
5142
- path: TRUTHMARK_GEMINI_PORTAL_COMMAND_PATH,
5143
- content: renderTruthmarkGeminiPortalCommand(config)
5144
- }
4698
+ })
5145
4699
  );
5146
4700
  }
5147
4701
  return files;
@@ -5163,8 +4717,10 @@ var filesForPlatform = (platform, config, block) => {
5163
4717
  return claudeFiles(config, block);
5164
4718
  case "github-copilot":
5165
4719
  return copilotFiles(config, block);
5166
- case "gemini-cli":
5167
- return geminiFiles(config, block);
4720
+ case "antigravity":
4721
+ return antigravityFiles(config);
4722
+ case "cursor":
4723
+ return cursorFiles(config);
5168
4724
  }
5169
4725
  };
5170
4726
  var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
@@ -5179,6 +4735,208 @@ var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
5179
4735
  ).sort((left, right) => left.path.localeCompare(right.path));
5180
4736
  };
5181
4737
 
4738
+ // src/checks/generated-surfaces.ts
4739
+ var readOptionalFile = async (rootDir, filePath) => {
4740
+ try {
4741
+ return await fs6.readFile(resolveRepoPath(rootDir, filePath), "utf8");
4742
+ } catch (error) {
4743
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
4744
+ return null;
4745
+ }
4746
+ throw error;
4747
+ }
4748
+ };
4749
+ var extractManagedBlock = (content) => {
4750
+ const startIndex = content.indexOf(TRUTHMARK_BLOCK_START);
4751
+ const endIndex = content.indexOf(TRUTHMARK_BLOCK_END);
4752
+ if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
4753
+ return null;
4754
+ }
4755
+ return content.slice(startIndex, endIndex + TRUTHMARK_BLOCK_END.length);
4756
+ };
4757
+ var normalizeGeneratedSurfaceContent = (content) => {
4758
+ if (content === null) {
4759
+ return null;
4760
+ }
4761
+ return content.replace(/\r\n/g, "\n").replace(/\n$/u, "");
4762
+ };
4763
+ var GENERATED_HOST_SKILL_ROOTS = [
4764
+ ".agents/skills",
4765
+ ".opencode/skills",
4766
+ ".claude/skills",
4767
+ ".github/skills",
4768
+ ".cursor/skills"
4769
+ ];
4770
+ var RETIRED_SKILL_HELPER_PATHS = [
4771
+ "helper-manifest.yml",
4772
+ "support/helper-policy.md"
4773
+ ];
4774
+ var RETIRED_PACKAGE_DIRECTORIES = ["truthmark-preview"];
4775
+ var RETIRED_GENERATED_SURFACE_PATHS = [
4776
+ "GEMINI.md",
4777
+ ".github/prompts/truthmark-preview.prompt.md",
4778
+ ".cursor/rules/truthmark-structure.mdc",
4779
+ ".cursor/rules/truthmark-document.mdc",
4780
+ ".cursor/rules/truthmark-sync.mdc",
4781
+ ".cursor/rules/truthmark-realize.mdc",
4782
+ ".cursor/rules/truthmark-check.mdc",
4783
+ ".cursor/rules/truthmark-portal.mdc"
4784
+ ];
4785
+ var RETIRED_GENERATED_SURFACE_ROOTS = [".gemini"];
4786
+ var isRetiredGeminiSurfacePath = (filePath) => filePath === "GEMINI.md" || filePath.startsWith(".gemini/");
4787
+ var obsoleteGeneratedSurfaceMessage = (surfacePath) => {
4788
+ if (isRetiredGeminiSurfacePath(surfacePath)) {
4789
+ return `Generated surface ${surfacePath} is obsolete; remove stale Gemini instructions manually if they are no longer wanted.`;
4790
+ }
4791
+ return `Generated surface ${surfacePath} is obsolete; rerun truthmark init.`;
4792
+ };
4793
+ var pathExists = async (absolutePath) => {
4794
+ try {
4795
+ await fs6.access(absolutePath);
4796
+ return true;
4797
+ } catch (error) {
4798
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
4799
+ return false;
4800
+ }
4801
+ throw error;
4802
+ }
4803
+ };
4804
+ var listDirectoryFiles = async (rootDir, packageRoot) => {
4805
+ const stack = [packageRoot];
4806
+ const files = [];
4807
+ while (stack.length > 0) {
4808
+ const current = stack.pop();
4809
+ if (current === void 0) {
4810
+ continue;
4811
+ }
4812
+ const absoluteCurrent = resolveRepoPath(rootDir, current);
4813
+ const entries = await fs6.readdir(absoluteCurrent, {
4814
+ withFileTypes: true
4815
+ });
4816
+ for (const entry of entries) {
4817
+ const next = `${current}/${entry.name}`;
4818
+ if (entry.isDirectory()) {
4819
+ stack.push(next);
4820
+ } else {
4821
+ files.push(next);
4822
+ }
4823
+ }
4824
+ }
4825
+ return files;
4826
+ };
4827
+ var collectRetiredGeneratedSurfaces = async (rootDir, expectedSurfacePaths, options = {}) => {
4828
+ const legacyCandidates = /* @__PURE__ */ new Set();
4829
+ const includeGeminiSurfaces = options.includeGeminiSurfaces ?? true;
4830
+ for (const retiredPath of RETIRED_GENERATED_SURFACE_PATHS) {
4831
+ if (!includeGeminiSurfaces && isRetiredGeminiSurfacePath(retiredPath)) {
4832
+ continue;
4833
+ }
4834
+ const absoluteRetiredPath = resolveRepoPath(rootDir, retiredPath);
4835
+ if (await pathExists(absoluteRetiredPath) && !expectedSurfacePaths.has(retiredPath)) {
4836
+ legacyCandidates.add(retiredPath);
4837
+ }
4838
+ }
4839
+ for (const retiredRoot of RETIRED_GENERATED_SURFACE_ROOTS) {
4840
+ if (!includeGeminiSurfaces && isRetiredGeminiSurfacePath(`${retiredRoot}/`)) {
4841
+ continue;
4842
+ }
4843
+ const absoluteRetiredRoot = resolveRepoPath(rootDir, retiredRoot);
4844
+ if (!await pathExists(absoluteRetiredRoot)) {
4845
+ continue;
4846
+ }
4847
+ const retiredFiles = await listDirectoryFiles(rootDir, retiredRoot);
4848
+ for (const filePath of retiredFiles) {
4849
+ if (!expectedSurfacePaths.has(filePath)) {
4850
+ legacyCandidates.add(filePath);
4851
+ }
4852
+ }
4853
+ }
4854
+ for (const skillRoot of GENERATED_HOST_SKILL_ROOTS) {
4855
+ const absoluteSkillRoot = resolveRepoPath(rootDir, skillRoot);
4856
+ let skillPackages = [];
4857
+ try {
4858
+ skillPackages = await fs6.readdir(absoluteSkillRoot, {
4859
+ withFileTypes: true
4860
+ });
4861
+ } catch (error) {
4862
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
4863
+ continue;
4864
+ }
4865
+ throw error;
4866
+ }
4867
+ const packageNames = skillPackages.filter((entry) => entry.isDirectory() && entry.name.startsWith("truthmark-")).map((entry) => entry.name);
4868
+ for (const packageName of RETIRED_PACKAGE_DIRECTORIES) {
4869
+ if (!packageNames.includes(packageName)) {
4870
+ continue;
4871
+ }
4872
+ const packageRoot = `${skillRoot}/${packageName}`;
4873
+ const packageFiles = await listDirectoryFiles(rootDir, packageRoot);
4874
+ for (const filePath of packageFiles) {
4875
+ if (!expectedSurfacePaths.has(filePath)) {
4876
+ legacyCandidates.add(filePath);
4877
+ }
4878
+ }
4879
+ }
4880
+ for (const packageName of packageNames) {
4881
+ for (const retiredName of RETIRED_SKILL_HELPER_PATHS) {
4882
+ const retiredPath = `${packageName}/${retiredName}`;
4883
+ const relativeRetiredPath = `${skillRoot}/${retiredPath}`;
4884
+ const absoluteRetiredPath = resolveRepoPath(rootDir, relativeRetiredPath);
4885
+ if (await pathExists(absoluteRetiredPath) && !expectedSurfacePaths.has(relativeRetiredPath)) {
4886
+ legacyCandidates.add(relativeRetiredPath);
4887
+ }
4888
+ }
4889
+ }
4890
+ }
4891
+ return Array.from(legacyCandidates);
4892
+ };
4893
+ var checkGeneratedSurfaces = async (rootDir, config) => {
4894
+ const diagnostics = [];
4895
+ const renderedSurfaces = renderGeneratedSurfaces(config);
4896
+ for (const surface of renderedSurfaces) {
4897
+ const content = await readOptionalFile(rootDir, surface.path);
4898
+ if (content === null) {
4899
+ diagnostics.push({
4900
+ category: "generated-surface",
4901
+ severity: "review",
4902
+ message: `Generated surface ${surface.path} is missing; rerun truthmark init.`,
4903
+ file: surface.path
4904
+ });
4905
+ continue;
4906
+ }
4907
+ const comparableContent = normalizeGeneratedSurfaceContent(
4908
+ surface.managedBlock ? extractManagedBlock(content) : content
4909
+ );
4910
+ const expectedContent = normalizeGeneratedSurfaceContent(surface.content);
4911
+ if (comparableContent !== expectedContent) {
4912
+ diagnostics.push({
4913
+ category: "generated-surface",
4914
+ severity: "review",
4915
+ message: `Generated surface ${surface.path} is stale; rerun truthmark init.`,
4916
+ file: surface.path
4917
+ });
4918
+ }
4919
+ }
4920
+ const staleSurfaces = await collectRetiredGeneratedSurfaces(
4921
+ rootDir,
4922
+ new Set(renderedSurfaces.map((surface) => surface.path))
4923
+ );
4924
+ for (const surfacePath of staleSurfaces) {
4925
+ diagnostics.push({
4926
+ category: "generated-surface",
4927
+ severity: "review",
4928
+ message: obsoleteGeneratedSurfaceMessage(surfacePath),
4929
+ file: surfacePath
4930
+ });
4931
+ }
4932
+ return diagnostics;
4933
+ };
4934
+ var findAutoRemovableRetiredGeneratedSurfaces = async (rootDir, expectedSurfacePaths) => {
4935
+ return collectRetiredGeneratedSurfaces(rootDir, expectedSurfacePaths, {
4936
+ includeGeminiSurfaces: false
4937
+ });
4938
+ };
4939
+
5182
4940
  // src/init/init.ts
5183
4941
  var escapeRegExp = (value) => {
5184
4942
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -5275,7 +5033,7 @@ ${block}`;
5275
5033
  var writeManagedAgentsFile = async (rootDir, path12 = "AGENTS.md", block) => {
5276
5034
  let existingContent = null;
5277
5035
  try {
5278
- existingContent = await fs6.readFile(resolveRepoPath(rootDir, path12), "utf8");
5036
+ existingContent = await fs7.readFile(resolveRepoPath(rootDir, path12), "utf8");
5279
5037
  } catch (error) {
5280
5038
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
5281
5039
  throw error;
@@ -5287,21 +5045,15 @@ var diagnosticCategoryForPath = (filePath, config) => {
5287
5045
  if (filePath === "AGENTS.md") {
5288
5046
  return "truth-sync";
5289
5047
  }
5290
- if (filePath === ".github/prompts/truthmark-realize.prompt.md" || filePath.startsWith(".github/skills/truthmark-realize/") || filePath.startsWith(".claude/skills/truthmark-realize/") || filePath.startsWith(".opencode/skills/truthmark-realize/") || filePath.startsWith(".agents/skills/truthmark-realize/") || filePath.startsWith(".gemini/skills/truthmark-realize/")) {
5048
+ if (filePath === ".github/prompts/truthmark-realize.prompt.md" || filePath.startsWith(".github/skills/truthmark-realize/") || filePath.startsWith(".claude/skills/truthmark-realize/") || filePath.startsWith(".opencode/skills/truthmark-realize/") || filePath.startsWith(".agents/skills/truthmark-realize/") || filePath.startsWith(".antigravity/rules/truthmark-realize") || filePath.startsWith(".cursor/rules/truthmark-realize") || filePath.startsWith(".cursor/skills/truthmark-realize/")) {
5291
5049
  return "realization";
5292
5050
  }
5293
- if (filePath === "CLAUDE.md" || filePath === "GEMINI.md" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".github/prompts/truthmark-") || filePath.startsWith(".github/agents/truth-") || filePath.startsWith(".github/skills/truthmark-") || filePath.startsWith(".claude/agents/truth-") || filePath.startsWith(".claude/skills/truthmark-") || filePath.startsWith(".opencode/skills/truthmark-") || filePath.startsWith(".opencode/agents/") || filePath.startsWith(".codex/agents/") || filePath.startsWith(".gemini/agents/truth-") || filePath.startsWith(".gemini/skills/truthmark-")) {
5051
+ if (filePath === "CLAUDE.md" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".github/prompts/truthmark-") || filePath.startsWith(".github/agents/truth-") || filePath.startsWith(".github/skills/truthmark-") || filePath.startsWith(".claude/agents/truth-") || filePath.startsWith(".claude/skills/truthmark-") || filePath.startsWith(".opencode/skills/truthmark-") || filePath.startsWith(".opencode/agents/") || filePath.startsWith(".codex/agents/") || filePath.startsWith(".antigravity/rules/truthmark-") || filePath.startsWith(".cursor/rules/truthmark-") || filePath.startsWith(".cursor/skills/truthmark-")) {
5294
5052
  return "truth-sync";
5295
5053
  }
5296
5054
  if (filePath.startsWith(".agents/skills/truthmark-")) {
5297
5055
  return "truth-sync";
5298
5056
  }
5299
- if (filePath.startsWith(".gemini/commands/truthmark/realize")) {
5300
- return "realization";
5301
- }
5302
- if (filePath.startsWith(".gemini/commands/truthmark/")) {
5303
- return "truth-sync";
5304
- }
5305
5057
  if (filePath === config.truthmark.paths.routesIndex) {
5306
5058
  return "area-index";
5307
5059
  }
@@ -5354,9 +5106,17 @@ var runInit = async (cwd) => {
5354
5106
  results.push(...await scaffoldHierarchy(rootDir, config));
5355
5107
  const block = renderAgentsBlock(config);
5356
5108
  const platformFiles = renderGeneratedSurfaces(config, block);
5109
+ const expectedSurfacePaths = new Set(platformFiles.map((file) => file.path));
5357
5110
  for (const file of platformFiles) {
5358
5111
  results.push(await writePlatformFile(rootDir, file));
5359
5112
  }
5113
+ const obsoleteSurfacePaths = await findAutoRemovableRetiredGeneratedSurfaces(
5114
+ rootDir,
5115
+ expectedSurfacePaths
5116
+ );
5117
+ for (const obsoletePath of obsoleteSurfacePaths) {
5118
+ await fs7.rm(resolveRepoPath(rootDir, obsoletePath), { force: true });
5119
+ }
5360
5120
  const changedResults = results.filter((result) => result.status !== "unchanged");
5361
5121
  return {
5362
5122
  command: "init",
@@ -5373,7 +5133,7 @@ var runInit = async (cwd) => {
5373
5133
  };
5374
5134
 
5375
5135
  // src/checks/branch-scope.ts
5376
- import fs7 from "fs/promises";
5136
+ import fs8 from "fs/promises";
5377
5137
  import fg from "fast-glob";
5378
5138
 
5379
5139
  // src/markdown/hash.ts
@@ -5429,7 +5189,7 @@ var getBranchScopeData = async (cwd) => {
5429
5189
  }
5430
5190
  for (const relativePath of [...relevantFiles].sort()) {
5431
5191
  try {
5432
- const source = await fs7.readFile(resolveWorktreePath(repository, relativePath), "utf8");
5192
+ const source = await fs8.readFile(resolveWorktreePath(repository, relativePath), "utf8");
5433
5193
  relevantFileHashes[relativePath] = hashText(source);
5434
5194
  } catch (error) {
5435
5195
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -5446,14 +5206,14 @@ var getBranchScopeData = async (cwd) => {
5446
5206
  };
5447
5207
 
5448
5208
  // src/checks/authority.ts
5449
- import fs8 from "fs/promises";
5209
+ import fs9 from "fs/promises";
5450
5210
  import fg2 from "fast-glob";
5451
5211
  var looksLikeGlob = (pattern) => {
5452
5212
  return /[*?[\]{}()!+@]/u.test(pattern);
5453
5213
  };
5454
- var pathExists = async (absolutePath) => {
5214
+ var pathExists2 = async (absolutePath) => {
5455
5215
  try {
5456
- await fs8.stat(absolutePath);
5216
+ await fs9.stat(absolutePath);
5457
5217
  return true;
5458
5218
  } catch (error) {
5459
5219
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -5521,7 +5281,7 @@ var checkControlledPaths = async (rootDir, controlledPaths) => {
5521
5281
  });
5522
5282
  continue;
5523
5283
  }
5524
- if (!await pathExists(absoluteEntryPath)) {
5284
+ if (!await pathExists2(absoluteEntryPath)) {
5525
5285
  diagnostics.push({
5526
5286
  category: "authority",
5527
5287
  severity: "error",
@@ -5545,7 +5305,7 @@ var checkAuthority = async (rootDir, config) => {
5545
5305
  };
5546
5306
 
5547
5307
  // src/checks/frontmatter.ts
5548
- import fs9 from "fs/promises";
5308
+ import fs10 from "fs/promises";
5549
5309
 
5550
5310
  // src/markdown/frontmatter.ts
5551
5311
  import { parse as parse3 } from "yaml";
@@ -5647,7 +5407,7 @@ var checkFrontmatter = async (rootDir, config, markdownPaths, truthDocumentEntri
5647
5407
  }
5648
5408
  const absolutePath = resolveRepoPath(rootDir, markdownPath);
5649
5409
  await assertRepoContainment(rootDir, absolutePath);
5650
- const source = await fs9.readFile(absolutePath, "utf8");
5410
+ const source = await fs10.readFile(absolutePath, "utf8");
5651
5411
  let document;
5652
5412
  try {
5653
5413
  parseFrontmatter(source, { throwOnInvalid: true });
@@ -5737,11 +5497,11 @@ var checkFrontmatter = async (rootDir, config, markdownPaths, truthDocumentEntri
5737
5497
  };
5738
5498
 
5739
5499
  // src/checks/links.ts
5740
- import fs10 from "fs/promises";
5500
+ import fs11 from "fs/promises";
5741
5501
  import path5 from "path";
5742
- var pathExists2 = async (absolutePath) => {
5502
+ var pathExists3 = async (absolutePath) => {
5743
5503
  try {
5744
- await fs10.stat(absolutePath);
5504
+ await fs11.stat(absolutePath);
5745
5505
  return true;
5746
5506
  } catch (error) {
5747
5507
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -5757,7 +5517,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
5757
5517
  continue;
5758
5518
  }
5759
5519
  const absolutePath = resolveRepoPath(rootDir, markdownPath);
5760
- const source = await fs10.readFile(absolutePath, "utf8");
5520
+ const source = await fs11.readFile(absolutePath, "utf8");
5761
5521
  let document;
5762
5522
  try {
5763
5523
  document = parseMarkdownDocument(source);
@@ -5785,7 +5545,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
5785
5545
  });
5786
5546
  continue;
5787
5547
  }
5788
- if (!await pathExists2(absoluteTarget)) {
5548
+ if (!await pathExists3(absoluteTarget)) {
5789
5549
  diagnostics.push({
5790
5550
  category: "links",
5791
5551
  severity: "error",
@@ -5799,12 +5559,12 @@ var checkLinks = async (rootDir, markdownPaths) => {
5799
5559
  };
5800
5560
 
5801
5561
  // src/checks/areas.ts
5802
- import fs12 from "fs/promises";
5562
+ import fs13 from "fs/promises";
5803
5563
  import fg4 from "fast-glob";
5804
5564
  import micromatch4 from "micromatch";
5805
5565
 
5806
5566
  // src/routing/area-resolver.ts
5807
- import fs11 from "fs/promises";
5567
+ import fs12 from "fs/promises";
5808
5568
  import fg3 from "fast-glob";
5809
5569
  import micromatch2 from "micromatch";
5810
5570
  var unique = (values) => {
@@ -5855,7 +5615,7 @@ var ensureChildPath = async (rootDir, areaFilesRoot, filePath) => {
5855
5615
  var readRouteFile = async (rootDir, filePath) => {
5856
5616
  try {
5857
5617
  return {
5858
- source: await fs11.readFile(resolveRepoPath(rootDir, filePath), "utf8"),
5618
+ source: await fs12.readFile(resolveRepoPath(rootDir, filePath), "utf8"),
5859
5619
  diagnostic: null
5860
5620
  };
5861
5621
  } catch (error) {
@@ -6136,7 +5896,7 @@ var classifyPath = (filePath, ignorePatterns) => {
6136
5896
  if (normalizedPath.startsWith(".truthmark/")) {
6137
5897
  return "derived";
6138
5898
  }
6139
- if (normalizedPath.startsWith(".agents/skills/truthmark-") || normalizedPath.startsWith(".claude/") || normalizedPath.startsWith(".codex/") || normalizedPath.startsWith(".gemini/agents/truth-") || normalizedPath.startsWith(".gemini/commands/") || normalizedPath.startsWith(".gemini/skills/truthmark-") || normalizedPath.startsWith(".opencode/") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath.startsWith(".github/agents/truth-") || normalizedPath.startsWith(".github/prompts/truthmark-") || normalizedPath.startsWith(".github/skills/truthmark-") || normalizedPath === "AGENTS.md" || normalizedPath === "CLAUDE.md" || normalizedPath === "GEMINI.md" || normalizedPath.startsWith(".gemini/commands/truthmark/")) {
5899
+ if (normalizedPath.startsWith(".agents/skills/truthmark-") || normalizedPath.startsWith(".claude/") || normalizedPath.startsWith(".codex/") || normalizedPath.startsWith(".opencode/") || normalizedPath.startsWith(".antigravity/rules/truthmark-") || normalizedPath.startsWith(".cursor/rules/truthmark-") || normalizedPath.startsWith(".cursor/skills/truthmark-") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath.startsWith(".github/agents/truth-") || normalizedPath.startsWith(".github/prompts/truthmark-") || normalizedPath.startsWith(".github/skills/truthmark-") || normalizedPath === "AGENTS.md" || normalizedPath === "CLAUDE.md") {
6140
5900
  return "derived";
6141
5901
  }
6142
5902
  if (ignorePatterns.length > 0 && micromatch3.isMatch(normalizedPath, ignorePatterns)) {
@@ -6161,9 +5921,9 @@ var classifyPath = (filePath, ignorePatterns) => {
6161
5921
  var looksLikeGlob2 = (pattern) => {
6162
5922
  return /[*?[\]{}()!+@]/u.test(pattern);
6163
5923
  };
6164
- var pathExists3 = async (absolutePath) => {
5924
+ var pathExists4 = async (absolutePath) => {
6165
5925
  try {
6166
- await fs12.stat(absolutePath);
5926
+ await fs13.stat(absolutePath);
6167
5927
  return true;
6168
5928
  } catch (error) {
6169
5929
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -6453,7 +6213,7 @@ var checkAreas = async (rootDir, config) => {
6453
6213
  areaHasTruthDocumentErrors = true;
6454
6214
  continue;
6455
6215
  }
6456
- if (!await pathExists3(absoluteTruthDocumentPath)) {
6216
+ if (!await pathExists4(absoluteTruthDocumentPath)) {
6457
6217
  diagnostics.push({
6458
6218
  category: "area-index",
6459
6219
  severity: "error",
@@ -6557,7 +6317,7 @@ var checkAreas = async (rootDir, config) => {
6557
6317
  entry.valid = false;
6558
6318
  continue;
6559
6319
  }
6560
- if (!await pathExists3(absoluteCodeSurfacePath)) {
6320
+ if (!await pathExists4(absoluteCodeSurfacePath)) {
6561
6321
  diagnostics.push({
6562
6322
  category: "area-index",
6563
6323
  severity: "error",
@@ -6604,7 +6364,7 @@ var checkAreas = async (rootDir, config) => {
6604
6364
  };
6605
6365
 
6606
6366
  // src/checks/decisions.ts
6607
- import fs13 from "fs/promises";
6367
+ import fs14 from "fs/promises";
6608
6368
  import micromatch5 from "micromatch";
6609
6369
  var PRODUCT_CAPABILITY_REQUIRED_HEADINGS = [
6610
6370
  "Capability Promise",
@@ -6720,7 +6480,7 @@ var checkDecisionSections = async (rootDir, config, markdownPaths, truthDocument
6720
6480
  (filePath) => truthDocumentMap.has(filePath) || isDecisionTruthCandidate(config, filePath)
6721
6481
  ).sort();
6722
6482
  for (const filePath of candidatePaths) {
6723
- const source = await fs13.readFile(
6483
+ const source = await fs14.readFile(
6724
6484
  resolveRepoPath(rootDir, filePath),
6725
6485
  "utf8"
6726
6486
  );
@@ -6761,61 +6521,6 @@ var checkDecisionSections = async (rootDir, config, markdownPaths, truthDocument
6761
6521
  return diagnostics;
6762
6522
  };
6763
6523
 
6764
- // src/checks/generated-surfaces.ts
6765
- import fs14 from "fs/promises";
6766
- var readOptionalFile = async (rootDir, filePath) => {
6767
- try {
6768
- return await fs14.readFile(resolveRepoPath(rootDir, filePath), "utf8");
6769
- } catch (error) {
6770
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
6771
- return null;
6772
- }
6773
- throw error;
6774
- }
6775
- };
6776
- var extractManagedBlock = (content) => {
6777
- const startIndex = content.indexOf(TRUTHMARK_BLOCK_START);
6778
- const endIndex = content.indexOf(TRUTHMARK_BLOCK_END);
6779
- if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
6780
- return null;
6781
- }
6782
- return content.slice(startIndex, endIndex + TRUTHMARK_BLOCK_END.length);
6783
- };
6784
- var normalizeGeneratedSurfaceContent = (content) => {
6785
- if (content === null) {
6786
- return null;
6787
- }
6788
- return content.replace(/\r\n/g, "\n").replace(/\n$/u, "");
6789
- };
6790
- var checkGeneratedSurfaces = async (rootDir, config) => {
6791
- const diagnostics = [];
6792
- for (const surface of renderGeneratedSurfaces(config)) {
6793
- const content = await readOptionalFile(rootDir, surface.path);
6794
- if (content === null) {
6795
- diagnostics.push({
6796
- category: "generated-surface",
6797
- severity: "review",
6798
- message: `Generated surface ${surface.path} is missing; rerun truthmark init.`,
6799
- file: surface.path
6800
- });
6801
- continue;
6802
- }
6803
- const comparableContent = normalizeGeneratedSurfaceContent(
6804
- surface.managedBlock ? extractManagedBlock(content) : content
6805
- );
6806
- const expectedContent = normalizeGeneratedSurfaceContent(surface.content);
6807
- if (comparableContent !== expectedContent) {
6808
- diagnostics.push({
6809
- category: "generated-surface",
6810
- severity: "review",
6811
- message: `Generated surface ${surface.path} is stale; rerun truthmark init.`,
6812
- file: surface.path
6813
- });
6814
- }
6815
- }
6816
- return diagnostics;
6817
- };
6818
-
6819
6524
  // src/impact/build.ts
6820
6525
  import path10 from "path";
6821
6526
  import micromatch7 from "micromatch";
@@ -7195,7 +6900,7 @@ var listChangedPaths = async (cwd, args) => {
7195
6900
  const result = await execa3("git", args, { cwd });
7196
6901
  return result.stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => normalizePath3(line));
7197
6902
  };
7198
- var pathExists4 = async (filePath) => {
6903
+ var pathExists5 = async (filePath) => {
7199
6904
  try {
7200
6905
  await fs17.access(filePath);
7201
6906
  return true;
@@ -7241,7 +6946,7 @@ var getUncommittedChanges = async (cwd) => {
7241
6946
  const deletedPathCandidates = /* @__PURE__ */ new Set([...stagedDeletedPaths, ...unstagedDeletedPaths]);
7242
6947
  for (const deletedPath of deletedPathCandidates) {
7243
6948
  const change = getOrCreateChange(changesByPath, deletedPath);
7244
- change.deleted = !await pathExists4(path9.join(rootDir, deletedPath));
6949
+ change.deleted = !await pathExists5(path9.join(rootDir, deletedPath));
7245
6950
  }
7246
6951
  return Array.from(changesByPath.values()).sort((left, right) => {
7247
6952
  return left.path.localeCompare(right.path);
@@ -7499,7 +7204,7 @@ var parseEvidenceReferences = async (rootDir, truthDocPath) => {
7499
7204
  };
7500
7205
 
7501
7206
  // src/evidence/validate.ts
7502
- var pathExists5 = async (filePath) => {
7207
+ var pathExists6 = async (filePath) => {
7503
7208
  try {
7504
7209
  await fs19.access(filePath);
7505
7210
  return true;
@@ -7575,7 +7280,7 @@ var validateReference = async (rootDir, reference) => {
7575
7280
  }
7576
7281
  const absolutePath = resolveRepoPath(rootDir, reference.path);
7577
7282
  await assertRepoContainment(rootDir, absolutePath);
7578
- if (!await pathExists5(absolutePath)) {
7283
+ if (!await pathExists6(absolutePath)) {
7579
7284
  diagnostics.push(diagnosticFor(reference, `Referenced file ${reference.path} does not exist.`));
7580
7285
  return diagnostics;
7581
7286
  }
@@ -7837,6 +7542,7 @@ var runCheck = async (cwd, options = {}) => {
7837
7542
 
7838
7543
  // src/workflow-state/build.ts
7839
7544
  import { execa as execa5 } from "execa";
7545
+ import micromatch8 from "micromatch";
7840
7546
 
7841
7547
  // src/workflow-state/action-context.ts
7842
7548
  var uniqueSorted3 = (values) => [...new Set(values.filter((value) => value.length > 0))].sort();
@@ -7870,7 +7576,7 @@ var baseContext = (manifestEntry, mode, allowedWritePaths, routeFiles, primaryTr
7870
7576
  writeLeaseRequired
7871
7577
  });
7872
7578
  var buildWorkflowActionContext = (manifestEntry, data = {}) => {
7873
- if (manifestEntry.id === "truthmark-preview" || manifestEntry.id === "truthmark-check") {
7579
+ if (manifestEntry.id === "truthmark-check") {
7874
7580
  return baseContext(manifestEntry, "read-only", [], [], [], [], [], false);
7875
7581
  }
7876
7582
  if (manifestEntry.id === "truthmark-sync" || manifestEntry.id === "truthmark-document") {
@@ -7946,7 +7652,7 @@ var helperCommandsFor2 = (workflow) => (TRUTHMARK_WORKFLOW_MANIFEST[workflow].he
7946
7652
  optional: helper.optional
7947
7653
  }));
7948
7654
  var uniqueSorted4 = (values) => [...new Set(values.filter((value) => value.length > 0))].sort();
7949
- var isWriteCapable = (workflow) => !["truthmark-preview", "truthmark-check"].includes(workflow);
7655
+ var isWriteCapable = (workflow) => workflow !== "truthmark-check";
7950
7656
  var DEFAULT_BASE_CANDIDATES = [
7951
7657
  "@{upstream}",
7952
7658
  "origin/main",
@@ -7974,9 +7680,67 @@ var selectComparisonBase = async (rootDir, suppliedBase) => {
7974
7680
  return null;
7975
7681
  };
7976
7682
  var routeFilesFor = (repoIndex) => uniqueSorted4(repoIndex.routeMap.routes.map((route) => route.sourcePath));
7977
- var candidateStaleTruthDocsFor = (indexedTruthDocs, primaryTruthDocs) => {
7683
+ var candidateStaleTruthDocsFor = (repoIndex, primaryTruthDocs, impactSet, diagnostics) => {
7684
+ const indexedTruthDocs = new Set(
7685
+ repoIndex.routeMap.routes.flatMap((route) => route.truthDocs)
7686
+ );
7978
7687
  const primary = new Set(primaryTruthDocs);
7979
- return indexedTruthDocs.filter((truthDoc) => !primary.has(truthDoc));
7688
+ const candidates = /* @__PURE__ */ new Set();
7689
+ const changedPaths = new Set(
7690
+ (impactSet?.changedFiles ?? []).flatMap((file) => [
7691
+ file.path,
7692
+ ...file.previousPath ? [file.previousPath] : []
7693
+ ])
7694
+ );
7695
+ const docEntries = new Map(
7696
+ repoIndex.routeMap.routes.flatMap((route) => route.truthDocumentEntries).map((entry) => [entry.path, entry])
7697
+ );
7698
+ const addCandidate = (truthDoc) => {
7699
+ if (indexedTruthDocs.has(truthDoc) && !primary.has(truthDoc)) {
7700
+ candidates.add(truthDoc);
7701
+ }
7702
+ };
7703
+ const linkedTruthDocs = (truthDoc) => {
7704
+ const entry = docEntries.get(truthDoc);
7705
+ return uniqueSorted4([
7706
+ ...entry?.realizedBy ?? [],
7707
+ ...entry?.realizes ?? [],
7708
+ ...entry?.dependsOn ?? [],
7709
+ ...[...docEntries.values()].filter(
7710
+ (candidate) => candidate.realizedBy.includes(truthDoc) || candidate.realizes.includes(truthDoc) || candidate.dependsOn.includes(truthDoc)
7711
+ ).map((candidate) => candidate.path)
7712
+ ]);
7713
+ };
7714
+ for (const truthDoc of [...primary, ...changedPaths].filter(
7715
+ (path12) => indexedTruthDocs.has(path12)
7716
+ )) {
7717
+ for (const linkedTruthDoc of linkedTruthDocs(truthDoc)) {
7718
+ addCandidate(linkedTruthDoc);
7719
+ }
7720
+ }
7721
+ for (const diagnostic of diagnostics) {
7722
+ if (diagnostic.category === "freshness" && diagnostic.file) {
7723
+ addCandidate(diagnostic.file);
7724
+ }
7725
+ }
7726
+ for (const route of repoIndex.routeMap.routes) {
7727
+ if (changedPaths.has(route.sourcePath)) {
7728
+ route.truthDocs.forEach(addCandidate);
7729
+ }
7730
+ }
7731
+ for (const doc of repoIndex.docs) {
7732
+ if (!indexedTruthDocs.has(doc.path) || primary.has(doc.path)) {
7733
+ continue;
7734
+ }
7735
+ if (doc.sourceOfTruth.some(
7736
+ (reference) => [...changedPaths].some(
7737
+ (changedPath) => reference === changedPath || micromatch8.isMatch(changedPath, reference)
7738
+ )
7739
+ )) {
7740
+ candidates.add(doc.path);
7741
+ }
7742
+ }
7743
+ return uniqueSorted4([...candidates]);
7980
7744
  };
7981
7745
  var hasUnmappedFunctionalChange = (impactSet) => impactSet?.diagnostics.some(
7982
7746
  (diagnostic) => diagnostic.category === "impact" && /not mapped to a Truthmark route|no affected truth document/u.test(
@@ -8042,7 +7806,7 @@ var workflowCardFor = (workflow, applicability, diagnostics, impactSet) => {
8042
7806
  }))
8043
7807
  };
8044
7808
  };
8045
- var contextDataFor = (workflow, repoIndex, config, impactSet) => {
7809
+ var contextDataFor = (workflow, repoIndex, config, impactSet, diagnostics) => {
8046
7810
  if (!config) {
8047
7811
  return {};
8048
7812
  }
@@ -8051,7 +7815,12 @@ var contextDataFor = (workflow, repoIndex, config, impactSet) => {
8051
7815
  repoIndex.routeMap.routes.flatMap((route) => route.truthDocs)
8052
7816
  );
8053
7817
  const primaryTruthDocs = uniqueSorted4(impactSet?.affectedTruthDocs ?? []);
8054
- const candidateStaleTruthDocs = workflow === "truthmark-sync" ? candidateStaleTruthDocsFor(indexedTruthDocs, primaryTruthDocs) : [];
7818
+ const candidateStaleTruthDocs = workflow === "truthmark-sync" ? candidateStaleTruthDocsFor(
7819
+ repoIndex,
7820
+ primaryTruthDocs,
7821
+ impactSet,
7822
+ diagnostics
7823
+ ) : [];
8055
7824
  const truthDocs = workflow === "truthmark-sync" ? uniqueSorted4([...primaryTruthDocs, ...candidateStaleTruthDocs]) : uniqueSorted4(impactSet?.affectedTruthDocs ?? indexedTruthDocs);
8056
7825
  return {
8057
7826
  routeIndexPath: config.truthmark.paths.routesIndex,
@@ -8111,7 +7880,8 @@ var buildWorkflowState = async (cwd, options) => {
8111
7880
  options.workflow,
8112
7881
  repoIndex,
8113
7882
  loadResult.config,
8114
- impactSet
7883
+ impactSet,
7884
+ diagnostics
8115
7885
  );
8116
7886
  return {
8117
7887
  schemaVersion: "truthmark-workflow/v0",
@@ -8202,7 +7972,6 @@ var validateEvidenceChecked = (text, errors, checks) => {
8202
7972
  };
8203
7973
  var validateHelperScriptEntries = (entries, requiredHelpers, errors, checks) => {
8204
7974
  if (entries === void 0 || entries.length === 0) {
8205
- errors.push("Helper scripts must include status for optional helpers");
8206
7975
  return;
8207
7976
  }
8208
7977
  const statusPattern = /^(?:-\s*)?([a-z0-9-]+):\s*(?:ran,\s*passed|skipped,\s*\S.*)$/iu;
@@ -8222,7 +7991,7 @@ var validateHelperScriptEntries = (entries, requiredHelpers, errors, checks) =>
8222
7991
  errors.push(`missing Helper scripts status: ${helperId}`);
8223
7992
  }
8224
7993
  }
8225
- if (errors.length === 0) {
7994
+ if (errors.length === 0 && requiredHelpers.length > 0) {
8226
7995
  checks.push(`Helper scripts statuses include ${requiredHelpers.join(", ")}`);
8227
7996
  }
8228
7997
  };
@@ -8267,15 +8036,20 @@ var validateTruthSyncReportText = (text) => {
8267
8036
  "Evidence checked entries include Claim:, Evidence:, and Result: supported | narrowed | removed | blocked"
8268
8037
  );
8269
8038
  }
8039
+ const completedTargets = [
8040
+ ...report.truthDocsUpdated,
8041
+ ...report.syncIntent?.targetTruthDocs ?? []
8042
+ ];
8043
+ const bootstrapTargets = completedTargets.filter(isBootstrapRoutingDocPath);
8044
+ if (bootstrapTargets.length > 0) {
8045
+ errors.push(
8046
+ `bootstrap-routing.md is a provisional topology handoff, not a completed behavior-update target: ${bootstrapTargets.join(", ")}`
8047
+ );
8048
+ }
8270
8049
  if (report.syncIntent !== void 0) {
8271
8050
  checks.push("Sync Intent");
8272
8051
  }
8273
- validateHelperScriptEntries(
8274
- report.helperScripts,
8275
- ["validate-write-lease"],
8276
- errors,
8277
- checks
8278
- );
8052
+ validateHelperScriptEntries(report.helperScripts, [], errors, checks);
8279
8053
  } catch (error) {
8280
8054
  errors.push(error instanceof Error ? error.message : "invalid Truth Sync report");
8281
8055
  }
@@ -8310,11 +8084,6 @@ var validateTruthDocumentReportText = (text) => {
8310
8084
  } else {
8311
8085
  errors.push("missing required section: Evidence checked");
8312
8086
  }
8313
- if (hasLabel(text, "Helper scripts")) {
8314
- checks.push("Helper scripts");
8315
- } else {
8316
- errors.push("missing required section: Helper scripts");
8317
- }
8318
8087
  const truthDocsUpdated = getSection(text, "Truth docs updated");
8319
8088
  const truthDocsCreated = getSection(text, "Truth docs created");
8320
8089
  if (truthDocsUpdated === null && truthDocsCreated === null) {
@@ -8327,7 +8096,7 @@ var validateTruthDocumentReportText = (text) => {
8327
8096
  checks.push("Truth docs updated or created");
8328
8097
  }
8329
8098
  validateEvidenceChecked(text, errors, checks);
8330
- validateHelperScripts(text, ["validate-write-lease"], errors, checks);
8099
+ validateHelperScripts(text, [], errors, checks);
8331
8100
  } else if (status === "blocked") {
8332
8101
  requireBulletSection(text, "Reason", errors, checks);
8333
8102
  }
@@ -8335,6 +8104,7 @@ var validateTruthDocumentReportText = (text) => {
8335
8104
  };
8336
8105
  var cleanPathValue = (value) => value.trim().replace(/^["']|["']$/gu, "");
8337
8106
  var normalizePath5 = (value) => cleanPathValue(value).replace(/^\.\//u, "");
8107
+ var isBootstrapRoutingDocPath = (value) => normalizePath5(value).endsWith("/bootstrap-routing.md");
8338
8108
  var windowsDriveAbsolutePattern = /^[A-Za-z]:[\\/]/u;
8339
8109
  var uncPathPattern = /^[/\\]{2}[^/\\]+[/\\]+[^/\\]+/u;
8340
8110
  var isUnsafePathValue = (value) => {