@jasonbelmonti/markdown-engine 2.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/README.md +132 -57
  3. package/dist/api/contracts.d.ts +2 -1
  4. package/dist/api/contracts.d.ts.map +1 -1
  5. package/dist/api/contracts.js +1 -0
  6. package/dist/api/contracts.js.map +1 -1
  7. package/dist/api/declarative-validation.d.ts +2 -2
  8. package/dist/api/declarative-validation.d.ts.map +1 -1
  9. package/dist/api/declarative-validation.js +53 -31
  10. package/dist/api/declarative-validation.js.map +1 -1
  11. package/dist/api/document-set-validation-types.d.ts +32 -0
  12. package/dist/api/document-set-validation-types.d.ts.map +1 -0
  13. package/dist/api/document-set-validation-types.js +2 -0
  14. package/dist/api/document-set-validation-types.js.map +1 -0
  15. package/dist/api/document-set-validation.d.ts +4 -0
  16. package/dist/api/document-set-validation.d.ts.map +1 -0
  17. package/dist/api/document-set-validation.js +60 -0
  18. package/dist/api/document-set-validation.js.map +1 -0
  19. package/dist/api/serialize.d.ts +2 -1
  20. package/dist/api/serialize.d.ts.map +1 -1
  21. package/dist/api/serialize.js.map +1 -1
  22. package/dist/cli/declarative-validation.d.ts.map +1 -1
  23. package/dist/cli/declarative-validation.js +7 -12
  24. package/dist/cli/declarative-validation.js.map +1 -1
  25. package/dist/declarative-validation/applicability/classifier.d.ts +18 -0
  26. package/dist/declarative-validation/applicability/classifier.d.ts.map +1 -0
  27. package/dist/declarative-validation/applicability/classifier.js +37 -0
  28. package/dist/declarative-validation/applicability/classifier.js.map +1 -0
  29. package/dist/declarative-validation/applicability/index.d.ts +2 -0
  30. package/dist/declarative-validation/applicability/index.d.ts.map +1 -0
  31. package/dist/declarative-validation/applicability/index.js +2 -0
  32. package/dist/declarative-validation/applicability/index.js.map +1 -0
  33. package/dist/declarative-validation/assertions/context.d.ts +2 -2
  34. package/dist/declarative-validation/assertions/context.d.ts.map +1 -1
  35. package/dist/declarative-validation/assertions/diagnostics.d.ts +7 -4
  36. package/dist/declarative-validation/assertions/diagnostics.d.ts.map +1 -1
  37. package/dist/declarative-validation/assertions/diagnostics.js +26 -1
  38. package/dist/declarative-validation/assertions/diagnostics.js.map +1 -1
  39. package/dist/declarative-validation/assertions/evaluator.d.ts +2 -2
  40. package/dist/declarative-validation/assertions/evaluator.d.ts.map +1 -1
  41. package/dist/declarative-validation/assertions/evaluator.js +9 -0
  42. package/dist/declarative-validation/assertions/evaluator.js.map +1 -1
  43. package/dist/declarative-validation/assertions/frontmatter-shape.d.ts +9 -0
  44. package/dist/declarative-validation/assertions/frontmatter-shape.d.ts.map +1 -0
  45. package/dist/declarative-validation/assertions/frontmatter-shape.js +105 -0
  46. package/dist/declarative-validation/assertions/frontmatter-shape.js.map +1 -0
  47. package/dist/declarative-validation/assertions/group-evaluator.d.ts +6 -0
  48. package/dist/declarative-validation/assertions/group-evaluator.d.ts.map +1 -0
  49. package/dist/declarative-validation/assertions/group-evaluator.js +57 -0
  50. package/dist/declarative-validation/assertions/group-evaluator.js.map +1 -0
  51. package/dist/declarative-validation/assertions/id-targets.d.ts +15 -0
  52. package/dist/declarative-validation/assertions/id-targets.d.ts.map +1 -1
  53. package/dist/declarative-validation/assertions/id-targets.js +18 -55
  54. package/dist/declarative-validation/assertions/id-targets.js.map +1 -1
  55. package/dist/declarative-validation/assertions/ids.d.ts.map +1 -1
  56. package/dist/declarative-validation/assertions/ids.js +100 -14
  57. package/dist/declarative-validation/assertions/ids.js.map +1 -1
  58. package/dist/declarative-validation/assertions/index.d.ts +1 -0
  59. package/dist/declarative-validation/assertions/index.d.ts.map +1 -1
  60. package/dist/declarative-validation/assertions/index.js +1 -0
  61. package/dist/declarative-validation/assertions/index.js.map +1 -1
  62. package/dist/declarative-validation/assertions/table-column-coverage.d.ts +9 -0
  63. package/dist/declarative-validation/assertions/table-column-coverage.d.ts.map +1 -0
  64. package/dist/declarative-validation/assertions/table-column-coverage.js +108 -0
  65. package/dist/declarative-validation/assertions/table-column-coverage.js.map +1 -0
  66. package/dist/declarative-validation/assertions/text-format.d.ts +9 -0
  67. package/dist/declarative-validation/assertions/text-format.d.ts.map +1 -0
  68. package/dist/declarative-validation/assertions/text-format.js +75 -0
  69. package/dist/declarative-validation/assertions/text-format.js.map +1 -0
  70. package/dist/declarative-validation/compiler/applicability-plan.d.ts +5 -0
  71. package/dist/declarative-validation/compiler/applicability-plan.d.ts.map +1 -0
  72. package/dist/declarative-validation/compiler/applicability-plan.js +22 -0
  73. package/dist/declarative-validation/compiler/applicability-plan.js.map +1 -0
  74. package/dist/declarative-validation/compiler/assertion-builders.d.ts +2 -1
  75. package/dist/declarative-validation/compiler/assertion-builders.d.ts.map +1 -1
  76. package/dist/declarative-validation/compiler/assertion-builders.js +88 -13
  77. package/dist/declarative-validation/compiler/assertion-builders.js.map +1 -1
  78. package/dist/declarative-validation/compiler/assertion-shapes.d.ts +5 -1
  79. package/dist/declarative-validation/compiler/assertion-shapes.d.ts.map +1 -1
  80. package/dist/declarative-validation/compiler/assertion-shapes.js +120 -0
  81. package/dist/declarative-validation/compiler/assertion-shapes.js.map +1 -1
  82. package/dist/declarative-validation/compiler/assertions.d.ts +2 -1
  83. package/dist/declarative-validation/compiler/assertions.d.ts.map +1 -1
  84. package/dist/declarative-validation/compiler/assertions.js +16 -4
  85. package/dist/declarative-validation/compiler/assertions.js.map +1 -1
  86. package/dist/declarative-validation/compiler/compatibility.d.ts.map +1 -1
  87. package/dist/declarative-validation/compiler/compatibility.js +3 -0
  88. package/dist/declarative-validation/compiler/compatibility.js.map +1 -1
  89. package/dist/declarative-validation/compiler/group-plans.d.ts +6 -0
  90. package/dist/declarative-validation/compiler/group-plans.d.ts.map +1 -0
  91. package/dist/declarative-validation/compiler/group-plans.js +67 -0
  92. package/dist/declarative-validation/compiler/group-plans.js.map +1 -0
  93. package/dist/declarative-validation/compiler/index.d.ts +1 -1
  94. package/dist/declarative-validation/compiler/index.d.ts.map +1 -1
  95. package/dist/declarative-validation/compiler/index.js +70 -35
  96. package/dist/declarative-validation/compiler/index.js.map +1 -1
  97. package/dist/declarative-validation/compiler/plan.d.ts +80 -5
  98. package/dist/declarative-validation/compiler/plan.d.ts.map +1 -1
  99. package/dist/declarative-validation/compiler/rule-fields.d.ts +6 -0
  100. package/dist/declarative-validation/compiler/rule-fields.d.ts.map +1 -0
  101. package/dist/declarative-validation/compiler/rule-fields.js +40 -0
  102. package/dist/declarative-validation/compiler/rule-fields.js.map +1 -0
  103. package/dist/declarative-validation/diagnostics/profile-config-diagnostics.d.ts +0 -1
  104. package/dist/declarative-validation/diagnostics/profile-config-diagnostics.d.ts.map +1 -1
  105. package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js +8 -2
  106. package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js.map +1 -1
  107. package/dist/declarative-validation/evidence/index.d.ts +3 -3
  108. package/dist/declarative-validation/evidence/index.d.ts.map +1 -1
  109. package/dist/declarative-validation/evidence/index.js +6 -6
  110. package/dist/declarative-validation/evidence/index.js.map +1 -1
  111. package/dist/declarative-validation/profile/applicability-schema.d.ts +4 -0
  112. package/dist/declarative-validation/profile/applicability-schema.d.ts.map +1 -0
  113. package/dist/declarative-validation/profile/applicability-schema.js +24 -0
  114. package/dist/declarative-validation/profile/applicability-schema.js.map +1 -0
  115. package/dist/declarative-validation/profile/assertion-schema.d.ts +2 -1
  116. package/dist/declarative-validation/profile/assertion-schema.d.ts.map +1 -1
  117. package/dist/declarative-validation/profile/assertion-schema.js +194 -14
  118. package/dist/declarative-validation/profile/assertion-schema.js.map +1 -1
  119. package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts +3 -1
  120. package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts.map +1 -1
  121. package/dist/declarative-validation/profile/direct-profile-diagnostics.js +10 -2
  122. package/dist/declarative-validation/profile/direct-profile-diagnostics.js.map +1 -1
  123. package/dist/declarative-validation/profile/frontmatter-shape-schema.d.ts +8 -0
  124. package/dist/declarative-validation/profile/frontmatter-shape-schema.d.ts.map +1 -0
  125. package/dist/declarative-validation/profile/frontmatter-shape-schema.js +178 -0
  126. package/dist/declarative-validation/profile/frontmatter-shape-schema.js.map +1 -0
  127. package/dist/declarative-validation/profile/group-schema.d.ts +5 -0
  128. package/dist/declarative-validation/profile/group-schema.d.ts.map +1 -0
  129. package/dist/declarative-validation/profile/group-schema.js +55 -0
  130. package/dist/declarative-validation/profile/group-schema.js.map +1 -0
  131. package/dist/declarative-validation/profile/ids-assertion-contract.d.ts +12 -0
  132. package/dist/declarative-validation/profile/ids-assertion-contract.d.ts.map +1 -0
  133. package/dist/declarative-validation/profile/ids-assertion-contract.js +32 -0
  134. package/dist/declarative-validation/profile/ids-assertion-contract.js.map +1 -0
  135. package/dist/declarative-validation/profile/index.d.ts +63 -2
  136. package/dist/declarative-validation/profile/index.d.ts.map +1 -1
  137. package/dist/declarative-validation/profile/index.js.map +1 -1
  138. package/dist/declarative-validation/profile/materialization.d.ts.map +1 -1
  139. package/dist/declarative-validation/profile/materialization.js +13 -10
  140. package/dist/declarative-validation/profile/materialization.js.map +1 -1
  141. package/dist/declarative-validation/profile/schema.d.ts.map +1 -1
  142. package/dist/declarative-validation/profile/schema.js +73 -12
  143. package/dist/declarative-validation/profile/schema.js.map +1 -1
  144. package/dist/declarative-validation/profile/syntax-version.d.ts +7 -0
  145. package/dist/declarative-validation/profile/syntax-version.d.ts.map +1 -0
  146. package/dist/declarative-validation/profile/syntax-version.js +11 -0
  147. package/dist/declarative-validation/profile/syntax-version.js.map +1 -0
  148. package/dist/declarative-validation/profile/text-format-contract.d.ts +4 -0
  149. package/dist/declarative-validation/profile/text-format-contract.d.ts.map +1 -0
  150. package/dist/declarative-validation/profile/text-format-contract.js +6 -0
  151. package/dist/declarative-validation/profile/text-format-contract.js.map +1 -0
  152. package/dist/declarative-validation/results/clone-rule-result.d.ts +6 -0
  153. package/dist/declarative-validation/results/clone-rule-result.d.ts.map +1 -0
  154. package/dist/declarative-validation/results/clone-rule-result.js +125 -0
  155. package/dist/declarative-validation/results/clone-rule-result.js.map +1 -0
  156. package/dist/declarative-validation/results/create-result.d.ts +15 -0
  157. package/dist/declarative-validation/results/create-result.d.ts.map +1 -0
  158. package/dist/declarative-validation/results/create-result.js +58 -0
  159. package/dist/declarative-validation/results/create-result.js.map +1 -0
  160. package/dist/declarative-validation/results/index.d.ts +3 -25
  161. package/dist/declarative-validation/results/index.d.ts.map +1 -1
  162. package/dist/declarative-validation/results/index.js +2 -1
  163. package/dist/declarative-validation/results/index.js.map +1 -1
  164. package/dist/declarative-validation/results/skipped-rule-result.d.ts +10 -0
  165. package/dist/declarative-validation/results/skipped-rule-result.d.ts.map +1 -0
  166. package/dist/declarative-validation/results/skipped-rule-result.js +18 -0
  167. package/dist/declarative-validation/results/skipped-rule-result.js.map +1 -0
  168. package/dist/declarative-validation/results/types.d.ts +77 -0
  169. package/dist/declarative-validation/results/types.d.ts.map +1 -0
  170. package/dist/declarative-validation/results/types.js +2 -0
  171. package/dist/declarative-validation/results/types.js.map +1 -0
  172. package/dist/declarative-validation/selectors/table-targets.d.ts +23 -0
  173. package/dist/declarative-validation/selectors/table-targets.d.ts.map +1 -1
  174. package/dist/declarative-validation/selectors/table-targets.js +52 -9
  175. package/dist/declarative-validation/selectors/table-targets.js.map +1 -1
  176. package/dist-bundled/markdown-engine-cli.mjs +27373 -0
  177. package/docs/contracts/api.md +79 -15
  178. package/docs/contracts/declarative-validation.md +462 -40
  179. package/fixtures/declarative-validation/examples/okf-v0.1/fail/invalid-log-date/log.md +5 -0
  180. package/fixtures/declarative-validation/examples/okf-v0.1/fail/missing-concept-type/concepts/customer-metric.md +8 -0
  181. package/fixtures/declarative-validation/examples/okf-v0.1/fail/non-root-index-frontmatter/datasets/index.md +7 -0
  182. package/fixtures/declarative-validation/examples/okf-v0.1/pass/datasets/index.md +3 -0
  183. package/fixtures/declarative-validation/examples/okf-v0.1/pass/datasets/sales.md +16 -0
  184. package/fixtures/declarative-validation/examples/okf-v0.1/pass/index.md +8 -0
  185. package/fixtures/declarative-validation/examples/okf-v0.1/pass/log.md +9 -0
  186. package/fixtures/declarative-validation/examples/okf-v0.1/pass/playbooks/incident-response.md +17 -0
  187. package/fixtures/declarative-validation/examples/okf-v0.1/profiles/concept.yaml +14 -0
  188. package/fixtures/declarative-validation/examples/okf-v0.1/profiles/log.yaml +10 -0
  189. package/fixtures/declarative-validation/examples/okf-v0.1/profiles/non-root-index.yaml +9 -0
  190. package/fixtures/declarative-validation/examples/okf-v0.1/profiles/root-index.yaml +12 -0
  191. package/package.json +9 -3
  192. package/scripts/install-markdown-engine-cli.sh +113 -0
  193. package/skills/profile-backed-markdown/SKILL.md +54 -0
  194. package/skills/profile-backed-markdown/assets/profiles/operational-spec.yaml +98 -0
  195. package/skills/profile-backed-markdown/references/repair-brief.md +14 -0
  196. package/skills/profile-backed-markdown/scripts/validate-profile-backed-markdown.mjs +590 -0
@@ -0,0 +1,5 @@
1
+ # Directory Update Log
2
+
3
+ ## 2026-02-30
4
+
5
+ * **Update**: This date heading is intentionally invalid.
@@ -0,0 +1,8 @@
1
+ ---
2
+ title: Customer Metric
3
+ description: A concept fixture that omits the required type field.
4
+ ---
5
+
6
+ # Definition
7
+
8
+ This fixture is intentionally missing `type` frontmatter for OKF concept validation.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Datasets
3
+ ---
4
+
5
+ # Datasets
6
+
7
+ * [Customer metric](customer-metric.md) - This non-root index intentionally has frontmatter.
@@ -0,0 +1,3 @@
1
+ # Datasets
2
+
3
+ * [Sales dataset](sales.md) - Sales knowledge assets.
@@ -0,0 +1,16 @@
1
+ ---
2
+ type: BigQuery Dataset
3
+ title: Sales Dataset
4
+ description: Sales reporting assets for the example bundle.
5
+ resource: https://example.com/bigquery/datasets/sales
6
+ tags: [sales, reporting]
7
+ timestamp: 2026-06-15T00:00:00Z
8
+ ---
9
+
10
+ # Schema
11
+
12
+ The sales dataset contains curated order and customer reporting tables.
13
+
14
+ # Citations
15
+
16
+ [1] [Internal sales catalog](https://example.com/catalog/sales)
@@ -0,0 +1,8 @@
1
+ ---
2
+ okf_version: "0.1"
3
+ ---
4
+
5
+ # Knowledge Bundle
6
+
7
+ * [Datasets](datasets/) - Curated data assets and related concepts.
8
+ * [Incident response](playbooks/incident-response.md) - Operational playbook concept.
@@ -0,0 +1,9 @@
1
+ # Directory Update Log
2
+
3
+ ## 2026-06-15
4
+
5
+ * **Creation**: Added the initial OKF v0.1 example bundle.
6
+
7
+ ## 2026-06-01
8
+
9
+ * **Initialization**: Established the example knowledge bundle structure.
@@ -0,0 +1,17 @@
1
+ ---
2
+ type: Playbook
3
+ title: Incident Response
4
+ description: Triage steps for a data freshness incident.
5
+ tags: [oncall, freshness]
6
+ timestamp: 2026-06-15T00:00:00Z
7
+ ---
8
+
9
+ # Trigger
10
+
11
+ A freshness alert fires when an expected dataset update is delayed.
12
+
13
+ # Steps
14
+
15
+ 1. Check the ingestion dashboard.
16
+ 2. Notify the on-call owner.
17
+ 3. Record the incident in the bundle log.
@@ -0,0 +1,14 @@
1
+ syntaxVersion: markdown-engine.validation@v2
2
+ documentVersion: 1.0.0
3
+ rules:
4
+ - id: okf.concept.frontmatter
5
+ select:
6
+ target: document
7
+ assert:
8
+ frontmatterShape:
9
+ presence: required
10
+ fields:
11
+ - field: type
12
+ required: true
13
+ valueType: string
14
+ nonEmpty: true
@@ -0,0 +1,10 @@
1
+ syntaxVersion: markdown-engine.validation@v2
2
+ documentVersion: 1.0.0
3
+ rules:
4
+ - id: okf.log.date-heading
5
+ select:
6
+ target: heading
7
+ depth: 2
8
+ assert:
9
+ textFormat:
10
+ format: isoDate
@@ -0,0 +1,9 @@
1
+ syntaxVersion: markdown-engine.validation@v2
2
+ documentVersion: 1.0.0
3
+ rules:
4
+ - id: okf.non-root-index.no-frontmatter
5
+ select:
6
+ target: document
7
+ assert:
8
+ frontmatterShape:
9
+ presence: forbidden
@@ -0,0 +1,12 @@
1
+ syntaxVersion: markdown-engine.validation@v2
2
+ documentVersion: 1.0.0
3
+ rules:
4
+ - id: okf.root-index.version-frontmatter
5
+ select:
6
+ target: document
7
+ assert:
8
+ frontmatterShape:
9
+ fields:
10
+ - field: okf_version
11
+ valueType: string
12
+ nonEmpty: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jasonbelmonti/markdown-engine",
3
- "version": "2.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Deterministic Markdown parsing and validation engine package.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,6 +31,9 @@
31
31
  "types": "./dist/index.d.ts",
32
32
  "files": [
33
33
  "dist",
34
+ "dist-bundled",
35
+ "scripts/install-markdown-engine-cli.sh",
36
+ "skills",
34
37
  "docs/contracts",
35
38
  "fixtures/declarative-validation/examples",
36
39
  "CHANGELOG.md",
@@ -42,9 +45,11 @@
42
45
  "scripts": {
43
46
  "clean": "node scripts/clean-dist.mjs",
44
47
  "build": "npm run clean && tsc -p tsconfig.json",
48
+ "build:cli:bundled": "node scripts/build-bundled-cli.mjs",
49
+ "build:cli-bundle": "node scripts/build-cli-bundle.mjs",
45
50
  "prepack": "npm run release:verify",
46
51
  "prepublishOnly": "npm run release:verify",
47
- "release:verify": "npm run typecheck && npm test && node scripts/check-boundaries.mjs && npm run docs:rich-ir-contract && npm run docs:declarative-validation-contract && npm run audit:declarative-validation-boundary && npm run build && node scripts/prove-repeatability.mjs --runs 10 && npm run release:check-clean",
52
+ "release:verify": "npm run typecheck && npm test && node scripts/check-boundaries.mjs && npm run docs:rich-ir-contract && npm run docs:declarative-validation-contract && npm run audit:declarative-validation-boundary && npm run build && npm run build:cli:bundled && node scripts/prove-repeatability.mjs --runs 10 && npm run release:check-clean",
48
53
  "release:check-clean": "git diff --check HEAD -- && git diff --exit-code HEAD --",
49
54
  "snapshots:update:parser": "npm run build && vitest run tests/parser-fixtures.test.ts -u \"--exclude=.worktrees/**\"",
50
55
  "snapshots:update:rules": "npm run build && vitest run tests/rules.test.ts -u \"--exclude=.worktrees/**\"",
@@ -65,7 +70,7 @@
65
70
  "test:validation:profile": "npm run build && vitest run tests/declarative-validation-profile.test.ts \"--exclude=.worktrees/**\"",
66
71
  "test:validation:compiler": "npm run build && vitest run tests/declarative-validation-compiler.test.ts \"--exclude=.worktrees/**\"",
67
72
  "test:validation:selectors": "npm run build && vitest run tests/declarative-validation-selectors.test.ts \"--exclude=.worktrees/**\"",
68
- "test:validation:assertions": "npm run build && vitest run tests/declarative-validation-assertions.test.ts \"--exclude=.worktrees/**\"",
73
+ "test:validation:assertions": "npm run build && vitest run tests/declarative-validation-assertions.test.ts tests/declarative-validation-frontmatter-shape-assertions.test.ts tests/declarative-validation-table-column-coverage-fixtures.test.ts tests/declarative-validation-grouped-rules-fixtures.test.ts tests/declarative-validation-when-skipped-rules-fixtures.test.ts \"--exclude=.worktrees/**\"",
69
74
  "test:validation:diagnostics": "npm run build && vitest run tests/declarative-validation-diagnostics.test.ts \"--exclude=.worktrees/**\"",
70
75
  "test:validation:cli": "npm run build && vitest run tests/declarative-validation-cli.test.ts \"--exclude=.worktrees/**\"",
71
76
  "test:validation:examples": "npm run build && vitest run tests/declarative-validation-examples.test.ts \"--exclude=.worktrees/**\"",
@@ -83,6 +88,7 @@
83
88
  "devDependencies": {
84
89
  "@types/node": "^22.19.17",
85
90
  "cmark-gfm": "^0.9.0",
91
+ "esbuild": "^0.27.7",
86
92
  "typescript": "^5.8.3",
87
93
  "vitest": "^3.1.3"
88
94
  },
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env sh
2
+ set -eu
3
+
4
+ VERSION="3.0.0"
5
+ PACKAGE="@jasonbelmonti/markdown-engine"
6
+ EXPECTED_SHA256="f61ab59e28eb92cccf4fd8073c090102e67a9397a7f0d208661ded14b879053d"
7
+ DEFAULT_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
8
+ MARKDOWN_ENGINE_HOME="${MARKDOWN_ENGINE_HOME:-$DEFAULT_DATA_HOME/markdown-engine}"
9
+ MARKDOWN_ENGINE_BIN_DIR="${MARKDOWN_ENGINE_BIN_DIR:-$HOME/.local/bin}"
10
+ INSTALL_DIR="$MARKDOWN_ENGINE_HOME/tools/markdown-engine/$VERSION"
11
+ INSTALL_CLI="$INSTALL_DIR/markdown-engine-cli.mjs"
12
+ BIN_DIR="$MARKDOWN_ENGINE_BIN_DIR"
13
+ BIN_PATH="$BIN_DIR/markdown-engine"
14
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
15
+ REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
16
+ LOCAL_CLI="$REPO_ROOT/dist-bundled/markdown-engine-cli.mjs"
17
+ PACKED_CLI_ENTRY="package/dist-bundled/markdown-engine-cli.mjs"
18
+ TMP_DIR=""
19
+ SOURCE_CLI=""
20
+
21
+ cleanup() {
22
+ if [ -n "$TMP_DIR" ] && [ -d "$TMP_DIR" ]; then
23
+ rm -rf "$TMP_DIR"
24
+ fi
25
+ }
26
+ trap cleanup EXIT HUP INT TERM
27
+
28
+ fail() {
29
+ printf 'install-markdown-engine-cli: %s\n' "$1" >&2
30
+ exit 1
31
+ }
32
+
33
+ require_command() {
34
+ command -v "$1" >/dev/null 2>&1 || fail "required command not found: $1"
35
+ }
36
+
37
+ sha256_of() {
38
+ shasum -a 256 "$1" | awk '{print $1}'
39
+ }
40
+
41
+ shell_quote() {
42
+ printf "'"
43
+ printf '%s' "$1" | sed "s/'/'\\\\''/g"
44
+ printf "'"
45
+ }
46
+
47
+ has_expected_sha() {
48
+ candidate_sha=$(sha256_of "$1")
49
+
50
+ if [ "$candidate_sha" = "$EXPECTED_SHA256" ]; then
51
+ return 0
52
+ fi
53
+
54
+ printf 'install-markdown-engine-cli: ignoring local CLI with unexpected SHA-256 for %s: %s\n' "$1" "$candidate_sha" >&2
55
+ return 1
56
+ }
57
+
58
+ resolve_source_cli() {
59
+ if [ -f "$LOCAL_CLI" ]; then
60
+ if has_expected_sha "$LOCAL_CLI"; then
61
+ SOURCE_CLI="$LOCAL_CLI"
62
+ return 0
63
+ fi
64
+ fi
65
+
66
+ require_command npm
67
+ require_command tar
68
+
69
+ TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/markdown-engine-cli.XXXXXX")
70
+ pack_file=$(npm pack "$PACKAGE@$VERSION" --ignore-scripts --pack-destination "$TMP_DIR" --silent)
71
+
72
+ [ -n "$pack_file" ] || fail "npm pack did not return a tarball name"
73
+ [ -f "$TMP_DIR/$pack_file" ] || fail "npm pack tarball not found: $TMP_DIR/$pack_file"
74
+
75
+ tar -xzf "$TMP_DIR/$pack_file" -C "$TMP_DIR" "$PACKED_CLI_ENTRY" ||
76
+ fail "packed CLI artifact not found in $PACKAGE@$VERSION"
77
+
78
+ packed_cli="$TMP_DIR/$PACKED_CLI_ENTRY"
79
+ [ -f "$packed_cli" ] || fail "packed CLI artifact not found in $PACKAGE@$VERSION"
80
+ SOURCE_CLI="$packed_cli"
81
+ }
82
+
83
+ require_command shasum
84
+ require_command node
85
+ require_command sed
86
+
87
+ resolve_source_cli
88
+ source_cli="$SOURCE_CLI"
89
+ [ -n "$source_cli" ] || fail "unable to resolve bundled CLI source"
90
+ actual_sha=$(sha256_of "$source_cli")
91
+
92
+ if [ "$actual_sha" != "$EXPECTED_SHA256" ]; then
93
+ fail "unexpected CLI SHA-256 for $source_cli: $actual_sha"
94
+ fi
95
+
96
+ mkdir -p "$INSTALL_DIR" "$BIN_DIR"
97
+ cp "$source_cli" "$INSTALL_CLI"
98
+ chmod 755 "$INSTALL_CLI"
99
+
100
+ quoted_install_cli=$(shell_quote "$INSTALL_CLI")
101
+ {
102
+ printf '%s\n' '#!/usr/bin/env sh'
103
+ printf 'DEFAULT_MARKDOWN_ENGINE_CLI=%s\n' "$quoted_install_cli"
104
+ printf '%s\n' 'MARKDOWN_ENGINE_CLI="${MARKDOWN_ENGINE_CLI:-$DEFAULT_MARKDOWN_ENGINE_CLI}"'
105
+ printf '%s\n' 'exec "${NODE_BINARY:-node}" "$MARKDOWN_ENGINE_CLI" "$@"'
106
+ } > "$BIN_PATH"
107
+ chmod 755 "$BIN_PATH"
108
+
109
+ "${NODE_BINARY:-node}" "$INSTALL_CLI" --help >/dev/null
110
+
111
+ printf 'Installed markdown-engine CLI: %s\n' "$INSTALL_CLI"
112
+ printf 'Installed markdown-engine wrapper: %s\n' "$BIN_PATH"
113
+ printf 'SHA-256: %s\n' "$actual_sha"
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: profile-backed-markdown
3
+ description: Validate Markdown files that declare a local markdown-engine validation profile in frontmatter.
4
+ ---
5
+
6
+ # Profile-Backed Markdown
7
+
8
+ Use this skill when a Markdown file contains frontmatter with `validationProfile`
9
+ and you need deterministic profile validation before editing or handing off the
10
+ file.
11
+
12
+ ## Workflow
13
+
14
+ 1. Run the bundled wrapper:
15
+
16
+ ```bash
17
+ node scripts/validate-profile-backed-markdown.mjs --file /path/to/file.md
18
+ ```
19
+
20
+ 2. Treat stdout as the validator JSON source of truth. Do not infer pass/fail
21
+ from prose or repair notes.
22
+ 3. If validation fails, rerun with `--repair-brief` to emit compact repair
23
+ guidance on stderr while preserving validator JSON on stdout.
24
+ 4. Edit the Markdown file only when the user asked for repair. Do not edit
25
+ validation profiles unless explicitly requested.
26
+ 5. Rerun the wrapper after edits and require exit code `0` before reporting the
27
+ document clean.
28
+
29
+ ## Frontmatter Contract
30
+
31
+ The wrapper reads a top-level frontmatter scalar:
32
+
33
+ ```yaml
34
+ validationProfile: operational-spec
35
+ ```
36
+
37
+ Profile names resolve to `assets/profiles/<validationProfile>.yaml` by default.
38
+ The wrapper rejects absolute paths and parent-directory traversal so validation
39
+ profiles stay within the local skill assets.
40
+
41
+ ## Bundled CLI
42
+
43
+ The wrapper does not require a globally installed `markdown-engine` binary. It
44
+ uses `MARKDOWN_ENGINE_CLI` when set, then checks for a local
45
+ `scripts/markdown-engine-cli.mjs`, then falls back to the package-level
46
+ `dist-bundled/markdown-engine-cli.mjs`.
47
+
48
+ For a standalone skill folder, build and copy the bundled CLI artifact before
49
+ distribution:
50
+
51
+ ```bash
52
+ npm run build:cli:bundled
53
+ cp dist-bundled/markdown-engine-cli.mjs skills/profile-backed-markdown/scripts/
54
+ ```
@@ -0,0 +1,98 @@
1
+ syntaxVersion: markdown-engine.validation@v1
2
+ documentVersion: 1.0.0
3
+ rules:
4
+ - id: frontmatter.required
5
+ select:
6
+ target: document
7
+ assert:
8
+ frontmatterRequired:
9
+ fields:
10
+ - title
11
+ - owner
12
+ - status
13
+
14
+ - id: sections.required
15
+ select:
16
+ target: document
17
+ assert:
18
+ sectionsRequired:
19
+ order: strict
20
+ headings:
21
+ - Objective
22
+ - Context / Constraints
23
+ - Execution Plan
24
+ - Risk Register
25
+ - Handoff Links
26
+
27
+ - id: objective.text
28
+ select:
29
+ target: section
30
+ title: Objective
31
+ assert:
32
+ text:
33
+ contains: "Mission control"
34
+
35
+ - id: objective.length
36
+ select:
37
+ target: section
38
+ title: Objective
39
+ assert:
40
+ textLength:
41
+ min: 80
42
+ max: 180
43
+
44
+ - id: risk.table.columns
45
+ select:
46
+ target: table
47
+ section: Risk Register
48
+ header:
49
+ - ID
50
+ - Mitigation
51
+ - Status
52
+ assert:
53
+ tableColumnsRequired:
54
+ columns:
55
+ - ID
56
+ - Mitigation
57
+ - Status
58
+
59
+ - id: risk.ids.unique
60
+ select:
61
+ target: tableCell
62
+ section: Risk Register
63
+ tableHeader:
64
+ - ID
65
+ - Mitigation
66
+ - Status
67
+ column: ID
68
+ assert:
69
+ ids:
70
+ prefix: OPS-RISK
71
+ unique: true
72
+
73
+ - id: execution.must.count
74
+ select:
75
+ target: section
76
+ title: Execution Plan
77
+ assert:
78
+ textOccurrenceCount:
79
+ text: MUST
80
+ count: 2
81
+
82
+ - id: execution.list
83
+ select:
84
+ target: list
85
+ section: Execution Plan
86
+ ordered: false
87
+ assert:
88
+ text:
89
+ contains: "Validate profile"
90
+
91
+ - id: handoff.link
92
+ select:
93
+ target: link
94
+ section: Handoff Links
95
+ text: "handoff packet"
96
+ url: "./handoff-packet.md"
97
+ assert:
98
+ exists: true
@@ -0,0 +1,14 @@
1
+ # Repair Brief Contract
2
+
3
+ `--repair-brief` emits a compact diagnostic summary on stderr and preserves the
4
+ validator JSON result on stdout.
5
+
6
+ Each diagnostic entry is derived from validator JSON only:
7
+
8
+ - `ruleId`: the failing profile rule when present, otherwise `(none)`.
9
+ - `message`: the validator diagnostic message.
10
+ - `sourceRange`: the validator diagnostic range when present, otherwise
11
+ `unavailable`.
12
+
13
+ The wrapper must not invent validation outcomes, synthesize missing diagnostics,
14
+ or edit local profile assets.