truthmark 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.de.md +2 -3
- package/README.es.md +2 -3
- package/README.md +3 -4
- package/README.ru.md +2 -3
- package/README.zh.md +2 -3
- package/dist/main.js +264 -304
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -256,13 +256,7 @@ var SUPPORTED_PLATFORMS = [
|
|
|
256
256
|
"github-copilot",
|
|
257
257
|
"gemini-cli"
|
|
258
258
|
];
|
|
259
|
-
var DEFAULT_PLATFORMS = [
|
|
260
|
-
"codex",
|
|
261
|
-
"opencode",
|
|
262
|
-
"claude-code",
|
|
263
|
-
"github-copilot",
|
|
264
|
-
"gemini-cli"
|
|
265
|
-
];
|
|
259
|
+
var DEFAULT_PLATFORMS = [];
|
|
266
260
|
var truthmarkConfigSchema = {
|
|
267
261
|
type: "object",
|
|
268
262
|
additionalProperties: false,
|
|
@@ -368,7 +362,6 @@ var DERIVED_TRUTHMARK_PATHS = {
|
|
|
368
362
|
var DEFAULT_INSTRUCTION_TARGETS = ["AGENTS.md"];
|
|
369
363
|
var createDefaultRawConfig = () => ({
|
|
370
364
|
version: 2,
|
|
371
|
-
platforms: [...DEFAULT_PLATFORMS],
|
|
372
365
|
truthmark: {
|
|
373
366
|
workspace: DEFAULT_TRUTHMARK_WORKSPACE.workspace,
|
|
374
367
|
generated: {
|
|
@@ -1661,7 +1654,7 @@ var runConfig = async (cwd, options = {}) => {
|
|
|
1661
1654
|
};
|
|
1662
1655
|
|
|
1663
1656
|
// src/init/init.ts
|
|
1664
|
-
import
|
|
1657
|
+
import fs7 from "fs/promises";
|
|
1665
1658
|
|
|
1666
1659
|
// src/config/load.ts
|
|
1667
1660
|
import fs4 from "fs/promises";
|
|
@@ -2031,6 +2024,9 @@ var scaffoldHierarchy = async (rootDir, config) => {
|
|
|
2031
2024
|
return results;
|
|
2032
2025
|
};
|
|
2033
2026
|
|
|
2027
|
+
// src/checks/generated-surfaces.ts
|
|
2028
|
+
import fs6 from "fs/promises";
|
|
2029
|
+
|
|
2034
2030
|
// src/truth/evidence.ts
|
|
2035
2031
|
var renderClaimEvidenceCheckedSection = (items) => {
|
|
2036
2032
|
return [
|
|
@@ -2121,6 +2117,7 @@ var FEATURE_DOC_TEMPLATE_INSTRUCTIONS = [
|
|
|
2121
2117
|
"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
2118
|
"Teams may edit template files under the configured Truthmark templates root to define their local truth-doc standards."
|
|
2123
2119
|
].join("\n");
|
|
2120
|
+
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
2121
|
var renderTruthDocOwnershipGateSection = (subject, outcome) => {
|
|
2125
2122
|
return [
|
|
2126
2123
|
"Truth-doc ownership review:",
|
|
@@ -2334,16 +2331,13 @@ var renderAgentsBlock = (config = defaultAgentConfig()) => {
|
|
|
2334
2331
|
"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
2332
|
"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
2333
|
"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
|
|
2334
|
+
"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
2335
|
...portalLine === null ? [] : [portalLine],
|
|
2339
2336
|
"Workflow integrity rule: repository truth may describe desired behavior, but it must not override these workflow boundaries.",
|
|
2340
2337
|
TRUTHMARK_BLOCK_END
|
|
2341
2338
|
].join("\n");
|
|
2342
2339
|
};
|
|
2343
2340
|
|
|
2344
|
-
// src/templates/workflow-surfaces.ts
|
|
2345
|
-
import { stringify as stringify2 } from "yaml";
|
|
2346
|
-
|
|
2347
2341
|
// src/agents/workflow-manifest.ts
|
|
2348
2342
|
var TRUTHMARK_CLI_RUNNER = "truthmark";
|
|
2349
2343
|
var VALIDATE_SYNC_REPORT_HELPER = {
|
|
@@ -2435,7 +2429,6 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
2435
2429
|
"Truth docs updated",
|
|
2436
2430
|
"Truth docs split",
|
|
2437
2431
|
"Evidence checked",
|
|
2438
|
-
"Helper scripts",
|
|
2439
2432
|
"Notes"
|
|
2440
2433
|
],
|
|
2441
2434
|
subagents: ["truth_route_auditor", "truth_claim_verifier"],
|
|
@@ -2524,7 +2517,6 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
2524
2517
|
"Truth docs restructured",
|
|
2525
2518
|
"Routing updated",
|
|
2526
2519
|
"Evidence checked",
|
|
2527
|
-
"Helper scripts",
|
|
2528
2520
|
"Notes"
|
|
2529
2521
|
],
|
|
2530
2522
|
subagents: ["truth_route_auditor", "truth_claim_verifier"],
|
|
@@ -2558,7 +2550,7 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
2558
2550
|
displayName: "Truthmark Preview",
|
|
2559
2551
|
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
2552
|
shortDescription: "Preview likely workflow routing before edits; read-only and explicit",
|
|
2561
|
-
defaultPrompt: "Use
|
|
2553
|
+
defaultPrompt: "Use Truthmark Preview to estimate likely workflow routing before edits.",
|
|
2562
2554
|
allowImplicitInvocation: false,
|
|
2563
2555
|
positiveTriggers: [
|
|
2564
2556
|
"explicit request to preview Truthmark workflow routing before edits",
|
|
@@ -2776,7 +2768,6 @@ ${DECISION_TRUTH_INSTRUCTIONS}`;
|
|
|
2776
2768
|
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
2769
|
var renderTruthDocumentReportExample = (config = defaultAgentConfig()) => {
|
|
2778
2770
|
const engineeringTruthRoot = resolveEngineeringTruthRoot(config);
|
|
2779
|
-
const helperScripts = ["validate-write-lease: skipped, no write lease used"];
|
|
2780
2771
|
return `Truth Document: completed
|
|
2781
2772
|
|
|
2782
2773
|
Implementation reviewed:
|
|
@@ -2808,9 +2799,6 @@ ${renderClaimEvidenceCheckedSection([
|
|
|
2808
2799
|
}
|
|
2809
2800
|
])}
|
|
2810
2801
|
|
|
2811
|
-
Helper scripts:
|
|
2812
|
-
${helperScripts.map((helperScript) => `- ${helperScript}`).join("\n")}
|
|
2813
|
-
|
|
2814
2802
|
Notes:
|
|
2815
2803
|
- Documented routing and behavior from route handlers and tests.`;
|
|
2816
2804
|
};
|
|
@@ -2878,18 +2866,14 @@ ${renderRouteFirstEvidenceGateSection(
|
|
|
2878
2866
|
)}
|
|
2879
2867
|
${subagentMode}${REPOSITORY_INTELLIGENCE_INSTRUCTIONS}
|
|
2880
2868
|
${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
|
|
2869
|
+
${TRUTH_DOC_AUTHORING_STYLE_INSTRUCTIONS}
|
|
2881
2870
|
${renderTruthDocRestructureGateSection(
|
|
2882
2871
|
"Truth Document may restructure only truth docs for the implemented behavior being documented."
|
|
2883
2872
|
)}
|
|
2884
2873
|
${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
|
|
2885
2874
|
${renderHierarchySummary(config)}
|
|
2886
2875
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
2887
|
-
|
|
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.
|
|
2876
|
+
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
2877
|
Parent post-document verification:
|
|
2894
2878
|
- verify only truth docs and leased truth routing files changed during document work
|
|
2895
2879
|
- stop on functional code, generated host surfaces, or unrelated diffs caused by document work
|
|
@@ -2898,7 +2882,10 @@ Parent post-document verification:
|
|
|
2898
2882
|
};
|
|
2899
2883
|
|
|
2900
2884
|
// src/agents/truth-preview.ts
|
|
2901
|
-
var TRUTH_PREVIEW_EXPLICIT_INVOCATIONS =
|
|
2885
|
+
var TRUTH_PREVIEW_EXPLICIT_INVOCATIONS = {
|
|
2886
|
+
copilot: "GitHub Copilot /truthmark-preview.",
|
|
2887
|
+
gemini: "Gemini CLI /truthmark:preview."
|
|
2888
|
+
};
|
|
2902
2889
|
var renderTruthPreviewReportExample = (config = defaultAgentConfig()) => {
|
|
2903
2890
|
return `Truth Preview: completed
|
|
2904
2891
|
|
|
@@ -2937,12 +2924,25 @@ Manual handoff questions:
|
|
|
2937
2924
|
Handoff:
|
|
2938
2925
|
- Run the selected Truthmark workflow after user approval.`;
|
|
2939
2926
|
};
|
|
2940
|
-
var
|
|
2941
|
-
return `
|
|
2927
|
+
var renderTruthPreviewAdapterReportFields = () => {
|
|
2928
|
+
return `Return a concise Truth Preview report with these fields:
|
|
2929
|
+
- requested outcome
|
|
2930
|
+
- likely workflow
|
|
2931
|
+
- why this workflow
|
|
2932
|
+
- likely route owner and lane impact
|
|
2933
|
+
- expected write classes
|
|
2934
|
+
- expected target files
|
|
2935
|
+
- suggested subagent use
|
|
2936
|
+
- manual handoff questions
|
|
2937
|
+
- handoff recommendation`;
|
|
2938
|
+
};
|
|
2939
|
+
var renderTruthPreviewProcedureBody = (config = defaultAgentConfig(), host) => {
|
|
2940
|
+
const invocationLine = host === void 0 ? "" : `Invocations: ${TRUTH_PREVIEW_EXPLICIT_INVOCATIONS[host]}
|
|
2942
2941
|
|
|
2943
|
-
|
|
2942
|
+
`;
|
|
2943
|
+
return `Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.
|
|
2944
2944
|
|
|
2945
|
-
Truth Preview is read-only. Its report is intended, not authorized.
|
|
2945
|
+
${invocationLine}Truth Preview is read-only. Its report is intended, not authorized.
|
|
2946
2946
|
|
|
2947
2947
|
Purpose:
|
|
2948
2948
|
- preview the likely Truthmark workflow, route owner, target files, expected write classes, suggested subagent use, and manual handoff questions before edits happen
|
|
@@ -3083,15 +3083,15 @@ ${renderLaneClassificationRuleBlock(config)}
|
|
|
3083
3083
|
- 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
3084
|
- define areas by product or behavior ownership, not by mechanical directory mirroring
|
|
3085
3085
|
- create or repair ${config.truthmark.paths.routesIndex}
|
|
3086
|
-
- create starter truth docs
|
|
3086
|
+
- create skeletal starter truth docs only when missing ownership would otherwise block future workflows
|
|
3087
3087
|
- 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
|
|
3088
|
+
- Starter truth docs are ownership anchors, not behavior writeups: include only the title, bounded area/scope, and Source References needed to make routing explicit.
|
|
3089
|
+
- 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
3090
|
${subagentMode}
|
|
3090
|
-
${FEATURE_DOC_TEMPLATE_INSTRUCTIONS}
|
|
3091
3091
|
- use ${productTruthRoot}/** for product truth destinations
|
|
3092
3092
|
- use ${engineeringTruthRoot}/** for engineering truth destinations
|
|
3093
3093
|
- use only canonical current-truth destinations for starter truth docs
|
|
3094
|
-
- keep
|
|
3094
|
+
- 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
3095
|
- preserve unrelated authored content
|
|
3096
3096
|
## New area setup
|
|
3097
3097
|
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 +3111,11 @@ Do not:
|
|
|
3111
3111
|
## Topology Governance
|
|
3112
3112
|
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
3113
|
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
|
|
3114
|
+
When topology pressure exists, repair route structure before creating or extending truth ownership anchors.
|
|
3115
3115
|
${renderTruthDocOwnershipGateSection(
|
|
3116
3116
|
"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
|
|
3117
|
+
"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
3118
|
)}
|
|
3119
|
-
${TRUTH_DOC_DECISION_RATIONALE_PRESERVATION_INSTRUCTIONS}
|
|
3120
3119
|
Topology pressure signals:
|
|
3121
3120
|
- one area maps broad code such as src/**, app/**, server/**, services/**, or packages/**
|
|
3122
3121
|
- one area maps multiple unrelated controllers, route groups, services, or bounded contexts
|
|
@@ -3132,10 +3131,10 @@ Use these review thresholds as guidance:
|
|
|
3132
3131
|
- more than 5 controllers mapped through one catch-all area
|
|
3133
3132
|
Repair rules:
|
|
3134
3133
|
- split broad, overloaded, or catch-all areas into behavior-owned child route files
|
|
3135
|
-
- split mixed-owner truth docs
|
|
3134
|
+
- split or flag mixed-owner truth docs for bounded owners before any workflow adds new behavior claims
|
|
3136
3135
|
- create route files under ${config.truthmark.paths.routeAreasRoot}/ when a product/domain boundary is clear
|
|
3137
|
-
- create engineering
|
|
3138
|
-
- create product
|
|
3136
|
+
- create skeletal engineering ownership anchors under ${engineeringTruthRoot} only when behavior lacks a current owner
|
|
3137
|
+
- create skeletal product ownership anchors under ${productTruthRoot} only when product promise, boundary, rationale, or user-visible capability ownership is in scope
|
|
3139
3138
|
- README.md files are indexes, not Truth Sync targets
|
|
3140
3139
|
- prefer bounded product docs under product/capabilities or product/decisions and engineering docs under engineering/<kind>/<surface>.md
|
|
3141
3140
|
- keep behavior truth docs behavior-oriented, not endpoint-oriented
|
|
@@ -3143,13 +3142,9 @@ Repair rules:
|
|
|
3143
3142
|
- update routing so future Truth Sync can target small docs
|
|
3144
3143
|
- preserve existing authored docs; move or rewrite only when needed to remove ambiguity
|
|
3145
3144
|
- 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
3145
|
${renderTopologyEvidenceGateSection()}
|
|
3150
|
-
${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
|
|
3151
3146
|
- 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,
|
|
3147
|
+
- 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
3148
|
Portable fallback:
|
|
3154
3149
|
- If this skill surface is unavailable, perform the same workflow directly from committed repository files.
|
|
3155
3150
|
- Do not require the truthmark CLI.
|
|
@@ -3398,50 +3393,28 @@ ${renderTruthSyncProductDecisionRuleBlock(config)}
|
|
|
3398
3393
|
- User-provided decisions/rationale: decisions, rationale, constraints, tradeoffs, rejection reasons, or scope boundaries from the current task conversation, or "none provided"
|
|
3399
3394
|
- No-update-needed rationale: why mapped truth is already current when no truth doc should change
|
|
3400
3395
|
- 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:
|
|
3396
|
+
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.
|
|
3397
|
+
${subagentMode}Topology review and repair:
|
|
3403
3398
|
- 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,
|
|
3405
|
-
-
|
|
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
|
|
3399
|
+
- 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
|
|
3400
|
+
- 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
|
|
3401
|
+
- stop and recommend Truth Structure only when topology repair is unsafe, ambiguous, or outside the current task boundary
|
|
3402
|
+
- report the route files and changed code paths that required structure repair
|
|
3403
|
+
- do not create another generic truth doc
|
|
3408
3404
|
- README.md files are indexes, not Truth Sync targets
|
|
3409
3405
|
- 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
3406
|
- 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
3407
|
Optional validation tooling:
|
|
3428
3408
|
- you may run truthmark check when local tooling is available
|
|
3409
|
+
- you may validate the final report with \`truthmark validate sync-report <report-file> --json\` when available
|
|
3429
3410
|
- do not require the truthmark binary; direct checkout inspection is the canonical path
|
|
3430
3411
|
- optional validation must not replace agent judgment about docs and routing
|
|
3431
3412
|
- 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
3413
|
${renderHierarchySummary(config)}
|
|
3439
|
-
${DECISION_TRUTH_INSTRUCTIONS}
|
|
3440
3414
|
Parent post-sync verification:
|
|
3441
3415
|
- verify only truth docs and leased truth routing files changed during sync
|
|
3442
3416
|
- stop on any unrelated diff caused by the sync step
|
|
3443
3417
|
- 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
3418
|
- 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
3419
|
- 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
3420
|
- verify the final report records ownership review, structure requirement, split, restructure, or manual handoff reason when the ownership review applies
|
|
@@ -3475,8 +3448,6 @@ var TRUTHMARK_REALIZE_SKILL_PATH = ".agents/skills/truthmark-realize/SKILL.md";
|
|
|
3475
3448
|
var TRUTHMARK_REALIZE_SKILL_METADATA_PATH = ".agents/skills/truthmark-realize/agents/openai.yaml";
|
|
3476
3449
|
var TRUTHMARK_CHECK_SKILL_PATH = ".agents/skills/truthmark-check/SKILL.md";
|
|
3477
3450
|
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
3451
|
var TRUTHMARK_PORTAL_SKILL_PATH = ".agents/skills/truthmark-portal/SKILL.md";
|
|
3481
3452
|
var TRUTHMARK_PORTAL_SKILL_METADATA_PATH = ".agents/skills/truthmark-portal/agents/openai.yaml";
|
|
3482
3453
|
var TRUTHMARK_ROUTE_AUDITOR_AGENT_PATH = ".codex/agents/truth-route-auditor.toml";
|
|
@@ -3535,12 +3506,10 @@ var workflowSupportFiles = (workflowId) => {
|
|
|
3535
3506
|
const workflow = getTruthmarkWorkflow(workflowId);
|
|
3536
3507
|
const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
|
|
3537
3508
|
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
3509
|
return [
|
|
3540
3510
|
"support/procedure.md",
|
|
3541
3511
|
"support/report-template.md",
|
|
3542
|
-
...hasSubagentSupport ? ["support/subagents-and-leases.md"] : []
|
|
3543
|
-
...hasHelperSupport ? ["helper-manifest.yml", "support/helper-policy.md"] : []
|
|
3512
|
+
...hasSubagentSupport ? ["support/subagents-and-leases.md"] : []
|
|
3544
3513
|
];
|
|
3545
3514
|
};
|
|
3546
3515
|
var renderWorkflowCommandAdapterInstructions = (workflowId, root, hostName, surfaceKind) => {
|
|
@@ -3615,7 +3584,7 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
3615
3584
|
"truthmark-preview": {
|
|
3616
3585
|
title: "Truthmark Preview",
|
|
3617
3586
|
argumentHint: "Optional requested outcome, code area, doc path, or routing question",
|
|
3618
|
-
invocations: TRUTH_PREVIEW_EXPLICIT_INVOCATIONS,
|
|
3587
|
+
invocations: TRUTH_PREVIEW_EXPLICIT_INVOCATIONS.copilot,
|
|
3619
3588
|
use: () => "Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.",
|
|
3620
3589
|
quickRules: (config) => [
|
|
3621
3590
|
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
@@ -3731,7 +3700,6 @@ ${renderMarkdownExample(
|
|
|
3731
3700
|
decisionRationaleCaptured: [
|
|
3732
3701
|
"Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale."
|
|
3733
3702
|
],
|
|
3734
|
-
helperScripts: ["validate-write-lease: skipped, no write lease used"],
|
|
3735
3703
|
notes: ["Updated session timeout behavior."]
|
|
3736
3704
|
})
|
|
3737
3705
|
)}
|
|
@@ -3809,56 +3777,6 @@ Truthmark-managed generated file. Refresh with truthmark init when truthmark che
|
|
|
3809
3777
|
${body}
|
|
3810
3778
|
`;
|
|
3811
3779
|
};
|
|
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
3780
|
var renderWorkflowProcedure = (workflowId, config) => {
|
|
3863
3781
|
switch (workflowId) {
|
|
3864
3782
|
case "truthmark-structure":
|
|
@@ -3890,12 +3808,6 @@ var renderWorkflowEntrypoint = (workflowId, config, supportFiles, host) => {
|
|
|
3890
3808
|
if (supportFile === "support/subagents-and-leases.md") {
|
|
3891
3809
|
return "read only when using subagents, leases, or accepting worker output";
|
|
3892
3810
|
}
|
|
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
3811
|
return "available when relevant to the current step";
|
|
3900
3812
|
};
|
|
3901
3813
|
const supportFileList = supportFiles.map((supportFile) => `- ${supportFile} \u2014 ${supportFileUsage(supportFile)}`).join("\n");
|
|
@@ -3979,7 +3891,6 @@ var renderTruthmarkSkillPackage = ({
|
|
|
3979
3891
|
config
|
|
3980
3892
|
);
|
|
3981
3893
|
const subagents = renderWorkflowSubagentSupport(workflowId, host);
|
|
3982
|
-
const helpers = getTruthmarkWorkflow(workflowId).helpers ?? [];
|
|
3983
3894
|
const supportFiles = workflowSupportFiles(workflowId);
|
|
3984
3895
|
const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId];
|
|
3985
3896
|
const files = [
|
|
@@ -4011,18 +3922,6 @@ var renderTruthmarkSkillPackage = ({
|
|
|
4011
3922
|
)
|
|
4012
3923
|
});
|
|
4013
3924
|
}
|
|
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
3925
|
return files;
|
|
4027
3926
|
};
|
|
4028
3927
|
var normalizeOpenCodePermissionPath = (path12) => {
|
|
@@ -4554,20 +4453,6 @@ var renderTruthmarkRealizeSkillMetadata = () => {
|
|
|
4554
4453
|
policy:
|
|
4555
4454
|
allow_implicit_invocation: ${workflow.allowImplicitInvocation}
|
|
4556
4455
|
|
|
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
4456
|
truthmark:
|
|
4572
4457
|
refresh_command: "truthmark init"
|
|
4573
4458
|
`;
|
|
@@ -4660,10 +4545,15 @@ var renderTruthmarkGeminiCheckCommand = (config = defaultAgentConfig()) => {
|
|
|
4660
4545
|
);
|
|
4661
4546
|
};
|
|
4662
4547
|
var renderTruthmarkGeminiPreviewCommand = (config = defaultAgentConfig()) => {
|
|
4663
|
-
|
|
4664
|
-
return
|
|
4665
|
-
|
|
4666
|
-
|
|
4548
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
4549
|
+
return renderGeminiCommand(
|
|
4550
|
+
workflow.description,
|
|
4551
|
+
`This command is the Gemini CLI entrypoint for Truthmark Preview.
|
|
4552
|
+
|
|
4553
|
+
Truth Preview is read-only and explicit. Do not invoke another Truthmark command from here.
|
|
4554
|
+
|
|
4555
|
+
${renderTruthPreviewProcedureBody(config, "gemini")}
|
|
4556
|
+
${renderTruthPreviewAdapterReportFields()}`
|
|
4667
4557
|
);
|
|
4668
4558
|
};
|
|
4669
4559
|
var renderTruthmarkGeminiPortalCommand = (config = defaultAgentConfig()) => {
|
|
@@ -4709,10 +4599,15 @@ var renderTruthmarkCopilotCheckPrompt = (config = defaultAgentConfig()) => {
|
|
|
4709
4599
|
);
|
|
4710
4600
|
};
|
|
4711
4601
|
var renderTruthmarkCopilotPreviewPrompt = (config = defaultAgentConfig()) => {
|
|
4712
|
-
|
|
4713
|
-
return
|
|
4714
|
-
|
|
4715
|
-
|
|
4602
|
+
const workflow = getTruthmarkWorkflow("truthmark-preview");
|
|
4603
|
+
return renderCopilotPromptFile(
|
|
4604
|
+
workflow.description,
|
|
4605
|
+
`This prompt is the GitHub Copilot entrypoint for Truthmark Preview.
|
|
4606
|
+
|
|
4607
|
+
Truth Preview is read-only and explicit. Do not invoke another Truthmark command from here.
|
|
4608
|
+
|
|
4609
|
+
${renderTruthPreviewProcedureBody(config, "copilot")}
|
|
4610
|
+
${renderTruthPreviewAdapterReportFields()}`
|
|
4716
4611
|
);
|
|
4717
4612
|
};
|
|
4718
4613
|
var renderTruthmarkCopilotPortalPrompt = (config = defaultAgentConfig()) => {
|
|
@@ -4756,16 +4651,6 @@ var codexFiles = (config) => {
|
|
|
4756
4651
|
path: TRUTHMARK_SYNC_SKILL_METADATA_PATH,
|
|
4757
4652
|
content: renderTruthmarkSyncSkillMetadata()
|
|
4758
4653
|
},
|
|
4759
|
-
...renderTruthmarkSkillPackage({
|
|
4760
|
-
skillPath: TRUTHMARK_PREVIEW_SKILL_PATH,
|
|
4761
|
-
workflowId: "truthmark-preview",
|
|
4762
|
-
host: "codex",
|
|
4763
|
-
config
|
|
4764
|
-
}),
|
|
4765
|
-
{
|
|
4766
|
-
path: TRUTHMARK_PREVIEW_SKILL_METADATA_PATH,
|
|
4767
|
-
content: renderTruthmarkPreviewSkillMetadata()
|
|
4768
|
-
},
|
|
4769
4654
|
...renderTruthmarkSkillPackage({
|
|
4770
4655
|
skillPath: TRUTHMARK_CHECK_SKILL_PATH,
|
|
4771
4656
|
workflowId: "truthmark-check",
|
|
@@ -4839,12 +4724,6 @@ var opencodeFiles = (config) => {
|
|
|
4839
4724
|
host: "opencode",
|
|
4840
4725
|
config
|
|
4841
4726
|
}),
|
|
4842
|
-
...renderTruthmarkSkillPackage({
|
|
4843
|
-
skillPath: ".opencode/skills/truthmark-preview/SKILL.md",
|
|
4844
|
-
workflowId: "truthmark-preview",
|
|
4845
|
-
host: "opencode",
|
|
4846
|
-
config
|
|
4847
|
-
}),
|
|
4848
4727
|
...renderTruthmarkSkillPackage({
|
|
4849
4728
|
skillPath: ".opencode/skills/truthmark-check/SKILL.md",
|
|
4850
4729
|
workflowId: "truthmark-check",
|
|
@@ -4907,12 +4786,6 @@ var claudeFiles = (config, block) => {
|
|
|
4907
4786
|
host: "claude-code",
|
|
4908
4787
|
config
|
|
4909
4788
|
}),
|
|
4910
|
-
...renderTruthmarkSkillPackage({
|
|
4911
|
-
skillPath: ".claude/skills/truthmark-preview/SKILL.md",
|
|
4912
|
-
workflowId: "truthmark-preview",
|
|
4913
|
-
host: "claude-code",
|
|
4914
|
-
config
|
|
4915
|
-
}),
|
|
4916
4789
|
...renderTruthmarkSkillPackage({
|
|
4917
4790
|
skillPath: ".claude/skills/truthmark-check/SKILL.md",
|
|
4918
4791
|
workflowId: "truthmark-check",
|
|
@@ -4975,12 +4848,6 @@ var copilotFiles = (config, block) => {
|
|
|
4975
4848
|
host: "github-copilot",
|
|
4976
4849
|
config
|
|
4977
4850
|
}),
|
|
4978
|
-
...renderTruthmarkSkillPackage({
|
|
4979
|
-
skillPath: ".github/skills/truthmark-preview/SKILL.md",
|
|
4980
|
-
workflowId: "truthmark-preview",
|
|
4981
|
-
host: "github-copilot",
|
|
4982
|
-
config
|
|
4983
|
-
}),
|
|
4984
4851
|
...renderTruthmarkSkillPackage({
|
|
4985
4852
|
skillPath: ".github/skills/truthmark-check/SKILL.md",
|
|
4986
4853
|
workflowId: "truthmark-check",
|
|
@@ -5071,12 +4938,6 @@ var geminiFiles = (config, block) => {
|
|
|
5071
4938
|
host: "gemini-cli",
|
|
5072
4939
|
config
|
|
5073
4940
|
}),
|
|
5074
|
-
...renderTruthmarkSkillPackage({
|
|
5075
|
-
skillPath: ".gemini/skills/truthmark-preview/SKILL.md",
|
|
5076
|
-
workflowId: "truthmark-preview",
|
|
5077
|
-
host: "gemini-cli",
|
|
5078
|
-
config
|
|
5079
|
-
}),
|
|
5080
4941
|
...renderTruthmarkSkillPackage({
|
|
5081
4942
|
skillPath: ".gemini/skills/truthmark-check/SKILL.md",
|
|
5082
4943
|
workflowId: "truthmark-check",
|
|
@@ -5179,6 +5040,163 @@ var renderGeneratedSurfaces = (config, block = renderAgentsBlock(config)) => {
|
|
|
5179
5040
|
).sort((left, right) => left.path.localeCompare(right.path));
|
|
5180
5041
|
};
|
|
5181
5042
|
|
|
5043
|
+
// src/checks/generated-surfaces.ts
|
|
5044
|
+
var readOptionalFile = async (rootDir, filePath) => {
|
|
5045
|
+
try {
|
|
5046
|
+
return await fs6.readFile(resolveRepoPath(rootDir, filePath), "utf8");
|
|
5047
|
+
} catch (error) {
|
|
5048
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
5049
|
+
return null;
|
|
5050
|
+
}
|
|
5051
|
+
throw error;
|
|
5052
|
+
}
|
|
5053
|
+
};
|
|
5054
|
+
var extractManagedBlock = (content) => {
|
|
5055
|
+
const startIndex = content.indexOf(TRUTHMARK_BLOCK_START);
|
|
5056
|
+
const endIndex = content.indexOf(TRUTHMARK_BLOCK_END);
|
|
5057
|
+
if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
|
|
5058
|
+
return null;
|
|
5059
|
+
}
|
|
5060
|
+
return content.slice(startIndex, endIndex + TRUTHMARK_BLOCK_END.length);
|
|
5061
|
+
};
|
|
5062
|
+
var normalizeGeneratedSurfaceContent = (content) => {
|
|
5063
|
+
if (content === null) {
|
|
5064
|
+
return null;
|
|
5065
|
+
}
|
|
5066
|
+
return content.replace(/\r\n/g, "\n").replace(/\n$/u, "");
|
|
5067
|
+
};
|
|
5068
|
+
var GENERATED_HOST_SKILL_ROOTS = [
|
|
5069
|
+
".agents/skills",
|
|
5070
|
+
".opencode/skills",
|
|
5071
|
+
".claude/skills",
|
|
5072
|
+
".github/skills",
|
|
5073
|
+
".gemini/skills"
|
|
5074
|
+
];
|
|
5075
|
+
var RETIRED_SKILL_HELPER_PATHS = [
|
|
5076
|
+
"helper-manifest.yml",
|
|
5077
|
+
"support/helper-policy.md"
|
|
5078
|
+
];
|
|
5079
|
+
var RETIRED_PACKAGE_DIRECTORIES = ["truthmark-preview"];
|
|
5080
|
+
var pathExists = async (absolutePath) => {
|
|
5081
|
+
try {
|
|
5082
|
+
await fs6.access(absolutePath);
|
|
5083
|
+
return true;
|
|
5084
|
+
} catch (error) {
|
|
5085
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
5086
|
+
return false;
|
|
5087
|
+
}
|
|
5088
|
+
throw error;
|
|
5089
|
+
}
|
|
5090
|
+
};
|
|
5091
|
+
var listDirectoryFiles = async (rootDir, packageRoot) => {
|
|
5092
|
+
const stack = [packageRoot];
|
|
5093
|
+
const files = [];
|
|
5094
|
+
while (stack.length > 0) {
|
|
5095
|
+
const current = stack.pop();
|
|
5096
|
+
if (current === void 0) {
|
|
5097
|
+
continue;
|
|
5098
|
+
}
|
|
5099
|
+
const absoluteCurrent = resolveRepoPath(rootDir, current);
|
|
5100
|
+
const entries = await fs6.readdir(absoluteCurrent, {
|
|
5101
|
+
withFileTypes: true
|
|
5102
|
+
});
|
|
5103
|
+
for (const entry of entries) {
|
|
5104
|
+
const next = `${current}/${entry.name}`;
|
|
5105
|
+
if (entry.isDirectory()) {
|
|
5106
|
+
stack.push(next);
|
|
5107
|
+
} else {
|
|
5108
|
+
files.push(next);
|
|
5109
|
+
}
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
return files;
|
|
5113
|
+
};
|
|
5114
|
+
var collectRetiredGeneratedSurfaces = async (rootDir, expectedSurfacePaths) => {
|
|
5115
|
+
const legacyCandidates = /* @__PURE__ */ new Set();
|
|
5116
|
+
for (const skillRoot of GENERATED_HOST_SKILL_ROOTS) {
|
|
5117
|
+
const absoluteSkillRoot = resolveRepoPath(rootDir, skillRoot);
|
|
5118
|
+
let skillPackages = [];
|
|
5119
|
+
try {
|
|
5120
|
+
skillPackages = await fs6.readdir(absoluteSkillRoot, {
|
|
5121
|
+
withFileTypes: true
|
|
5122
|
+
});
|
|
5123
|
+
} catch (error) {
|
|
5124
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
5125
|
+
continue;
|
|
5126
|
+
}
|
|
5127
|
+
throw error;
|
|
5128
|
+
}
|
|
5129
|
+
const packageNames = skillPackages.filter((entry) => entry.isDirectory() && entry.name.startsWith("truthmark-")).map((entry) => entry.name);
|
|
5130
|
+
for (const packageName of RETIRED_PACKAGE_DIRECTORIES) {
|
|
5131
|
+
if (!packageNames.includes(packageName)) {
|
|
5132
|
+
continue;
|
|
5133
|
+
}
|
|
5134
|
+
const packageRoot = `${skillRoot}/${packageName}`;
|
|
5135
|
+
const packageFiles = await listDirectoryFiles(rootDir, packageRoot);
|
|
5136
|
+
for (const filePath of packageFiles) {
|
|
5137
|
+
if (!expectedSurfacePaths.has(filePath)) {
|
|
5138
|
+
legacyCandidates.add(filePath);
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
for (const packageName of packageNames) {
|
|
5143
|
+
for (const retiredName of RETIRED_SKILL_HELPER_PATHS) {
|
|
5144
|
+
const retiredPath = `${packageName}/${retiredName}`;
|
|
5145
|
+
const relativeRetiredPath = `${skillRoot}/${retiredPath}`;
|
|
5146
|
+
const absoluteRetiredPath = resolveRepoPath(rootDir, relativeRetiredPath);
|
|
5147
|
+
if (await pathExists(absoluteRetiredPath) && !expectedSurfacePaths.has(relativeRetiredPath)) {
|
|
5148
|
+
legacyCandidates.add(relativeRetiredPath);
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
return Array.from(legacyCandidates);
|
|
5154
|
+
};
|
|
5155
|
+
var checkGeneratedSurfaces = async (rootDir, config) => {
|
|
5156
|
+
const diagnostics = [];
|
|
5157
|
+
const renderedSurfaces = renderGeneratedSurfaces(config);
|
|
5158
|
+
for (const surface of renderedSurfaces) {
|
|
5159
|
+
const content = await readOptionalFile(rootDir, surface.path);
|
|
5160
|
+
if (content === null) {
|
|
5161
|
+
diagnostics.push({
|
|
5162
|
+
category: "generated-surface",
|
|
5163
|
+
severity: "review",
|
|
5164
|
+
message: `Generated surface ${surface.path} is missing; rerun truthmark init.`,
|
|
5165
|
+
file: surface.path
|
|
5166
|
+
});
|
|
5167
|
+
continue;
|
|
5168
|
+
}
|
|
5169
|
+
const comparableContent = normalizeGeneratedSurfaceContent(
|
|
5170
|
+
surface.managedBlock ? extractManagedBlock(content) : content
|
|
5171
|
+
);
|
|
5172
|
+
const expectedContent = normalizeGeneratedSurfaceContent(surface.content);
|
|
5173
|
+
if (comparableContent !== expectedContent) {
|
|
5174
|
+
diagnostics.push({
|
|
5175
|
+
category: "generated-surface",
|
|
5176
|
+
severity: "review",
|
|
5177
|
+
message: `Generated surface ${surface.path} is stale; rerun truthmark init.`,
|
|
5178
|
+
file: surface.path
|
|
5179
|
+
});
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
const staleSurfaces = await collectRetiredGeneratedSurfaces(
|
|
5183
|
+
rootDir,
|
|
5184
|
+
new Set(renderedSurfaces.map((surface) => surface.path))
|
|
5185
|
+
);
|
|
5186
|
+
for (const surfacePath of staleSurfaces) {
|
|
5187
|
+
diagnostics.push({
|
|
5188
|
+
category: "generated-surface",
|
|
5189
|
+
severity: "review",
|
|
5190
|
+
message: `Generated surface ${surfacePath} is obsolete; rerun truthmark init.`,
|
|
5191
|
+
file: surfacePath
|
|
5192
|
+
});
|
|
5193
|
+
}
|
|
5194
|
+
return diagnostics;
|
|
5195
|
+
};
|
|
5196
|
+
var findRetiredGeneratedSurfaces = async (rootDir, expectedSurfacePaths) => {
|
|
5197
|
+
return collectRetiredGeneratedSurfaces(rootDir, expectedSurfacePaths);
|
|
5198
|
+
};
|
|
5199
|
+
|
|
5182
5200
|
// src/init/init.ts
|
|
5183
5201
|
var escapeRegExp = (value) => {
|
|
5184
5202
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -5275,7 +5293,7 @@ ${block}`;
|
|
|
5275
5293
|
var writeManagedAgentsFile = async (rootDir, path12 = "AGENTS.md", block) => {
|
|
5276
5294
|
let existingContent = null;
|
|
5277
5295
|
try {
|
|
5278
|
-
existingContent = await
|
|
5296
|
+
existingContent = await fs7.readFile(resolveRepoPath(rootDir, path12), "utf8");
|
|
5279
5297
|
} catch (error) {
|
|
5280
5298
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
5281
5299
|
throw error;
|
|
@@ -5354,9 +5372,17 @@ var runInit = async (cwd) => {
|
|
|
5354
5372
|
results.push(...await scaffoldHierarchy(rootDir, config));
|
|
5355
5373
|
const block = renderAgentsBlock(config);
|
|
5356
5374
|
const platformFiles = renderGeneratedSurfaces(config, block);
|
|
5375
|
+
const expectedSurfacePaths = new Set(platformFiles.map((file) => file.path));
|
|
5357
5376
|
for (const file of platformFiles) {
|
|
5358
5377
|
results.push(await writePlatformFile(rootDir, file));
|
|
5359
5378
|
}
|
|
5379
|
+
const obsoleteSurfacePaths = await findRetiredGeneratedSurfaces(
|
|
5380
|
+
rootDir,
|
|
5381
|
+
expectedSurfacePaths
|
|
5382
|
+
);
|
|
5383
|
+
for (const obsoletePath of obsoleteSurfacePaths) {
|
|
5384
|
+
await fs7.rm(resolveRepoPath(rootDir, obsoletePath), { force: true });
|
|
5385
|
+
}
|
|
5360
5386
|
const changedResults = results.filter((result) => result.status !== "unchanged");
|
|
5361
5387
|
return {
|
|
5362
5388
|
command: "init",
|
|
@@ -5373,7 +5399,7 @@ var runInit = async (cwd) => {
|
|
|
5373
5399
|
};
|
|
5374
5400
|
|
|
5375
5401
|
// src/checks/branch-scope.ts
|
|
5376
|
-
import
|
|
5402
|
+
import fs8 from "fs/promises";
|
|
5377
5403
|
import fg from "fast-glob";
|
|
5378
5404
|
|
|
5379
5405
|
// src/markdown/hash.ts
|
|
@@ -5429,7 +5455,7 @@ var getBranchScopeData = async (cwd) => {
|
|
|
5429
5455
|
}
|
|
5430
5456
|
for (const relativePath of [...relevantFiles].sort()) {
|
|
5431
5457
|
try {
|
|
5432
|
-
const source = await
|
|
5458
|
+
const source = await fs8.readFile(resolveWorktreePath(repository, relativePath), "utf8");
|
|
5433
5459
|
relevantFileHashes[relativePath] = hashText(source);
|
|
5434
5460
|
} catch (error) {
|
|
5435
5461
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -5446,14 +5472,14 @@ var getBranchScopeData = async (cwd) => {
|
|
|
5446
5472
|
};
|
|
5447
5473
|
|
|
5448
5474
|
// src/checks/authority.ts
|
|
5449
|
-
import
|
|
5475
|
+
import fs9 from "fs/promises";
|
|
5450
5476
|
import fg2 from "fast-glob";
|
|
5451
5477
|
var looksLikeGlob = (pattern) => {
|
|
5452
5478
|
return /[*?[\]{}()!+@]/u.test(pattern);
|
|
5453
5479
|
};
|
|
5454
|
-
var
|
|
5480
|
+
var pathExists2 = async (absolutePath) => {
|
|
5455
5481
|
try {
|
|
5456
|
-
await
|
|
5482
|
+
await fs9.stat(absolutePath);
|
|
5457
5483
|
return true;
|
|
5458
5484
|
} catch (error) {
|
|
5459
5485
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -5521,7 +5547,7 @@ var checkControlledPaths = async (rootDir, controlledPaths) => {
|
|
|
5521
5547
|
});
|
|
5522
5548
|
continue;
|
|
5523
5549
|
}
|
|
5524
|
-
if (!await
|
|
5550
|
+
if (!await pathExists2(absoluteEntryPath)) {
|
|
5525
5551
|
diagnostics.push({
|
|
5526
5552
|
category: "authority",
|
|
5527
5553
|
severity: "error",
|
|
@@ -5545,7 +5571,7 @@ var checkAuthority = async (rootDir, config) => {
|
|
|
5545
5571
|
};
|
|
5546
5572
|
|
|
5547
5573
|
// src/checks/frontmatter.ts
|
|
5548
|
-
import
|
|
5574
|
+
import fs10 from "fs/promises";
|
|
5549
5575
|
|
|
5550
5576
|
// src/markdown/frontmatter.ts
|
|
5551
5577
|
import { parse as parse3 } from "yaml";
|
|
@@ -5647,7 +5673,7 @@ var checkFrontmatter = async (rootDir, config, markdownPaths, truthDocumentEntri
|
|
|
5647
5673
|
}
|
|
5648
5674
|
const absolutePath = resolveRepoPath(rootDir, markdownPath);
|
|
5649
5675
|
await assertRepoContainment(rootDir, absolutePath);
|
|
5650
|
-
const source = await
|
|
5676
|
+
const source = await fs10.readFile(absolutePath, "utf8");
|
|
5651
5677
|
let document;
|
|
5652
5678
|
try {
|
|
5653
5679
|
parseFrontmatter(source, { throwOnInvalid: true });
|
|
@@ -5737,11 +5763,11 @@ var checkFrontmatter = async (rootDir, config, markdownPaths, truthDocumentEntri
|
|
|
5737
5763
|
};
|
|
5738
5764
|
|
|
5739
5765
|
// src/checks/links.ts
|
|
5740
|
-
import
|
|
5766
|
+
import fs11 from "fs/promises";
|
|
5741
5767
|
import path5 from "path";
|
|
5742
|
-
var
|
|
5768
|
+
var pathExists3 = async (absolutePath) => {
|
|
5743
5769
|
try {
|
|
5744
|
-
await
|
|
5770
|
+
await fs11.stat(absolutePath);
|
|
5745
5771
|
return true;
|
|
5746
5772
|
} catch (error) {
|
|
5747
5773
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -5757,7 +5783,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
|
|
|
5757
5783
|
continue;
|
|
5758
5784
|
}
|
|
5759
5785
|
const absolutePath = resolveRepoPath(rootDir, markdownPath);
|
|
5760
|
-
const source = await
|
|
5786
|
+
const source = await fs11.readFile(absolutePath, "utf8");
|
|
5761
5787
|
let document;
|
|
5762
5788
|
try {
|
|
5763
5789
|
document = parseMarkdownDocument(source);
|
|
@@ -5785,7 +5811,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
|
|
|
5785
5811
|
});
|
|
5786
5812
|
continue;
|
|
5787
5813
|
}
|
|
5788
|
-
if (!await
|
|
5814
|
+
if (!await pathExists3(absoluteTarget)) {
|
|
5789
5815
|
diagnostics.push({
|
|
5790
5816
|
category: "links",
|
|
5791
5817
|
severity: "error",
|
|
@@ -5799,12 +5825,12 @@ var checkLinks = async (rootDir, markdownPaths) => {
|
|
|
5799
5825
|
};
|
|
5800
5826
|
|
|
5801
5827
|
// src/checks/areas.ts
|
|
5802
|
-
import
|
|
5828
|
+
import fs13 from "fs/promises";
|
|
5803
5829
|
import fg4 from "fast-glob";
|
|
5804
5830
|
import micromatch4 from "micromatch";
|
|
5805
5831
|
|
|
5806
5832
|
// src/routing/area-resolver.ts
|
|
5807
|
-
import
|
|
5833
|
+
import fs12 from "fs/promises";
|
|
5808
5834
|
import fg3 from "fast-glob";
|
|
5809
5835
|
import micromatch2 from "micromatch";
|
|
5810
5836
|
var unique = (values) => {
|
|
@@ -5855,7 +5881,7 @@ var ensureChildPath = async (rootDir, areaFilesRoot, filePath) => {
|
|
|
5855
5881
|
var readRouteFile = async (rootDir, filePath) => {
|
|
5856
5882
|
try {
|
|
5857
5883
|
return {
|
|
5858
|
-
source: await
|
|
5884
|
+
source: await fs12.readFile(resolveRepoPath(rootDir, filePath), "utf8"),
|
|
5859
5885
|
diagnostic: null
|
|
5860
5886
|
};
|
|
5861
5887
|
} catch (error) {
|
|
@@ -6161,9 +6187,9 @@ var classifyPath = (filePath, ignorePatterns) => {
|
|
|
6161
6187
|
var looksLikeGlob2 = (pattern) => {
|
|
6162
6188
|
return /[*?[\]{}()!+@]/u.test(pattern);
|
|
6163
6189
|
};
|
|
6164
|
-
var
|
|
6190
|
+
var pathExists4 = async (absolutePath) => {
|
|
6165
6191
|
try {
|
|
6166
|
-
await
|
|
6192
|
+
await fs13.stat(absolutePath);
|
|
6167
6193
|
return true;
|
|
6168
6194
|
} catch (error) {
|
|
6169
6195
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -6453,7 +6479,7 @@ var checkAreas = async (rootDir, config) => {
|
|
|
6453
6479
|
areaHasTruthDocumentErrors = true;
|
|
6454
6480
|
continue;
|
|
6455
6481
|
}
|
|
6456
|
-
if (!await
|
|
6482
|
+
if (!await pathExists4(absoluteTruthDocumentPath)) {
|
|
6457
6483
|
diagnostics.push({
|
|
6458
6484
|
category: "area-index",
|
|
6459
6485
|
severity: "error",
|
|
@@ -6557,7 +6583,7 @@ var checkAreas = async (rootDir, config) => {
|
|
|
6557
6583
|
entry.valid = false;
|
|
6558
6584
|
continue;
|
|
6559
6585
|
}
|
|
6560
|
-
if (!await
|
|
6586
|
+
if (!await pathExists4(absoluteCodeSurfacePath)) {
|
|
6561
6587
|
diagnostics.push({
|
|
6562
6588
|
category: "area-index",
|
|
6563
6589
|
severity: "error",
|
|
@@ -6604,7 +6630,7 @@ var checkAreas = async (rootDir, config) => {
|
|
|
6604
6630
|
};
|
|
6605
6631
|
|
|
6606
6632
|
// src/checks/decisions.ts
|
|
6607
|
-
import
|
|
6633
|
+
import fs14 from "fs/promises";
|
|
6608
6634
|
import micromatch5 from "micromatch";
|
|
6609
6635
|
var PRODUCT_CAPABILITY_REQUIRED_HEADINGS = [
|
|
6610
6636
|
"Capability Promise",
|
|
@@ -6720,7 +6746,7 @@ var checkDecisionSections = async (rootDir, config, markdownPaths, truthDocument
|
|
|
6720
6746
|
(filePath) => truthDocumentMap.has(filePath) || isDecisionTruthCandidate(config, filePath)
|
|
6721
6747
|
).sort();
|
|
6722
6748
|
for (const filePath of candidatePaths) {
|
|
6723
|
-
const source = await
|
|
6749
|
+
const source = await fs14.readFile(
|
|
6724
6750
|
resolveRepoPath(rootDir, filePath),
|
|
6725
6751
|
"utf8"
|
|
6726
6752
|
);
|
|
@@ -6761,61 +6787,6 @@ var checkDecisionSections = async (rootDir, config, markdownPaths, truthDocument
|
|
|
6761
6787
|
return diagnostics;
|
|
6762
6788
|
};
|
|
6763
6789
|
|
|
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
6790
|
// src/impact/build.ts
|
|
6820
6791
|
import path10 from "path";
|
|
6821
6792
|
import micromatch7 from "micromatch";
|
|
@@ -7195,7 +7166,7 @@ var listChangedPaths = async (cwd, args) => {
|
|
|
7195
7166
|
const result = await execa3("git", args, { cwd });
|
|
7196
7167
|
return result.stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => normalizePath3(line));
|
|
7197
7168
|
};
|
|
7198
|
-
var
|
|
7169
|
+
var pathExists5 = async (filePath) => {
|
|
7199
7170
|
try {
|
|
7200
7171
|
await fs17.access(filePath);
|
|
7201
7172
|
return true;
|
|
@@ -7241,7 +7212,7 @@ var getUncommittedChanges = async (cwd) => {
|
|
|
7241
7212
|
const deletedPathCandidates = /* @__PURE__ */ new Set([...stagedDeletedPaths, ...unstagedDeletedPaths]);
|
|
7242
7213
|
for (const deletedPath of deletedPathCandidates) {
|
|
7243
7214
|
const change = getOrCreateChange(changesByPath, deletedPath);
|
|
7244
|
-
change.deleted = !await
|
|
7215
|
+
change.deleted = !await pathExists5(path9.join(rootDir, deletedPath));
|
|
7245
7216
|
}
|
|
7246
7217
|
return Array.from(changesByPath.values()).sort((left, right) => {
|
|
7247
7218
|
return left.path.localeCompare(right.path);
|
|
@@ -7499,7 +7470,7 @@ var parseEvidenceReferences = async (rootDir, truthDocPath) => {
|
|
|
7499
7470
|
};
|
|
7500
7471
|
|
|
7501
7472
|
// src/evidence/validate.ts
|
|
7502
|
-
var
|
|
7473
|
+
var pathExists6 = async (filePath) => {
|
|
7503
7474
|
try {
|
|
7504
7475
|
await fs19.access(filePath);
|
|
7505
7476
|
return true;
|
|
@@ -7575,7 +7546,7 @@ var validateReference = async (rootDir, reference) => {
|
|
|
7575
7546
|
}
|
|
7576
7547
|
const absolutePath = resolveRepoPath(rootDir, reference.path);
|
|
7577
7548
|
await assertRepoContainment(rootDir, absolutePath);
|
|
7578
|
-
if (!await
|
|
7549
|
+
if (!await pathExists6(absolutePath)) {
|
|
7579
7550
|
diagnostics.push(diagnosticFor(reference, `Referenced file ${reference.path} does not exist.`));
|
|
7580
7551
|
return diagnostics;
|
|
7581
7552
|
}
|
|
@@ -8202,7 +8173,6 @@ var validateEvidenceChecked = (text, errors, checks) => {
|
|
|
8202
8173
|
};
|
|
8203
8174
|
var validateHelperScriptEntries = (entries, requiredHelpers, errors, checks) => {
|
|
8204
8175
|
if (entries === void 0 || entries.length === 0) {
|
|
8205
|
-
errors.push("Helper scripts must include status for optional helpers");
|
|
8206
8176
|
return;
|
|
8207
8177
|
}
|
|
8208
8178
|
const statusPattern = /^(?:-\s*)?([a-z0-9-]+):\s*(?:ran,\s*passed|skipped,\s*\S.*)$/iu;
|
|
@@ -8222,7 +8192,7 @@ var validateHelperScriptEntries = (entries, requiredHelpers, errors, checks) =>
|
|
|
8222
8192
|
errors.push(`missing Helper scripts status: ${helperId}`);
|
|
8223
8193
|
}
|
|
8224
8194
|
}
|
|
8225
|
-
if (errors.length === 0) {
|
|
8195
|
+
if (errors.length === 0 && requiredHelpers.length > 0) {
|
|
8226
8196
|
checks.push(`Helper scripts statuses include ${requiredHelpers.join(", ")}`);
|
|
8227
8197
|
}
|
|
8228
8198
|
};
|
|
@@ -8270,12 +8240,7 @@ var validateTruthSyncReportText = (text) => {
|
|
|
8270
8240
|
if (report.syncIntent !== void 0) {
|
|
8271
8241
|
checks.push("Sync Intent");
|
|
8272
8242
|
}
|
|
8273
|
-
validateHelperScriptEntries(
|
|
8274
|
-
report.helperScripts,
|
|
8275
|
-
["validate-write-lease"],
|
|
8276
|
-
errors,
|
|
8277
|
-
checks
|
|
8278
|
-
);
|
|
8243
|
+
validateHelperScriptEntries(report.helperScripts, [], errors, checks);
|
|
8279
8244
|
} catch (error) {
|
|
8280
8245
|
errors.push(error instanceof Error ? error.message : "invalid Truth Sync report");
|
|
8281
8246
|
}
|
|
@@ -8310,11 +8275,6 @@ var validateTruthDocumentReportText = (text) => {
|
|
|
8310
8275
|
} else {
|
|
8311
8276
|
errors.push("missing required section: Evidence checked");
|
|
8312
8277
|
}
|
|
8313
|
-
if (hasLabel(text, "Helper scripts")) {
|
|
8314
|
-
checks.push("Helper scripts");
|
|
8315
|
-
} else {
|
|
8316
|
-
errors.push("missing required section: Helper scripts");
|
|
8317
|
-
}
|
|
8318
8278
|
const truthDocsUpdated = getSection(text, "Truth docs updated");
|
|
8319
8279
|
const truthDocsCreated = getSection(text, "Truth docs created");
|
|
8320
8280
|
if (truthDocsUpdated === null && truthDocsCreated === null) {
|
|
@@ -8327,7 +8287,7 @@ var validateTruthDocumentReportText = (text) => {
|
|
|
8327
8287
|
checks.push("Truth docs updated or created");
|
|
8328
8288
|
}
|
|
8329
8289
|
validateEvidenceChecked(text, errors, checks);
|
|
8330
|
-
validateHelperScripts(text, [
|
|
8290
|
+
validateHelperScripts(text, [], errors, checks);
|
|
8331
8291
|
} else if (status === "blocked") {
|
|
8332
8292
|
requireBulletSection(text, "Reason", errors, checks);
|
|
8333
8293
|
}
|