@jasonbelmonti/markdown-engine 1.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +113 -56
- package/SECURITY.md +5 -3
- package/dist/api/annotation-source-range.d.ts +7 -0
- package/dist/api/annotation-source-range.d.ts.map +1 -0
- package/dist/api/annotation-source-range.js +103 -0
- package/dist/api/annotation-source-range.js.map +1 -0
- package/dist/api/annotation-target-candidate.d.ts +10 -0
- package/dist/api/annotation-target-candidate.d.ts.map +1 -0
- package/dist/api/annotation-target-candidate.js +14 -0
- package/dist/api/annotation-target-candidate.js.map +1 -0
- package/dist/api/annotation-target-cloning.d.ts +5 -0
- package/dist/api/annotation-target-cloning.d.ts.map +1 -0
- package/dist/api/annotation-target-cloning.js +122 -0
- package/dist/api/annotation-target-cloning.js.map +1 -0
- package/dist/api/annotation-target-diagnostics.d.ts +8 -0
- package/dist/api/annotation-target-diagnostics.d.ts.map +1 -0
- package/dist/api/annotation-target-diagnostics.js +57 -0
- package/dist/api/annotation-target-diagnostics.js.map +1 -0
- package/dist/api/annotation-target-validation.d.ts +2 -2
- package/dist/api/annotation-target-validation.d.ts.map +1 -1
- package/dist/api/annotation-target-validation.js +5 -272
- package/dist/api/annotation-target-validation.js.map +1 -1
- package/dist/api/contracts.d.ts +2 -1
- package/dist/api/contracts.d.ts.map +1 -1
- package/dist/api/contracts.js +1 -0
- package/dist/api/contracts.js.map +1 -1
- package/dist/api/declarative-validation.d.ts +13 -0
- package/dist/api/declarative-validation.d.ts.map +1 -0
- package/dist/api/declarative-validation.js +85 -0
- package/dist/api/declarative-validation.js.map +1 -0
- package/dist/api/document-queries.d.ts.map +1 -1
- package/dist/api/document-queries.js +74 -3
- package/dist/api/document-queries.js.map +1 -1
- package/dist/api/document.d.ts +44 -0
- package/dist/api/document.d.ts.map +1 -1
- package/dist/api/engine-node-attributes.d.ts +15 -0
- package/dist/api/engine-node-attributes.d.ts.map +1 -0
- package/dist/api/engine-node-attributes.js +99 -0
- package/dist/api/engine-node-attributes.js.map +1 -0
- package/dist/api/normalize.d.ts.map +1 -1
- package/dist/api/normalize.js +22 -1
- package/dist/api/normalize.js.map +1 -1
- package/dist/api/serialize.js +2 -14
- package/dist/api/serialize.js.map +1 -1
- package/dist/cli/args.d.ts +6 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +33 -25
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/declarative-validation.d.ts +18 -0
- package/dist/cli/declarative-validation.d.ts.map +1 -0
- package/dist/cli/declarative-validation.js +126 -0
- package/dist/cli/declarative-validation.js.map +1 -0
- package/dist/cli/files.d.ts +1 -0
- package/dist/cli/files.d.ts.map +1 -1
- package/dist/cli/files.js +3 -0
- package/dist/cli/files.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +18 -3
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/validate-args.d.ts +18 -0
- package/dist/cli/validate-args.d.ts.map +1 -0
- package/dist/cli/validate-args.js +131 -0
- package/dist/cli/validate-args.js.map +1 -0
- package/dist/declarative-validation/applicability/classifier.d.ts +18 -0
- package/dist/declarative-validation/applicability/classifier.d.ts.map +1 -0
- package/dist/declarative-validation/applicability/classifier.js +37 -0
- package/dist/declarative-validation/applicability/classifier.js.map +1 -0
- package/dist/declarative-validation/applicability/index.d.ts +2 -0
- package/dist/declarative-validation/applicability/index.d.ts.map +1 -0
- package/dist/declarative-validation/applicability/index.js +2 -0
- package/dist/declarative-validation/applicability/index.js.map +1 -0
- package/dist/declarative-validation/assertions/context.d.ts +8 -0
- package/dist/declarative-validation/assertions/context.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/context.js +2 -0
- package/dist/declarative-validation/assertions/context.js.map +1 -0
- package/dist/declarative-validation/assertions/diagnostics.d.ts +25 -0
- package/dist/declarative-validation/assertions/diagnostics.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/diagnostics.js +96 -0
- package/dist/declarative-validation/assertions/diagnostics.js.map +1 -0
- package/dist/declarative-validation/assertions/document-text-offsets.d.ts +3 -0
- package/dist/declarative-validation/assertions/document-text-offsets.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/document-text-offsets.js +32 -0
- package/dist/declarative-validation/assertions/document-text-offsets.js.map +1 -0
- package/dist/declarative-validation/assertions/evaluator.d.ts +5 -0
- package/dist/declarative-validation/assertions/evaluator.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/evaluator.js +49 -0
- package/dist/declarative-validation/assertions/evaluator.js.map +1 -0
- package/dist/declarative-validation/assertions/exists.d.ts +4 -0
- package/dist/declarative-validation/assertions/exists.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/exists.js +8 -0
- package/dist/declarative-validation/assertions/exists.js.map +1 -0
- package/dist/declarative-validation/assertions/frontmatter-required.d.ts +9 -0
- package/dist/declarative-validation/assertions/frontmatter-required.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/frontmatter-required.js +15 -0
- package/dist/declarative-validation/assertions/frontmatter-required.js.map +1 -0
- package/dist/declarative-validation/assertions/group-evaluator.d.ts +6 -0
- package/dist/declarative-validation/assertions/group-evaluator.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/group-evaluator.js +57 -0
- package/dist/declarative-validation/assertions/group-evaluator.js.map +1 -0
- package/dist/declarative-validation/assertions/id-targets.d.ts +44 -0
- package/dist/declarative-validation/assertions/id-targets.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/id-targets.js +391 -0
- package/dist/declarative-validation/assertions/id-targets.js.map +1 -0
- package/dist/declarative-validation/assertions/id-tokens.d.ts +15 -0
- package/dist/declarative-validation/assertions/id-tokens.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/id-tokens.js +27 -0
- package/dist/declarative-validation/assertions/id-tokens.js.map +1 -0
- package/dist/declarative-validation/assertions/ids.d.ts +9 -0
- package/dist/declarative-validation/assertions/ids.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/ids.js +128 -0
- package/dist/declarative-validation/assertions/ids.js.map +1 -0
- package/dist/declarative-validation/assertions/index.d.ts +4 -0
- package/dist/declarative-validation/assertions/index.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/index.js +4 -0
- package/dist/declarative-validation/assertions/index.js.map +1 -0
- package/dist/declarative-validation/assertions/literal-text.d.ts +2 -0
- package/dist/declarative-validation/assertions/literal-text.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/literal-text.js +14 -0
- package/dist/declarative-validation/assertions/literal-text.js.map +1 -0
- package/dist/declarative-validation/assertions/normalized-source-ranges.d.ts +3 -0
- package/dist/declarative-validation/assertions/normalized-source-ranges.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/normalized-source-ranges.js +105 -0
- package/dist/declarative-validation/assertions/normalized-source-ranges.js.map +1 -0
- package/dist/declarative-validation/assertions/ordering.d.ts +6 -0
- package/dist/declarative-validation/assertions/ordering.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/ordering.js +71 -0
- package/dist/declarative-validation/assertions/ordering.js.map +1 -0
- package/dist/declarative-validation/assertions/references.d.ts +9 -0
- package/dist/declarative-validation/assertions/references.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/references.js +354 -0
- package/dist/declarative-validation/assertions/references.js.map +1 -0
- package/dist/declarative-validation/assertions/sections-required.d.ts +9 -0
- package/dist/declarative-validation/assertions/sections-required.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/sections-required.js +49 -0
- package/dist/declarative-validation/assertions/sections-required.js.map +1 -0
- package/dist/declarative-validation/assertions/table-column-coverage.d.ts +9 -0
- package/dist/declarative-validation/assertions/table-column-coverage.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/table-column-coverage.js +108 -0
- package/dist/declarative-validation/assertions/table-column-coverage.js.map +1 -0
- package/dist/declarative-validation/assertions/table-columns-required.d.ts +9 -0
- package/dist/declarative-validation/assertions/table-columns-required.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/table-columns-required.js +31 -0
- package/dist/declarative-validation/assertions/table-columns-required.js.map +1 -0
- package/dist/declarative-validation/assertions/text-length.d.ts +9 -0
- package/dist/declarative-validation/assertions/text-length.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/text-length.js +40 -0
- package/dist/declarative-validation/assertions/text-length.js.map +1 -0
- package/dist/declarative-validation/assertions/text-occurrence-count.d.ts +9 -0
- package/dist/declarative-validation/assertions/text-occurrence-count.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/text-occurrence-count.js +22 -0
- package/dist/declarative-validation/assertions/text-occurrence-count.js.map +1 -0
- package/dist/declarative-validation/assertions/text.d.ts +9 -0
- package/dist/declarative-validation/assertions/text.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/text.js +32 -0
- package/dist/declarative-validation/assertions/text.js.map +1 -0
- package/dist/declarative-validation/compiler/applicability-plan.d.ts +5 -0
- package/dist/declarative-validation/compiler/applicability-plan.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/applicability-plan.js +22 -0
- package/dist/declarative-validation/compiler/applicability-plan.js.map +1 -0
- package/dist/declarative-validation/compiler/assertion-builders.d.ts +7 -0
- package/dist/declarative-validation/compiler/assertion-builders.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/assertion-builders.js +237 -0
- package/dist/declarative-validation/compiler/assertion-builders.js.map +1 -0
- package/dist/declarative-validation/compiler/assertion-shapes.d.ts +20 -0
- package/dist/declarative-validation/compiler/assertion-shapes.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/assertion-shapes.js +219 -0
- package/dist/declarative-validation/compiler/assertion-shapes.js.map +1 -0
- package/dist/declarative-validation/compiler/assertions.d.ts +6 -0
- package/dist/declarative-validation/compiler/assertions.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/assertions.js +35 -0
- package/dist/declarative-validation/compiler/assertions.js.map +1 -0
- package/dist/declarative-validation/compiler/compatibility.d.ts +4 -0
- package/dist/declarative-validation/compiler/compatibility.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/compatibility.js +29 -0
- package/dist/declarative-validation/compiler/compatibility.js.map +1 -0
- package/dist/declarative-validation/compiler/diagnostics.d.ts +3 -0
- package/dist/declarative-validation/compiler/diagnostics.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/diagnostics.js +9 -0
- package/dist/declarative-validation/compiler/diagnostics.js.map +1 -0
- package/dist/declarative-validation/compiler/group-plans.d.ts +6 -0
- package/dist/declarative-validation/compiler/group-plans.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/group-plans.js +67 -0
- package/dist/declarative-validation/compiler/group-plans.js.map +1 -0
- package/dist/declarative-validation/compiler/index.d.ts +5 -0
- package/dist/declarative-validation/compiler/index.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/index.js +199 -0
- package/dist/declarative-validation/compiler/index.js.map +1 -0
- package/dist/declarative-validation/compiler/plan.d.ts +126 -0
- package/dist/declarative-validation/compiler/plan.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/plan.js +2 -0
- package/dist/declarative-validation/compiler/plan.js.map +1 -0
- package/dist/declarative-validation/compiler/rule-fields.d.ts +6 -0
- package/dist/declarative-validation/compiler/rule-fields.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/rule-fields.js +40 -0
- package/dist/declarative-validation/compiler/rule-fields.js.map +1 -0
- package/dist/declarative-validation/diagnostics/index.d.ts +7 -0
- package/dist/declarative-validation/diagnostics/index.d.ts.map +1 -0
- package/dist/declarative-validation/diagnostics/index.js +2 -0
- package/dist/declarative-validation/diagnostics/index.js.map +1 -0
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.d.ts +10 -0
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.d.ts.map +1 -0
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js +51 -0
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js.map +1 -0
- package/dist/declarative-validation/evidence/index.d.ts +14 -0
- package/dist/declarative-validation/evidence/index.d.ts.map +1 -0
- package/dist/declarative-validation/evidence/index.js +38 -0
- package/dist/declarative-validation/evidence/index.js.map +1 -0
- package/dist/declarative-validation/profile/applicability-schema.d.ts +4 -0
- package/dist/declarative-validation/profile/applicability-schema.d.ts.map +1 -0
- package/dist/declarative-validation/profile/applicability-schema.js +24 -0
- package/dist/declarative-validation/profile/applicability-schema.js.map +1 -0
- package/dist/declarative-validation/profile/assertion-schema.d.ts +5 -0
- package/dist/declarative-validation/profile/assertion-schema.d.ts.map +1 -0
- package/dist/declarative-validation/profile/assertion-schema.js +420 -0
- package/dist/declarative-validation/profile/assertion-schema.js.map +1 -0
- package/dist/declarative-validation/profile/data-closure.d.ts +6 -0
- package/dist/declarative-validation/profile/data-closure.d.ts.map +1 -0
- package/dist/declarative-validation/profile/data-closure.js +167 -0
- package/dist/declarative-validation/profile/data-closure.js.map +1 -0
- package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts +7 -0
- package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts.map +1 -0
- package/dist/declarative-validation/profile/direct-profile-diagnostics.js +81 -0
- package/dist/declarative-validation/profile/direct-profile-diagnostics.js.map +1 -0
- package/dist/declarative-validation/profile/group-schema.d.ts +5 -0
- package/dist/declarative-validation/profile/group-schema.d.ts.map +1 -0
- package/dist/declarative-validation/profile/group-schema.js +55 -0
- package/dist/declarative-validation/profile/group-schema.js.map +1 -0
- package/dist/declarative-validation/profile/ids-assertion-contract.d.ts +12 -0
- package/dist/declarative-validation/profile/ids-assertion-contract.d.ts.map +1 -0
- package/dist/declarative-validation/profile/ids-assertion-contract.js +32 -0
- package/dist/declarative-validation/profile/ids-assertion-contract.js.map +1 -0
- package/dist/declarative-validation/profile/index.d.ts +153 -0
- package/dist/declarative-validation/profile/index.d.ts.map +1 -0
- package/dist/declarative-validation/profile/index.js +2 -0
- package/dist/declarative-validation/profile/index.js.map +1 -0
- package/dist/declarative-validation/profile/materialization.d.ts +9 -0
- package/dist/declarative-validation/profile/materialization.d.ts.map +1 -0
- package/dist/declarative-validation/profile/materialization.js +112 -0
- package/dist/declarative-validation/profile/materialization.js.map +1 -0
- package/dist/declarative-validation/profile/parse.d.ts +3 -0
- package/dist/declarative-validation/profile/parse.d.ts.map +1 -0
- package/dist/declarative-validation/profile/parse.js +89 -0
- package/dist/declarative-validation/profile/parse.js.map +1 -0
- package/dist/declarative-validation/profile/schema-values.d.ts +14 -0
- package/dist/declarative-validation/profile/schema-values.d.ts.map +1 -0
- package/dist/declarative-validation/profile/schema-values.js +81 -0
- package/dist/declarative-validation/profile/schema-values.js.map +1 -0
- package/dist/declarative-validation/profile/schema.d.ts +9 -0
- package/dist/declarative-validation/profile/schema.d.ts.map +1 -0
- package/dist/declarative-validation/profile/schema.js +159 -0
- package/dist/declarative-validation/profile/schema.js.map +1 -0
- package/dist/declarative-validation/profile/selector-schema.d.ts +4 -0
- package/dist/declarative-validation/profile/selector-schema.d.ts.map +1 -0
- package/dist/declarative-validation/profile/selector-schema.js +145 -0
- package/dist/declarative-validation/profile/selector-schema.js.map +1 -0
- package/dist/declarative-validation/profile/syntax-version.d.ts +7 -0
- package/dist/declarative-validation/profile/syntax-version.d.ts.map +1 -0
- package/dist/declarative-validation/profile/syntax-version.js +11 -0
- package/dist/declarative-validation/profile/syntax-version.js.map +1 -0
- package/dist/declarative-validation/results/clone-rule-result.d.ts +6 -0
- package/dist/declarative-validation/results/clone-rule-result.d.ts.map +1 -0
- package/dist/declarative-validation/results/clone-rule-result.js +125 -0
- package/dist/declarative-validation/results/clone-rule-result.js.map +1 -0
- package/dist/declarative-validation/results/create-result.d.ts +15 -0
- package/dist/declarative-validation/results/create-result.d.ts.map +1 -0
- package/dist/declarative-validation/results/create-result.js +58 -0
- package/dist/declarative-validation/results/create-result.js.map +1 -0
- package/dist/declarative-validation/results/index.d.ts +4 -0
- package/dist/declarative-validation/results/index.d.ts.map +1 -0
- package/dist/declarative-validation/results/index.js +3 -0
- package/dist/declarative-validation/results/index.js.map +1 -0
- package/dist/declarative-validation/results/skipped-rule-result.d.ts +10 -0
- package/dist/declarative-validation/results/skipped-rule-result.d.ts.map +1 -0
- package/dist/declarative-validation/results/skipped-rule-result.js +18 -0
- package/dist/declarative-validation/results/skipped-rule-result.js.map +1 -0
- package/dist/declarative-validation/results/types.d.ts +77 -0
- package/dist/declarative-validation/results/types.d.ts.map +1 -0
- package/dist/declarative-validation/results/types.js +2 -0
- package/dist/declarative-validation/results/types.js.map +1 -0
- package/dist/declarative-validation/selectors/index.d.ts +57 -0
- package/dist/declarative-validation/selectors/index.d.ts.map +1 -0
- package/dist/declarative-validation/selectors/index.js +149 -0
- package/dist/declarative-validation/selectors/index.js.map +1 -0
- package/dist/declarative-validation/selectors/source.d.ts +8 -0
- package/dist/declarative-validation/selectors/source.d.ts.map +1 -0
- package/dist/declarative-validation/selectors/source.js +57 -0
- package/dist/declarative-validation/selectors/source.js.map +1 -0
- package/dist/declarative-validation/selectors/table-targets.d.ts +36 -0
- package/dist/declarative-validation/selectors/table-targets.d.ts.map +1 -0
- package/dist/declarative-validation/selectors/table-targets.js +149 -0
- package/dist/declarative-validation/selectors/table-targets.js.map +1 -0
- package/dist/declarative-validation/selectors/table-text.d.ts +4 -0
- package/dist/declarative-validation/selectors/table-text.d.ts.map +1 -0
- package/dist/declarative-validation/selectors/table-text.js +16 -0
- package/dist/declarative-validation/selectors/table-text.js.map +1 -0
- package/dist/{ir → internal}/document-node-walk.d.ts +5 -0
- package/dist/internal/document-node-walk.d.ts.map +1 -0
- package/dist/internal/document-node-walk.js +36 -0
- package/dist/internal/document-node-walk.js.map +1 -0
- package/dist/internal/stable-json.d.ts +3 -0
- package/dist/internal/stable-json.d.ts.map +1 -0
- package/dist/internal/stable-json.js +17 -0
- package/dist/internal/stable-json.js.map +1 -0
- package/dist/ir/document-derived-views.d.ts.map +1 -1
- package/dist/ir/document-derived-views.js +2 -0
- package/dist/ir/document-derived-views.js.map +1 -1
- package/dist/ir/document-link-reference-views.d.ts +3 -0
- package/dist/ir/document-link-reference-views.d.ts.map +1 -0
- package/dist/ir/document-link-reference-views.js +150 -0
- package/dist/ir/document-link-reference-views.js.map +1 -0
- package/dist/ir/document-link-views.d.ts.map +1 -1
- package/dist/ir/document-link-views.js +7 -8
- package/dist/ir/document-link-views.js.map +1 -1
- package/dist/ir/document-list-views.d.ts.map +1 -1
- package/dist/ir/document-list-views.js +14 -13
- package/dist/ir/document-list-views.js.map +1 -1
- package/dist/ir/document-sections.d.ts.map +1 -1
- package/dist/ir/document-sections.js +2 -4
- package/dist/ir/document-sections.js.map +1 -1
- package/dist/ir/document-table-views.js +1 -1
- package/dist/ir/document-table-views.js.map +1 -1
- package/dist/ir/document-text-spans.js +1 -1
- package/dist/ir/document-text-spans.js.map +1 -1
- package/dist/ir/document.d.ts +2 -3
- package/dist/ir/document.d.ts.map +1 -1
- package/dist/ir/document.js +1 -1
- package/dist/ir/document.js.map +1 -1
- package/dist/ir/index.d.ts +1 -0
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/normalization-input.d.ts +12 -0
- package/dist/ir/normalization-input.d.ts.map +1 -0
- package/dist/ir/normalization-input.js +2 -0
- package/dist/ir/normalization-input.js.map +1 -0
- package/dist/rules/code-fence-languages.d.ts.map +1 -1
- package/dist/rules/code-fence-languages.js +4 -6
- package/dist/rules/code-fence-languages.js.map +1 -1
- package/dist/rules/document-query.d.ts +0 -2
- package/dist/rules/document-query.d.ts.map +1 -1
- package/dist/rules/document-query.js +1 -17
- package/dist/rules/document-query.js.map +1 -1
- package/dist/rules/index.d.ts +2 -6
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +3 -37
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/links-allowed-schemes.d.ts.map +1 -1
- package/dist/rules/links-allowed-schemes.js +3 -2
- package/dist/rules/links-allowed-schemes.js.map +1 -1
- package/dist/rules/registry.d.ts +12 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +61 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist-bundled/markdown-engine-cli.mjs +26826 -0
- package/docs/contracts/api.md +665 -0
- package/docs/contracts/declarative-validation.md +842 -0
- package/docs/contracts/frontmatter.md +122 -0
- package/fixtures/declarative-validation/examples/operational-spec/fail.md +32 -0
- package/fixtures/declarative-validation/examples/operational-spec/pass.md +34 -0
- package/fixtures/declarative-validation/examples/operational-spec/profile.yaml +131 -0
- package/fixtures/declarative-validation/examples/release-checklist/fail.md +22 -0
- package/fixtures/declarative-validation/examples/release-checklist/pass.md +22 -0
- package/fixtures/declarative-validation/examples/release-checklist/profile.yaml +96 -0
- package/fixtures/declarative-validation/examples/requirements-traceability/fail.md +27 -0
- package/fixtures/declarative-validation/examples/requirements-traceability/pass.md +27 -0
- package/fixtures/declarative-validation/examples/requirements-traceability/profile.yaml +119 -0
- package/package.json +26 -6
- package/skills/profile-backed-markdown/SKILL.md +54 -0
- package/skills/profile-backed-markdown/assets/profiles/operational-spec.yaml +98 -0
- package/skills/profile-backed-markdown/references/repair-brief.md +14 -0
- package/skills/profile-backed-markdown/scripts/validate-profile-backed-markdown.mjs +590 -0
- package/dist/ir/document-node-walk.d.ts.map +0 -1
- package/dist/ir/document-node-walk.js +0 -16
- package/dist/ir/document-node-walk.js.map +0 -1
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
# Declarative Validation Contract
|
|
2
|
+
|
|
3
|
+
Status: package 3.0.0, v1 profile syntax with v2 Conditional V2, document contract 1.0.0
|
|
4
|
+
Last updated: 2026-06-05
|
|
5
|
+
Current v2 surface: flat-rule result/evidence shell, ID count-bound schema and
|
|
6
|
+
runtime evaluator contract, plus `tableColumnCoverage` schema, compiled-plan,
|
|
7
|
+
and runtime evaluator contract, grouped rule runtime contract, and rule-level
|
|
8
|
+
`when` schema, matcher, public skipped-rule result, skipped counts, and evidence
|
|
9
|
+
cloning contract.
|
|
10
|
+
|
|
11
|
+
This document defines the public declarative validation contract for
|
|
12
|
+
`@jasonbelmonti/markdown-engine`. The stable surface is the package-root API,
|
|
13
|
+
the v1 profile syntax, the admitted v2 profile syntax and runtime subset, the
|
|
14
|
+
CLI validation command, diagnostic codes, serialized result shapes, and evidence
|
|
15
|
+
fields. Internal parser output, compiled rule-plan records, selector target
|
|
16
|
+
records, and evaluator implementation modules are not public contracts.
|
|
17
|
+
|
|
18
|
+
Package 3.0 does not introduce `documentVersion: "3.0.0"` or CLI JSON
|
|
19
|
+
discrimination.
|
|
20
|
+
Declarative validation continues to use the existing `documentVersion: "1.0.0"`
|
|
21
|
+
rich IR document contract, while the profile admission path recognizes
|
|
22
|
+
`markdown-engine.validation@v2` for the same flat rule shape with `id`, optional
|
|
23
|
+
`severity`, `select`, and `assert`; non-recursive `anyOf` and `allOf`; and
|
|
24
|
+
optional rule-level `when`. The admitted v2 path exposes the result and evidence
|
|
25
|
+
shell needed to distinguish assertion, grouped, and skipped evaluation output
|
|
26
|
+
from v1 output, plus the ID count-bound schema, compiled-plan, and runtime
|
|
27
|
+
evaluator contract; the `tableColumnCoverage` schema, compiled-plan, and
|
|
28
|
+
runtime evaluator contract; and the `when` schema plus private compiled-plan and
|
|
29
|
+
matcher contract. Matched applicability continues into normal rule evaluation.
|
|
30
|
+
Non-matching applicability returns a public skipped rule result with
|
|
31
|
+
`status: "skipped"`, `passed: true`, `evaluation.kind: "skipped"`,
|
|
32
|
+
`reason: "whenNotMatched"`, `skippedRuleCount`, no top-level diagnostics, and a
|
|
33
|
+
nested `when` applicability result.
|
|
34
|
+
|
|
35
|
+
## 1.0 Contract
|
|
36
|
+
|
|
37
|
+
Declarative validation is a local, deterministic validation layer over a
|
|
38
|
+
normalized `EngineDocument`. It accepts inert YAML-compatible profile data,
|
|
39
|
+
compiles supported selectors and assertions into engine-owned rule plans, and
|
|
40
|
+
returns stable diagnostics, rule results, profile metadata, and optional
|
|
41
|
+
evidence.
|
|
42
|
+
|
|
43
|
+
The public API functions are:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
parseValidationProfile(
|
|
47
|
+
input: string | JsonSafeValue,
|
|
48
|
+
options?: DeclarativeProfileParseOptions,
|
|
49
|
+
): DeclarativeProfileParseResult
|
|
50
|
+
|
|
51
|
+
validateWithProfile(
|
|
52
|
+
document: EngineDocument,
|
|
53
|
+
profile: ValidationProfile,
|
|
54
|
+
options?: DeclarativeValidationOptions,
|
|
55
|
+
): DeclarativeValidationResult
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Compiled declarative validation plans are internal. They are not exported from
|
|
59
|
+
the package root, are not serialized in API or CLI results, and carry no semver
|
|
60
|
+
stability guarantee.
|
|
61
|
+
|
|
62
|
+
## Syntax Versioning
|
|
63
|
+
|
|
64
|
+
The v1 syntax is selected with:
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
syntaxVersion: markdown-engine.validation@v1
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`syntaxVersion` is required. Missing or unsupported values emit
|
|
71
|
+
`profile.config.unsupportedSyntaxVersion`.
|
|
72
|
+
|
|
73
|
+
The v2 syntax is admitted as an additive profile syntax:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
syntaxVersion: markdown-engine.validation@v2
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This release recognizes v2 as a distinct syntax version at profile admission,
|
|
80
|
+
admits ID count bounds at the schema, compiled-plan, and runtime evaluator
|
|
81
|
+
layers, admits `tableColumnCoverage` at the schema, internal compiled-plan, and
|
|
82
|
+
runtime evaluator layers, admits non-recursive grouped rules at the schema,
|
|
83
|
+
compiled-plan, and runtime evaluator layers, and admits optional rule-level
|
|
84
|
+
`when` at the schema, internal compiled-plan, and matcher layers. Matching
|
|
85
|
+
`when` rules continue through normal flat or grouped evaluation and do not add a
|
|
86
|
+
public `when` field to the evaluated rule result. Non-matching `when` rules are
|
|
87
|
+
not evaluated; they return the public skipped-rule result shape, increment
|
|
88
|
+
`skippedRuleCount`, and leave `evaluatedRuleCount` unchanged.
|
|
89
|
+
|
|
90
|
+
The admitted v1/v2 flat vocabulary is closed. Unknown profile keys, rule keys,
|
|
91
|
+
selector keys, known assertion keys, and nested assertion keys emit
|
|
92
|
+
`profile.config.unsupportedKey` unless the contract assigns a more specific
|
|
93
|
+
compile diagnostic for an unsupported selector target or unsupported assertion
|
|
94
|
+
member.
|
|
95
|
+
|
|
96
|
+
Regex-like keys are explicitly unsupported in v1:
|
|
97
|
+
|
|
98
|
+
- `matches`
|
|
99
|
+
- `pattern`
|
|
100
|
+
- `regex`
|
|
101
|
+
- `regexp`
|
|
102
|
+
|
|
103
|
+
Executable-like keys are also unsupported:
|
|
104
|
+
|
|
105
|
+
- `callback`
|
|
106
|
+
- `eval`
|
|
107
|
+
- `execute`
|
|
108
|
+
- `expression`
|
|
109
|
+
- `function`
|
|
110
|
+
- `import`
|
|
111
|
+
- `imports`
|
|
112
|
+
- `plugin`
|
|
113
|
+
- `script`
|
|
114
|
+
|
|
115
|
+
These keys are treated as data-only unsupported config. They are not executed,
|
|
116
|
+
imported, evaluated, or compiled.
|
|
117
|
+
|
|
118
|
+
## Document-Version Behavior
|
|
119
|
+
|
|
120
|
+
Profiles may include:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
documentVersion: 1.0.0
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Supported profile `documentVersion` values are `"0.0.0"` and `"1.0.0"`.
|
|
127
|
+
Omission is allowed. `parseValidationProfile` preserves omission and does not
|
|
128
|
+
inject a default into the parsed profile.
|
|
129
|
+
|
|
130
|
+
Direct object inputs to `parseValidationProfile` are closed as JSON-safe data
|
|
131
|
+
before schema traversal. Accessors, proxies, cyclic values, sparse arrays,
|
|
132
|
+
functions, non-finite numbers, explicit `undefined`, and `__proto__` data
|
|
133
|
+
properties are rejected with inert diagnostics rather than being executed or
|
|
134
|
+
compiled.
|
|
135
|
+
|
|
136
|
+
`validateWithProfile` resolves an omitted profile `documentVersion` to the
|
|
137
|
+
supplied `EngineDocument.version`. The returned
|
|
138
|
+
`DeclarativeValidationResult.profile.documentVersion` records that resolved
|
|
139
|
+
version.
|
|
140
|
+
|
|
141
|
+
If the resolved profile `documentVersion` differs from `document.version`,
|
|
142
|
+
validation emits `profile.config.documentVersionMismatch`, returns no rule
|
|
143
|
+
results, and does not evaluate rules.
|
|
144
|
+
|
|
145
|
+
## Profile Shape
|
|
146
|
+
|
|
147
|
+
The top-level profile shape is:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
type ValidationProfileSyntaxVersion =
|
|
151
|
+
| "markdown-engine.validation@v1"
|
|
152
|
+
| "markdown-engine.validation@v2";
|
|
153
|
+
|
|
154
|
+
interface ValidationProfile {
|
|
155
|
+
syntaxVersion: ValidationProfileSyntaxVersion;
|
|
156
|
+
documentVersion?: EngineDocumentVersion;
|
|
157
|
+
rules: readonly DeclarativeValidationRule[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
type DeclarativeValidationRule =
|
|
161
|
+
| DeclarativeValidationFlatRule
|
|
162
|
+
| DeclarativeValidationGroupRule;
|
|
163
|
+
|
|
164
|
+
interface DeclarativeValidationRuleFields {
|
|
165
|
+
id: string;
|
|
166
|
+
severity?: "error" | "warning" | "info";
|
|
167
|
+
when?: DeclarativeValidationApplicability;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
interface DeclarativeValidationFlatRule extends DeclarativeValidationRuleFields {
|
|
171
|
+
select: DeclarativeSelector;
|
|
172
|
+
assert: DeclarativeAssertion;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface DeclarativeValidationApplicability {
|
|
176
|
+
select: DeclarativeSelector;
|
|
177
|
+
assert: DeclarativeAssertion;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
type DeclarativeValidationGroupRule =
|
|
181
|
+
| DeclarativeValidationAnyOfRule
|
|
182
|
+
| DeclarativeValidationAllOfRule;
|
|
183
|
+
|
|
184
|
+
interface DeclarativeValidationAnyOfRule
|
|
185
|
+
extends DeclarativeValidationRuleFields {
|
|
186
|
+
anyOf: readonly DeclarativeValidationBranch[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
interface DeclarativeValidationAllOfRule
|
|
190
|
+
extends DeclarativeValidationRuleFields {
|
|
191
|
+
allOf: readonly DeclarativeValidationBranch[];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
interface DeclarativeValidationBranch {
|
|
195
|
+
label?: string;
|
|
196
|
+
select: DeclarativeSelector;
|
|
197
|
+
assert: DeclarativeAssertion;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Rule IDs must be non-empty strings and unique within one profile. Duplicate rule
|
|
202
|
+
IDs emit `profile.config.invalidShape` because diagnostics, rule results, and
|
|
203
|
+
evidence identify output by `ruleId`.
|
|
204
|
+
|
|
205
|
+
Rule `severity` defaults to `error` when omitted. Unsupported severity values
|
|
206
|
+
emit `profile.config.invalidShape`.
|
|
207
|
+
|
|
208
|
+
Rule-level `when` is allowed only on v2 rules. Branch-level `when` remains
|
|
209
|
+
unsupported. V1 profiles preserve the original flat rule authoring contract;
|
|
210
|
+
grouped `anyOf` / `allOf`, ID count bounds, `tableColumnCoverage`, and
|
|
211
|
+
rule-level `when` are v2 additions.
|
|
212
|
+
|
|
213
|
+
Profile values must be JSON-safe data properties after YAML materialization.
|
|
214
|
+
Functions, accessors, proxies, cyclic structures, sparse arrays, `undefined`
|
|
215
|
+
payloads in required positions, non-finite numbers, and `__proto__` properties
|
|
216
|
+
are rejected as invalid shape.
|
|
217
|
+
|
|
218
|
+
## Selector Contract
|
|
219
|
+
|
|
220
|
+
Selectors resolve against public `EngineDocument` structure and query helper
|
|
221
|
+
semantics. Supported selector targets are:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
type DeclarativeSelector =
|
|
225
|
+
| { target: "document" }
|
|
226
|
+
| { target: "section"; title?: string; depth?: number }
|
|
227
|
+
| { target: "heading"; text?: string; depth?: number }
|
|
228
|
+
| { target: "table"; section?: string; header?: readonly string[] }
|
|
229
|
+
| {
|
|
230
|
+
target: "tableRow";
|
|
231
|
+
section?: string;
|
|
232
|
+
tableHeader?: readonly string[];
|
|
233
|
+
where?: { column: string; equals?: string; includes?: string };
|
|
234
|
+
}
|
|
235
|
+
| {
|
|
236
|
+
target: "tableCell";
|
|
237
|
+
section?: string;
|
|
238
|
+
tableHeader?: readonly string[];
|
|
239
|
+
column: string;
|
|
240
|
+
rowWhere?: { column: string; equals?: string; includes?: string };
|
|
241
|
+
}
|
|
242
|
+
| { target: "textSpan"; section?: string; nodeType?: string; textIncludes?: string }
|
|
243
|
+
| { target: "link"; section?: string; text?: string; url?: string }
|
|
244
|
+
| { target: "list"; section?: string; ordered?: boolean; depth?: number };
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Unsupported selector targets emit `profile.compile.unsupportedSelector`.
|
|
248
|
+
|
|
249
|
+
String matching is deterministic literal matching. Heading, section, header,
|
|
250
|
+
column, `equals`, and frontmatter field names use exact string equality.
|
|
251
|
+
`includes`, `contains`, `excludes`, and `textOccurrenceCount.text` use literal
|
|
252
|
+
substring matching. No profile-supplied regular expression is compiled.
|
|
253
|
+
|
|
254
|
+
Table `header` and `tableHeader` arrays match normalized table header cells as
|
|
255
|
+
an exact-title ordered subsequence. Unrelated columns may appear before, between,
|
|
256
|
+
or after listed values. Duplicate supplied values require separate matching
|
|
257
|
+
header cells.
|
|
258
|
+
|
|
259
|
+
`tableRow.where` and `tableCell.rowWhere` require a non-empty `column` and at
|
|
260
|
+
least one of `equals` or `includes`. When both are present, both tests must
|
|
261
|
+
pass. A missing predicate column makes the row fail the predicate; it does not
|
|
262
|
+
emit a diagnostic by itself.
|
|
263
|
+
|
|
264
|
+
## Assertion Contract
|
|
265
|
+
|
|
266
|
+
Supported assertion members are:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
interface DeclarativeAssertion {
|
|
270
|
+
exists?: true;
|
|
271
|
+
sectionsRequired?: {
|
|
272
|
+
headings: readonly string[];
|
|
273
|
+
order?: "none" | "strict";
|
|
274
|
+
};
|
|
275
|
+
tableColumnsRequired?: {
|
|
276
|
+
columns: readonly string[];
|
|
277
|
+
};
|
|
278
|
+
ids?: {
|
|
279
|
+
prefix?: string;
|
|
280
|
+
unique?: boolean;
|
|
281
|
+
caseSensitive?: boolean;
|
|
282
|
+
minCount?: number;
|
|
283
|
+
maxCount?: number;
|
|
284
|
+
};
|
|
285
|
+
references?: {
|
|
286
|
+
idsFrom: { section?: string; column?: string; prefix?: string };
|
|
287
|
+
mustAppearIn: readonly string[];
|
|
288
|
+
};
|
|
289
|
+
tableColumnCoverage?: {
|
|
290
|
+
source: {
|
|
291
|
+
section: string;
|
|
292
|
+
column: string;
|
|
293
|
+
prefix?: string;
|
|
294
|
+
caseSensitive?: boolean;
|
|
295
|
+
};
|
|
296
|
+
target: {
|
|
297
|
+
section: string;
|
|
298
|
+
tableHeader?: readonly string[];
|
|
299
|
+
column: string;
|
|
300
|
+
};
|
|
301
|
+
require: "everySourceId";
|
|
302
|
+
};
|
|
303
|
+
text?: {
|
|
304
|
+
contains?: string;
|
|
305
|
+
excludes?: readonly string[];
|
|
306
|
+
};
|
|
307
|
+
textOccurrenceCount?: {
|
|
308
|
+
text: string;
|
|
309
|
+
count: number;
|
|
310
|
+
};
|
|
311
|
+
textLength?: {
|
|
312
|
+
min?: number;
|
|
313
|
+
max?: number;
|
|
314
|
+
};
|
|
315
|
+
frontmatterRequired?: {
|
|
316
|
+
fields: readonly string[];
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Unsupported first-level assertion members parsed from YAML or JSON-safe profile
|
|
322
|
+
input emit `profile.compile.unsupportedAssertion`, except regex-like and
|
|
323
|
+
executable-like keys, which retain `profile.config.unsupportedKey` precedence.
|
|
324
|
+
Direct typed profile objects passed to validation are hardened as closed
|
|
325
|
+
JSON-safe data before execution; unsupported assertion properties on that path
|
|
326
|
+
emit `profile.config.unsupportedKey`.
|
|
327
|
+
|
|
328
|
+
Selector/assertion compatibility is part of the public contract:
|
|
329
|
+
|
|
330
|
+
| Assertion | Compatible selector targets |
|
|
331
|
+
| --- | --- |
|
|
332
|
+
| `exists` | all supported selector targets |
|
|
333
|
+
| `sectionsRequired` | `document` |
|
|
334
|
+
| `tableColumnsRequired` | `table` |
|
|
335
|
+
| `ids` | all supported selector targets |
|
|
336
|
+
| `references` | `document` |
|
|
337
|
+
| `tableColumnCoverage` | `document` |
|
|
338
|
+
| `text` | all supported selector targets |
|
|
339
|
+
| `textOccurrenceCount` | all supported selector targets |
|
|
340
|
+
| `textLength` | all supported selector targets |
|
|
341
|
+
| `frontmatterRequired` | `document` |
|
|
342
|
+
|
|
343
|
+
Incompatible supported selector/assertion pairs emit
|
|
344
|
+
`profile.compile.incompatibleSelectorAssertion`.
|
|
345
|
+
|
|
346
|
+
`exists` must be `true`. It passes when the selector resolves at least one
|
|
347
|
+
target and fails with `profile.validation.emptySelection` when the selector
|
|
348
|
+
resolves zero targets.
|
|
349
|
+
|
|
350
|
+
`sectionsRequired.order` defaults to `none`. `strict` checks that configured
|
|
351
|
+
headings appear as an ordered subsequence in the normalized section tree
|
|
352
|
+
flattened in source order.
|
|
353
|
+
|
|
354
|
+
For v1 profiles, `ids.unique` must be `true`. For v2 profiles, `ids.unique`
|
|
355
|
+
must be `true` when provided and may be omitted when `ids.minCount` or
|
|
356
|
+
`ids.maxCount` provides the predicate. `prefix` and `caseSensitive` are modifiers,
|
|
357
|
+
not standalone predicates. `caseSensitive` defaults to `true`. ID tokens use the
|
|
358
|
+
documented token grammar `[A-Za-z][A-Za-z0-9]*-[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*`.
|
|
359
|
+
For v2 profiles, `ids.minCount` and `ids.maxCount` are admitted as non-negative
|
|
360
|
+
integer schema and compiled-plan fields. When both are present, `minCount` must
|
|
361
|
+
be less than or equal to `maxCount`. Runtime count evaluation uses unique
|
|
362
|
+
comparison values after prefix filtering and duplicate occurrence de-duplication.
|
|
363
|
+
Failed lower and upper bounds emit `profile.validation.idCountTooLow` and
|
|
364
|
+
`profile.validation.idCountTooHigh`.
|
|
365
|
+
|
|
366
|
+
For v2 profiles, `tableColumnCoverage` is admitted as a flat-rule schema and
|
|
367
|
+
internal compiled-plan assertion. It is compatible only with a `document`
|
|
368
|
+
selector because the assertion owns its source and target table-column inputs.
|
|
369
|
+
`source.section`, `source.column`, `target.section`, and `target.column` are
|
|
370
|
+
required non-empty strings. `source.prefix` is optional and must be non-empty
|
|
371
|
+
when provided. `source.caseSensitive` is optional and defaults to `true` in the
|
|
372
|
+
compiled plan. `target.tableHeader` is an optional non-empty string array.
|
|
373
|
+
`require` must be exactly `"everySourceId"`. Runtime evaluation extracts unique
|
|
374
|
+
source IDs from `source.section` and `source.column`, applies `source.prefix`
|
|
375
|
+
and `source.caseSensitive`, and requires every source ID comparison value to
|
|
376
|
+
appear in the configured target table column. IDs appearing elsewhere in the
|
|
377
|
+
target section do not satisfy coverage. Missing target sections, missing target
|
|
378
|
+
columns, and missing target-column IDs emit deterministic validation diagnostics
|
|
379
|
+
source-grounded to the source ID when source evidence is available.
|
|
380
|
+
|
|
381
|
+
`text` must include `contains` or a non-empty `excludes` array.
|
|
382
|
+
`textOccurrenceCount.count` is a finite number and counts non-overlapping
|
|
383
|
+
literal occurrences per selected target.
|
|
384
|
+
`textLength` must include `min`, `max`, or both. Bounds are non-negative
|
|
385
|
+
integers, `min` must be less than or equal to `max` when both are present, and
|
|
386
|
+
evaluation uses JavaScript string `.length` for each selected target's
|
|
387
|
+
normalized text.
|
|
388
|
+
|
|
389
|
+
Empty selector results produce `profile.validation.emptySelection` for exists,
|
|
390
|
+
table, ID, reference, text, occurrence, and text-length assertions.
|
|
391
|
+
Document-scoped required-section and required-frontmatter assertions evaluate
|
|
392
|
+
against the document.
|
|
393
|
+
|
|
394
|
+
## Diagnostics
|
|
395
|
+
|
|
396
|
+
All declarative validation diagnostics use the public `MarkdownDiagnostic`
|
|
397
|
+
shape. Config diagnostics are error severity except
|
|
398
|
+
`profile.config.yamlWarning`, which is warning severity. Compile diagnostics are
|
|
399
|
+
error severity. Validation diagnostics use the rule severity. Source ranges are
|
|
400
|
+
included when a selected target has source evidence; locations are omitted
|
|
401
|
+
rather than fabricated when unavailable.
|
|
402
|
+
|
|
403
|
+
Rule-level `when` uses the existing validation diagnostic codes. When
|
|
404
|
+
applicability does not match, those diagnostics are cloned into
|
|
405
|
+
`ruleResults[].when.diagnostics`; they are not promoted into top-level
|
|
406
|
+
`diagnostics`, so a skipped rule with a nested error-severity applicability
|
|
407
|
+
diagnostic can still leave the aggregate `valid` value `true`.
|
|
408
|
+
|
|
409
|
+
| Code | Severity source | Emitted when |
|
|
410
|
+
| --- | --- | --- |
|
|
411
|
+
| `profile.config.invalidYaml` | `error` | YAML text cannot be parsed or materialized as JSON-safe profile data. |
|
|
412
|
+
| `profile.config.yamlWarning` | `warning` | YAML materialization produces a non-fatal parser warning. |
|
|
413
|
+
| `profile.config.unsupportedSyntaxVersion` | `error` | `syntaxVersion` is missing or is not `markdown-engine.validation@v1` or `markdown-engine.validation@v2`. |
|
|
414
|
+
| `profile.config.invalidShape` | `error` | Required fields are missing, fields have wrong types, arrays or strings are empty, rule IDs duplicate, scalar values are invalid, table predicates are ineffective, or assertion payloads contain no effective predicate. |
|
|
415
|
+
| `profile.config.documentVersionMismatch` | `error` | Resolved profile `documentVersion` differs from the supplied `EngineDocument.version`. |
|
|
416
|
+
| `profile.config.unsupportedKey` | `error` | A closed profile, rule, selector, known assertion object, nested object, regex-like key, executable-like key, or direct typed profile object contains unsupported syntax. |
|
|
417
|
+
| `profile.compile.unsupportedSelector` | `error` | `select.target` is not a supported v1 target. |
|
|
418
|
+
| `profile.compile.unsupportedAssertion` | `error` | Parsed YAML or JSON-safe `assert` input contains an unsupported first-level assertion member that does not have unsupported-key precedence. |
|
|
419
|
+
| `profile.compile.incompatibleSelectorAssertion` | `error` | A supported selector target is paired with an incompatible supported assertion. |
|
|
420
|
+
| `profile.validation.emptySelection` | Rule severity | A rule cannot evaluate because its selector matches no applicable target. |
|
|
421
|
+
| `profile.validation.assertionFailed` | Rule severity | A supported assertion evaluates and fails without a more specific diagnostic code, including missing table columns, exact occurrence-count mismatches, and text-length bound failures. |
|
|
422
|
+
| `profile.validation.duplicateId` | Rule severity | An `ids.unique` assertion finds repeated IDs. |
|
|
423
|
+
| `profile.validation.frontmatterFieldMissing` | Rule severity | A required frontmatter field is absent. |
|
|
424
|
+
| `profile.validation.idCountTooHigh` | Rule severity | Unique ID count after filtering is higher than `ids.maxCount`. |
|
|
425
|
+
| `profile.validation.idCountTooLow` | Rule severity | Unique ID count after filtering is lower than `ids.minCount`. |
|
|
426
|
+
| `profile.validation.referenceMissing` | Rule severity | A source ID is absent from a required target section. |
|
|
427
|
+
| `profile.validation.sectionMissing` | Rule severity | A required section heading is absent. |
|
|
428
|
+
| `profile.validation.sectionOrder` | Rule severity | A strict required-section order cannot be satisfied. |
|
|
429
|
+
| `profile.validation.tableColumnCoverageIdMissing` | Rule severity | A source ID is absent from the configured target table column. |
|
|
430
|
+
| `profile.validation.tableColumnCoverageTargetColumnMissing` | Rule severity | The configured target table column cannot be resolved. |
|
|
431
|
+
| `profile.validation.tableColumnCoverageTargetSectionMissing` | Rule severity | The configured target section cannot be resolved. |
|
|
432
|
+
| `profile.validation.textExcluded` | Rule severity | A selected target contains forbidden literal text. |
|
|
433
|
+
| `profile.validation.textMissing` | Rule severity | A selected target lacks required literal text from a `text.contains` assertion. |
|
|
434
|
+
| `profile.validation.assertionUnsupported` | `error` | A compiled assertion or compiled assertion feature has no evaluator implementation; this is an internal safety diagnostic. |
|
|
435
|
+
|
|
436
|
+
## Result Shape
|
|
437
|
+
|
|
438
|
+
`DeclarativeValidationResult` extends the public validation result shape:
|
|
439
|
+
|
|
440
|
+
```ts
|
|
441
|
+
interface DeclarativeValidationResult extends ValidationResult {
|
|
442
|
+
valid: boolean;
|
|
443
|
+
diagnostics: readonly MarkdownDiagnostic[];
|
|
444
|
+
ruleResults: readonly (
|
|
445
|
+
| ValidationRuleResult
|
|
446
|
+
| DeclarativeValidationRuleResultV2
|
|
447
|
+
)[];
|
|
448
|
+
profile: {
|
|
449
|
+
syntaxVersion: ValidationProfileSyntaxVersion;
|
|
450
|
+
documentVersion: EngineDocumentVersion;
|
|
451
|
+
ruleCount: number;
|
|
452
|
+
};
|
|
453
|
+
evidence?: DeclarativeValidationEvidence;
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
For admitted v2 profiles, result metadata records
|
|
458
|
+
`syntaxVersion: "markdown-engine.validation@v2"`, `evaluatedRuleCount`, and
|
|
459
|
+
`skippedRuleCount`. V2 rule results include the v1-compatible `ruleId`,
|
|
460
|
+
`passed`, and `diagnostics` fields plus `status`, optional skipped
|
|
461
|
+
applicability metadata, and flat, grouped, or skipped evaluation metadata:
|
|
462
|
+
|
|
463
|
+
```ts
|
|
464
|
+
interface DeclarativeValidationRuleResultV2 extends ValidationRuleResult {
|
|
465
|
+
status: "passed" | "failed" | "skipped";
|
|
466
|
+
when?: DeclarativeValidationApplicabilityResult;
|
|
467
|
+
evaluation:
|
|
468
|
+
| { kind: "assertions"; diagnostics: readonly MarkdownDiagnostic[] }
|
|
469
|
+
| {
|
|
470
|
+
kind: "anyOf";
|
|
471
|
+
selectedBranch?: DeclarativeValidationBranchReference;
|
|
472
|
+
branches: readonly DeclarativeValidationBranchResult[];
|
|
473
|
+
}
|
|
474
|
+
| {
|
|
475
|
+
kind: "allOf";
|
|
476
|
+
branches: readonly DeclarativeValidationBranchResult[];
|
|
477
|
+
}
|
|
478
|
+
| { kind: "skipped"; reason: "whenNotMatched" };
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
interface DeclarativeValidationApplicabilityResult {
|
|
482
|
+
status: "matched" | "notMatched";
|
|
483
|
+
diagnostics: readonly MarkdownDiagnostic[];
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
interface DeclarativeValidationBranchReference {
|
|
487
|
+
branchIndex: number;
|
|
488
|
+
label?: string;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
interface DeclarativeValidationBranchResult
|
|
492
|
+
extends DeclarativeValidationBranchReference {
|
|
493
|
+
status: "passed" | "failed";
|
|
494
|
+
diagnostics: readonly MarkdownDiagnostic[];
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
For configured `when`, matched applicability continues into normal flat or
|
|
499
|
+
grouped evaluation and contributes one evaluated rule. The evaluated rule result
|
|
500
|
+
does not serialize a `when` field. Non-matching applicability returns one
|
|
501
|
+
skipped rule result with `status: "skipped"`, `passed: true`, empty top-level
|
|
502
|
+
rule `diagnostics`, `when.status: "notMatched"`, nested applicability
|
|
503
|
+
diagnostics, `evaluation.kind: "skipped"`, and `reason: "whenNotMatched"`.
|
|
504
|
+
Skipped rules increment `skippedRuleCount`, do not increment
|
|
505
|
+
`evaluatedRuleCount`, and do not evaluate flat assertions or grouped branches.
|
|
506
|
+
|
|
507
|
+
`valid` is `false` when any top-level error-severity diagnostic exists in
|
|
508
|
+
`diagnostics`. Nested skipped applicability diagnostics under
|
|
509
|
+
`ruleResults[].when.diagnostics` do not by themselves make the aggregate result
|
|
510
|
+
invalid. Warning and info validation diagnostics can make a rule result fail
|
|
511
|
+
without making the aggregate result invalid.
|
|
512
|
+
|
|
513
|
+
Rule results are sorted deterministically. Each rule result includes the public
|
|
514
|
+
`ruleId`, `passed`, and cloned diagnostics. Results do not expose compiled rule
|
|
515
|
+
plans or selector internals.
|
|
516
|
+
|
|
517
|
+
## Evidence Fields
|
|
518
|
+
|
|
519
|
+
Evidence is emitted only when `DeclarativeValidationOptions.includeEvidence` is
|
|
520
|
+
`true`:
|
|
521
|
+
|
|
522
|
+
```ts
|
|
523
|
+
interface DeclarativeValidationEvidence<
|
|
524
|
+
RuleResult extends ValidationRuleResult = ValidationRuleResult,
|
|
525
|
+
> {
|
|
526
|
+
inputHash: string;
|
|
527
|
+
profileHash: string;
|
|
528
|
+
engineVersion: string;
|
|
529
|
+
runtimeVersion: string;
|
|
530
|
+
ruleResults: readonly RuleResult[];
|
|
531
|
+
diagnostics: readonly MarkdownDiagnostic[];
|
|
532
|
+
}
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
For v1 profiles, `ruleResults` contains the unchanged v1 rule-result shape. For
|
|
536
|
+
admitted v2 profiles, `ruleResults` clones the public v2 rule-result shape,
|
|
537
|
+
including `status`, flat assertion evaluation, and grouped `anyOf` / `allOf`
|
|
538
|
+
branch evaluation. Skipped v2 rule results are cloned through evidence in the
|
|
539
|
+
same `ruleResults` array, and `evidence.diagnostics` clones the top-level
|
|
540
|
+
diagnostics array. Evidence does not serialize compiled rule plans, selector
|
|
541
|
+
target records, assertion-specific ID count evidence, or assertion-specific
|
|
542
|
+
table-column coverage evidence.
|
|
543
|
+
|
|
544
|
+
`inputHash` is a lowercase hexadecimal SHA-256 digest of the stable JSON
|
|
545
|
+
serialization of the supplied normalized `EngineDocument` after omitting only
|
|
546
|
+
the top-level `document.path` field. Structural target paths remain part of the
|
|
547
|
+
canonical input.
|
|
548
|
+
|
|
549
|
+
`profileHash` is a lowercase hexadecimal SHA-256 digest of the stable JSON
|
|
550
|
+
serialization of the resolved `ValidationProfile` after applying the resolved
|
|
551
|
+
`documentVersion` and default rule severity of `error`. An omitted
|
|
552
|
+
`documentVersion` and an explicit matching `documentVersion` therefore produce
|
|
553
|
+
the same profile hash for the same document version and rules.
|
|
554
|
+
|
|
555
|
+
`engineVersion` records the package version that produced the evidence. In the
|
|
556
|
+
3.0 release line this is `"3.0.0"` even though `documentVersion` remains
|
|
557
|
+
`"1.0.0"`.
|
|
558
|
+
|
|
559
|
+
Raw Markdown bytes, raw YAML bytes, YAML comments, caller file paths, and
|
|
560
|
+
`includeEvidence` itself are not part of either evidence hash.
|
|
561
|
+
|
|
562
|
+
## CLI Behavior
|
|
563
|
+
|
|
564
|
+
The declarative validation CLI command is:
|
|
565
|
+
|
|
566
|
+
```sh
|
|
567
|
+
markdown-engine validate --file <markdown-file> --profile <profile-file> [--format json]
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
`--format json` is the default and only supported validation output format.
|
|
571
|
+
The command always normalizes Markdown with `documentVersion: "1.0.0"` and does
|
|
572
|
+
not accept `--document-version`.
|
|
573
|
+
|
|
574
|
+
The CLI reads and checks the profile before reading the Markdown file. Profile
|
|
575
|
+
parse, config, and compile failures emit profile-stage JSON and do not parse or
|
|
576
|
+
validate the Markdown file.
|
|
577
|
+
|
|
578
|
+
After profile compilation succeeds, the CLI emits a validation-result JSON
|
|
579
|
+
shape whether the document passes or fails. Validation CLI results include
|
|
580
|
+
evidence. V2 CLI results use the same validation-result arm of the CLI JSON
|
|
581
|
+
union; there is no extra CLI discriminator beyond
|
|
582
|
+
`profile.syntaxVersion: "markdown-engine.validation@v2"`.
|
|
583
|
+
|
|
584
|
+
## CLI JSON Union
|
|
585
|
+
|
|
586
|
+
The CLI JSON output is:
|
|
587
|
+
|
|
588
|
+
```ts
|
|
589
|
+
type DeclarativeValidationCliJsonResult =
|
|
590
|
+
| DeclarativeValidationResult
|
|
591
|
+
| DeclarativeValidationConfigErrorResult;
|
|
592
|
+
|
|
593
|
+
interface DeclarativeValidationConfigErrorResult {
|
|
594
|
+
valid: false;
|
|
595
|
+
stage: "profile";
|
|
596
|
+
diagnostics: readonly MarkdownDiagnostic[];
|
|
597
|
+
ruleResults: readonly [];
|
|
598
|
+
profile?: undefined;
|
|
599
|
+
evidence?: undefined;
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Profile-stage JSON is used for invalid YAML, invalid profile shape,
|
|
604
|
+
unsupported syntax version, unsupported keys, unsupported selector targets,
|
|
605
|
+
unsupported assertion members, and incompatible selector/assertion pairs. It
|
|
606
|
+
contains no `profile` and no `evidence`.
|
|
607
|
+
|
|
608
|
+
Validation-result JSON is used after profile compilation succeeds. It contains
|
|
609
|
+
`profile`, `ruleResults`, `diagnostics`, `valid`, and `evidence`. For v2
|
|
610
|
+
profiles, that same validation-result JSON can include `evaluatedRuleCount`,
|
|
611
|
+
`skippedRuleCount`, `status: "skipped"`, nested `when` diagnostics, and
|
|
612
|
+
`evaluation.kind: "skipped"`.
|
|
613
|
+
|
|
614
|
+
## Exit Codes
|
|
615
|
+
|
|
616
|
+
| Exit code | Meaning |
|
|
617
|
+
| --- | --- |
|
|
618
|
+
| `0` | Validation completed with no top-level error-severity diagnostics. |
|
|
619
|
+
| `1` | Profile/config/compile, Markdown normalization, document-version mismatch, or top-level validation diagnostics include at least one error. |
|
|
620
|
+
| `2` | CLI usage, unsupported format, unknown argument, missing argument value, repeated singleton flag, unsupported `--document-version`, or local file read error. |
|
|
621
|
+
|
|
622
|
+
## Compatibility And Migration
|
|
623
|
+
|
|
624
|
+
The v1 declarative validation syntax is a durable authoring contract for the
|
|
625
|
+
3.0 package release line. Changes to profile syntax names, selector names,
|
|
626
|
+
assertion names, result fields, diagnostic codes, CLI flags, CLI JSON shape, or
|
|
627
|
+
evidence hash inputs require explicit compatibility review.
|
|
628
|
+
|
|
629
|
+
V1 preservation is explicit: v1 authoring syntax, v1 rule result shape, v1
|
|
630
|
+
diagnostic inventory, v1 CLI JSON behavior, and v1 evidence hash inputs remain
|
|
631
|
+
unchanged by the admitted v2 syntax.
|
|
632
|
+
|
|
633
|
+
Compatibility examples:
|
|
634
|
+
|
|
635
|
+
```yaml
|
|
636
|
+
# v1 compatibility profile: remains on the v1 authoring and result contract.
|
|
637
|
+
syntaxVersion: markdown-engine.validation@v1
|
|
638
|
+
rules:
|
|
639
|
+
- id: sections.present
|
|
640
|
+
select:
|
|
641
|
+
target: document
|
|
642
|
+
assert:
|
|
643
|
+
sectionsRequired:
|
|
644
|
+
headings:
|
|
645
|
+
- Mission Brief
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
```yaml
|
|
649
|
+
# v2 opt-in profile: selects Conditional V2 behavior explicitly.
|
|
650
|
+
syntaxVersion: markdown-engine.validation@v2
|
|
651
|
+
rules:
|
|
652
|
+
- id: release.docs
|
|
653
|
+
anyOf:
|
|
654
|
+
- label: release-section
|
|
655
|
+
select:
|
|
656
|
+
target: section
|
|
657
|
+
title: Release
|
|
658
|
+
assert:
|
|
659
|
+
exists: true
|
|
660
|
+
- label: changelog-link
|
|
661
|
+
select:
|
|
662
|
+
target: link
|
|
663
|
+
text: changelog
|
|
664
|
+
assert:
|
|
665
|
+
exists: true
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
The v1 profile above continues to emit the v1 validation-result shape. The v2
|
|
669
|
+
profile above emits syntax-versioned v2 result metadata with
|
|
670
|
+
`evaluatedRuleCount` and `skippedRuleCount`; v2 rule results include `status`
|
|
671
|
+
and `evaluation`. The CLI does not add a second discriminator for v2; consumers
|
|
672
|
+
branch on
|
|
673
|
+
`profile.syntaxVersion: "markdown-engine.validation@v2"`.
|
|
674
|
+
|
|
675
|
+
Migration notes:
|
|
676
|
+
|
|
677
|
+
- Consumers using fixed `validate(document, config)` rule families can continue
|
|
678
|
+
using that API. Declarative validation is additive and does not replace fixed
|
|
679
|
+
rule validation.
|
|
680
|
+
- Consumers that need reusable structural policies should move profile-owned
|
|
681
|
+
checks into `parseValidationProfile` and `validateWithProfile`.
|
|
682
|
+
- Consumers parsing CLI validation output must handle the
|
|
683
|
+
`DeclarativeValidationCliJsonResult` union. Profile-stage failures do not
|
|
684
|
+
include `profile` or `evidence`.
|
|
685
|
+
- Consumers opting into `markdown-engine.validation@v2` must handle rule
|
|
686
|
+
`status` values of `"passed"`, `"failed"`, and `"skipped"`, plus
|
|
687
|
+
`evaluatedRuleCount`, `skippedRuleCount`, grouped branch results, and nested
|
|
688
|
+
skipped-rule `when` diagnostics. Aggregate validity is still determined from
|
|
689
|
+
top-level diagnostics.
|
|
690
|
+
- Consumers that compare evidence hashes must normalize expectations around
|
|
691
|
+
resolved `documentVersion`, default rule severity, stable key order, and
|
|
692
|
+
exclusion of only top-level `document.path` from `inputHash`.
|
|
693
|
+
- Regex-like matching, JavaScript predicates, plugins, semantic scoring, and
|
|
694
|
+
profile-specific rules belong outside this package unless a future contract
|
|
695
|
+
explicitly expands the engine boundary.
|
|
696
|
+
|
|
697
|
+
## Examples
|
|
698
|
+
|
|
699
|
+
Minimal profile:
|
|
700
|
+
|
|
701
|
+
```yaml
|
|
702
|
+
syntaxVersion: markdown-engine.validation@v1
|
|
703
|
+
rules:
|
|
704
|
+
- id: sections.present
|
|
705
|
+
select:
|
|
706
|
+
target: document
|
|
707
|
+
assert:
|
|
708
|
+
sectionsRequired:
|
|
709
|
+
headings:
|
|
710
|
+
- Mission Brief
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
Link existence profile:
|
|
714
|
+
|
|
715
|
+
```yaml
|
|
716
|
+
syntaxVersion: markdown-engine.validation@v1
|
|
717
|
+
rules:
|
|
718
|
+
- id: rollback-link.exists
|
|
719
|
+
select:
|
|
720
|
+
target: link
|
|
721
|
+
section: Escalation
|
|
722
|
+
text: rollback guide
|
|
723
|
+
url: ./rollback-guide.md
|
|
724
|
+
assert:
|
|
725
|
+
exists: true
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
Table cell text profile:
|
|
729
|
+
|
|
730
|
+
```yaml
|
|
731
|
+
syntaxVersion: markdown-engine.validation@v1
|
|
732
|
+
documentVersion: 1.0.0
|
|
733
|
+
rules:
|
|
734
|
+
- id: requirement-text
|
|
735
|
+
severity: error
|
|
736
|
+
select:
|
|
737
|
+
target: tableCell
|
|
738
|
+
section: Requirements
|
|
739
|
+
tableHeader:
|
|
740
|
+
- ID
|
|
741
|
+
- Requirement statement
|
|
742
|
+
column: Requirement statement
|
|
743
|
+
assert:
|
|
744
|
+
text:
|
|
745
|
+
contains: shall
|
|
746
|
+
excludes:
|
|
747
|
+
- and/or
|
|
748
|
+
textOccurrenceCount:
|
|
749
|
+
text: shall
|
|
750
|
+
count: 1
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
Conditional v2 grouped rule with applicability:
|
|
754
|
+
|
|
755
|
+
```yaml
|
|
756
|
+
syntaxVersion: markdown-engine.validation@v2
|
|
757
|
+
rules:
|
|
758
|
+
- id: release.when.docs-ready
|
|
759
|
+
when:
|
|
760
|
+
select:
|
|
761
|
+
target: section
|
|
762
|
+
title: Release
|
|
763
|
+
assert:
|
|
764
|
+
exists: true
|
|
765
|
+
anyOf:
|
|
766
|
+
- label: contract-link
|
|
767
|
+
select:
|
|
768
|
+
target: link
|
|
769
|
+
section: Release
|
|
770
|
+
text: contract
|
|
771
|
+
assert:
|
|
772
|
+
exists: true
|
|
773
|
+
- label: contract-heading
|
|
774
|
+
select:
|
|
775
|
+
target: heading
|
|
776
|
+
text: Contract
|
|
777
|
+
assert:
|
|
778
|
+
exists: true
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
CLI invocation:
|
|
782
|
+
|
|
783
|
+
```sh
|
|
784
|
+
markdown-engine validate --file docs/mission.md --profile validation-profile.yaml
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
Reader-facing operational spec, release checklist, and requirements
|
|
788
|
+
traceability examples live under
|
|
789
|
+
`fixtures/declarative-validation/examples/**`. After building from the
|
|
790
|
+
repository root, run one passing and one intentionally failing example with:
|
|
791
|
+
|
|
792
|
+
```sh
|
|
793
|
+
node dist/cli/index.js validate --file fixtures/declarative-validation/examples/operational-spec/pass.md --profile fixtures/declarative-validation/examples/operational-spec/profile.yaml
|
|
794
|
+
node dist/cli/index.js validate --file fixtures/declarative-validation/examples/operational-spec/fail.md --profile fixtures/declarative-validation/examples/operational-spec/profile.yaml
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
The passing command exits `0`; the intentionally failing command exits `1` and
|
|
798
|
+
emits validation JSON with representative diagnostics and evidence.
|
|
799
|
+
|
|
800
|
+
## Boundary And Non-Goals
|
|
801
|
+
|
|
802
|
+
Declarative validation remains inside the `markdown-engine` deterministic local
|
|
803
|
+
boundary: parse, normalize, validate, diagnose, serialize, and emit evidence.
|
|
804
|
+
|
|
805
|
+
The v1 contract explicitly excludes:
|
|
806
|
+
|
|
807
|
+
- arbitrary JavaScript
|
|
808
|
+
- expression evaluation
|
|
809
|
+
- user-supplied regular expression compilation
|
|
810
|
+
- profile-sourced regex compilation
|
|
811
|
+
- plugins and plugin loading
|
|
812
|
+
- network calls
|
|
813
|
+
- LLM calls
|
|
814
|
+
- file watching
|
|
815
|
+
- persistence
|
|
816
|
+
- profile-specific core semantics
|
|
817
|
+
- operational-design-spec, AGENTS.md, TASK.md, or other domain-specific rule
|
|
818
|
+
meaning in core engine code
|
|
819
|
+
|
|
820
|
+
The admitted v2 Conditional V2 surface also excludes `documentVersion: "3.0.0"`,
|
|
821
|
+
recursive grouped rules, branch-level `when`, profile-defined predicates,
|
|
822
|
+
assertion-specific evidence payloads, a separate skipped-rule evidence channel,
|
|
823
|
+
and a new CLI JSON discriminator.
|
|
824
|
+
|
|
825
|
+
The CLI reads only the caller-specified local Markdown and profile files. The
|
|
826
|
+
API owns no file traversal, daemon, database, browser runtime, network service,
|
|
827
|
+
agent adapter, MCP transport, runtime lens, or persistent cache.
|
|
828
|
+
|
|
829
|
+
## Contract Review Gates
|
|
830
|
+
|
|
831
|
+
The BEL-985 contract gates are:
|
|
832
|
+
|
|
833
|
+
```sh
|
|
834
|
+
npm run docs:declarative-validation-contract
|
|
835
|
+
npm run audit:declarative-validation-boundary
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
The documentation gate checks this contract, README links, legacy contract and
|
|
839
|
+
boundary evidence files, Conditional V2 EVD-6 reviewer notes, and package script
|
|
840
|
+
wiring. The boundary audit checks dependency drift, source-level runtime
|
|
841
|
+
boundary patterns, unsupported regex-like and executable profile-key coverage,
|
|
842
|
+
and declarative validation boundary evidence.
|