@jasonbelmonti/markdown-engine 2.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 +26 -1
- package/README.md +65 -57
- package/dist/api/declarative-validation.d.ts +2 -2
- package/dist/api/declarative-validation.d.ts.map +1 -1
- package/dist/api/declarative-validation.js +53 -31
- package/dist/api/declarative-validation.js.map +1 -1
- package/dist/cli/declarative-validation.d.ts.map +1 -1
- package/dist/cli/declarative-validation.js +7 -12
- package/dist/cli/declarative-validation.js.map +1 -1
- 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 +2 -2
- package/dist/declarative-validation/assertions/context.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/diagnostics.d.ts +7 -4
- package/dist/declarative-validation/assertions/diagnostics.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/diagnostics.js +26 -1
- package/dist/declarative-validation/assertions/diagnostics.js.map +1 -1
- package/dist/declarative-validation/assertions/evaluator.d.ts +2 -2
- package/dist/declarative-validation/assertions/evaluator.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/evaluator.js +3 -0
- package/dist/declarative-validation/assertions/evaluator.js.map +1 -1
- 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 +15 -0
- package/dist/declarative-validation/assertions/id-targets.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/id-targets.js +18 -55
- package/dist/declarative-validation/assertions/id-targets.js.map +1 -1
- package/dist/declarative-validation/assertions/ids.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/ids.js +100 -14
- package/dist/declarative-validation/assertions/ids.js.map +1 -1
- package/dist/declarative-validation/assertions/index.d.ts +1 -0
- package/dist/declarative-validation/assertions/index.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/index.js +1 -0
- package/dist/declarative-validation/assertions/index.js.map +1 -1
- 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/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 +2 -1
- package/dist/declarative-validation/compiler/assertion-builders.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/assertion-builders.js +51 -13
- package/dist/declarative-validation/compiler/assertion-builders.js.map +1 -1
- package/dist/declarative-validation/compiler/assertion-shapes.d.ts +3 -1
- package/dist/declarative-validation/compiler/assertion-shapes.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/assertion-shapes.js +90 -0
- package/dist/declarative-validation/compiler/assertion-shapes.js.map +1 -1
- package/dist/declarative-validation/compiler/assertions.d.ts +2 -1
- package/dist/declarative-validation/compiler/assertions.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/assertions.js +14 -4
- package/dist/declarative-validation/compiler/assertions.js.map +1 -1
- package/dist/declarative-validation/compiler/compatibility.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/compatibility.js +1 -0
- package/dist/declarative-validation/compiler/compatibility.js.map +1 -1
- 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 +1 -1
- package/dist/declarative-validation/compiler/index.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/index.js +70 -35
- package/dist/declarative-validation/compiler/index.js.map +1 -1
- package/dist/declarative-validation/compiler/plan.d.ts +72 -4
- package/dist/declarative-validation/compiler/plan.d.ts.map +1 -1
- 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/profile-config-diagnostics.d.ts +0 -1
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.d.ts.map +1 -1
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js +8 -2
- package/dist/declarative-validation/diagnostics/profile-config-diagnostics.js.map +1 -1
- package/dist/declarative-validation/evidence/index.d.ts +3 -3
- package/dist/declarative-validation/evidence/index.d.ts.map +1 -1
- package/dist/declarative-validation/evidence/index.js +6 -6
- package/dist/declarative-validation/evidence/index.js.map +1 -1
- 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 +2 -1
- package/dist/declarative-validation/profile/assertion-schema.d.ts.map +1 -1
- package/dist/declarative-validation/profile/assertion-schema.js +149 -14
- package/dist/declarative-validation/profile/assertion-schema.js.map +1 -1
- package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts +3 -1
- package/dist/declarative-validation/profile/direct-profile-diagnostics.d.ts.map +1 -1
- package/dist/declarative-validation/profile/direct-profile-diagnostics.js +10 -2
- package/dist/declarative-validation/profile/direct-profile-diagnostics.js.map +1 -1
- 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 +42 -2
- package/dist/declarative-validation/profile/index.d.ts.map +1 -1
- package/dist/declarative-validation/profile/index.js.map +1 -1
- package/dist/declarative-validation/profile/materialization.d.ts.map +1 -1
- package/dist/declarative-validation/profile/materialization.js +13 -10
- package/dist/declarative-validation/profile/materialization.js.map +1 -1
- package/dist/declarative-validation/profile/schema.d.ts.map +1 -1
- package/dist/declarative-validation/profile/schema.js +73 -12
- package/dist/declarative-validation/profile/schema.js.map +1 -1
- 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 +3 -25
- package/dist/declarative-validation/results/index.d.ts.map +1 -1
- package/dist/declarative-validation/results/index.js +2 -1
- package/dist/declarative-validation/results/index.js.map +1 -1
- 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/table-targets.d.ts +23 -0
- package/dist/declarative-validation/selectors/table-targets.d.ts.map +1 -1
- package/dist/declarative-validation/selectors/table-targets.js +52 -9
- package/dist/declarative-validation/selectors/table-targets.js.map +1 -1
- package/dist-bundled/markdown-engine-cli.mjs +26826 -0
- package/docs/contracts/api.md +19 -15
- package/docs/contracts/declarative-validation.md +319 -36
- package/package.json +8 -3
- 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/docs/contracts/api.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Public API Contract
|
|
2
2
|
|
|
3
|
-
Status: package
|
|
4
|
-
Last updated: 2026-05
|
|
3
|
+
Status: package 3.0.0, document contract 1.0.0
|
|
4
|
+
Last updated: 2026-06-05
|
|
5
5
|
|
|
6
6
|
This document defines the public `@jasonbelmonti/markdown-engine` package
|
|
7
|
-
contract for the `
|
|
7
|
+
contract for the `3.0.0` package release. The serialized rich IR document
|
|
8
8
|
contract remains `documentVersion: "1.0.0"`. The stable public surface is the
|
|
9
9
|
package export from `@jasonbelmonti/markdown-engine`, not internal adapter
|
|
10
10
|
modules or raw parser output. The 1.0 rich IR design is tracked in
|
|
@@ -72,7 +72,7 @@ normalize(parsed: ParsedMarkdown, options?: NormalizeOptions): NormalizeResult
|
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
`NormalizeOptions.documentVersion` selects the document contract version.
|
|
75
|
-
Package
|
|
75
|
+
Package 3.0 keeps omitted `documentVersion` defaulting to the rich IR
|
|
76
76
|
`"1.0.0"` contract. The retained `0.1.0`-compatible path is `"0.0.0"` and must
|
|
77
77
|
be requested explicitly.
|
|
78
78
|
|
|
@@ -227,7 +227,9 @@ validateWithProfile(
|
|
|
227
227
|
|
|
228
228
|
`parseValidationProfile` accepts YAML text or JSON-safe profile objects. The
|
|
229
229
|
top-level profile keys are `syntaxVersion`, `documentVersion`, and `rules`.
|
|
230
|
-
`syntaxVersion` must be `"markdown-engine.validation@v1"
|
|
230
|
+
`syntaxVersion` must be `"markdown-engine.validation@v1"` or
|
|
231
|
+
`"markdown-engine.validation@v2"`; v2 admission is limited to the existing flat
|
|
232
|
+
rule shape.
|
|
231
233
|
`documentVersion` is optional; when provided it must be `"0.0.0"` or
|
|
232
234
|
`"1.0.0"`. The parser preserves omission and does not inject a default into
|
|
233
235
|
the parsed profile.
|
|
@@ -309,7 +311,7 @@ code nodes with `kind: "fenced"`. Raw parser node objects are not public.
|
|
|
309
311
|
|
|
310
312
|
## 1.0 Contract
|
|
311
313
|
|
|
312
|
-
The final 1.0 document contract is selected by default in package
|
|
314
|
+
The final 1.0 document contract is selected by default in package 3.0, remains
|
|
313
315
|
available explicitly as `documentVersion: "1.0.0"`, and is checked with
|
|
314
316
|
`compatibilityMode: "default"`.
|
|
315
317
|
|
|
@@ -536,8 +538,8 @@ serialization behavior.
|
|
|
536
538
|
|
|
537
539
|
### Compatibility And Migration
|
|
538
540
|
|
|
539
|
-
The current package version is `
|
|
540
|
-
version remains `"1.0.0"`. Package
|
|
541
|
+
The current package version is `3.0.0`. The serialized document contract
|
|
542
|
+
version remains `"1.0.0"`. Package 3.0 selects that rich IR contract by
|
|
541
543
|
default for `normalize(parsed)`; callers may also request it explicitly with
|
|
542
544
|
`normalize(..., { documentVersion: "1.0.0" })`. Serialization gates check it
|
|
543
545
|
with `compatibilityMode: "default"`.
|
|
@@ -550,7 +552,7 @@ compatibility from the absence of rich IR fields.
|
|
|
550
552
|
Migration from the `0.1.0` document shape, or from pre-2.0 API callers that
|
|
551
553
|
depended on implicit legacy normalization, requires consumers to:
|
|
552
554
|
|
|
553
|
-
- use package
|
|
555
|
+
- use package 3.0's default `normalize(parsed)` rich IR output or request
|
|
554
556
|
`documentVersion: "1.0.0"` during normalization;
|
|
555
557
|
- read `target`, `sections`, `textSpans`, `tables`, `lists`, `links`,
|
|
556
558
|
`linkReferences`, and `source` from the normalized document instead of
|
|
@@ -609,10 +611,10 @@ exit with code `2`. Validation success exits with code `0`; validation or
|
|
|
609
611
|
normalization error diagnostics exit with code `1`. Validation JSON includes
|
|
610
612
|
`profile`, `ruleResults`, `diagnostics`, and `evidence`.
|
|
611
613
|
|
|
612
|
-
Semver classification: package
|
|
613
|
-
normalization output while retaining the document contract version
|
|
614
|
-
`"1.0.0"`.
|
|
615
|
-
expect the legacy `0.0.0` document shape
|
|
614
|
+
Semver classification: package 3.0 keeps the rich IR contract as the default
|
|
615
|
+
API normalization output while retaining the document contract version
|
|
616
|
+
`"1.0.0"`. The 2.0 migration remains applicable for API consumers that call
|
|
617
|
+
`normalize(parsed)` and expect the legacy `0.0.0` document shape: consume the
|
|
616
618
|
rich IR fields or pin `documentVersion: "0.0.0"` until the downstream consumer
|
|
617
619
|
is ready. CLI consumers can still pin `--document-version 0.0.0` for explicit
|
|
618
620
|
legacy output.
|
|
@@ -651,8 +653,10 @@ The `0.1.0` contract was review-gated by WP-2, MS-2, and MS-3 before first
|
|
|
651
653
|
publication. From the published `0.1.0` baseline forward, changes to public API
|
|
652
654
|
signatures, result fields, diagnostic schema, source-location semantics,
|
|
653
655
|
validation config semantics, or serialized output shape require
|
|
654
|
-
semantic-version classification. The
|
|
655
|
-
|
|
656
|
+
semantic-version classification. The 1.0 rich IR document contract is now the
|
|
657
|
+
retained default document contract for package 3.0, and the explicit legacy
|
|
658
|
+
`0.0.0` path remains the compatibility boundary for consumers that still need
|
|
659
|
+
the first package-line output shape.
|
|
656
660
|
|
|
657
661
|
The `@jasonbelmonti/markdown-engine` package boundary remains limited to
|
|
658
662
|
parsing, normalization, deterministic validation, diagnostics, and
|
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
# Declarative Validation Contract
|
|
2
2
|
|
|
3
|
-
Status: package
|
|
4
|
-
Last updated: 2026-05
|
|
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.
|
|
5
10
|
|
|
6
11
|
This document defines the public declarative validation contract for
|
|
7
12
|
`@jasonbelmonti/markdown-engine`. The stable surface is the package-root API,
|
|
8
|
-
the v1 profile syntax, the
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
public contracts.
|
|
12
|
-
|
|
13
|
-
Package
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
document contract
|
|
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.
|
|
17
34
|
|
|
18
35
|
## 1.0 Contract
|
|
19
36
|
|
|
@@ -53,8 +70,25 @@ syntaxVersion: markdown-engine.validation@v1
|
|
|
53
70
|
`syntaxVersion` is required. Missing or unsupported values emit
|
|
54
71
|
`profile.config.unsupportedSyntaxVersion`.
|
|
55
72
|
|
|
56
|
-
The
|
|
57
|
-
|
|
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
|
|
58
92
|
`profile.config.unsupportedKey` unless the contract assigns a more specific
|
|
59
93
|
compile diagnostic for an unsupported selector target or unsupported assertion
|
|
60
94
|
member.
|
|
@@ -113,15 +147,52 @@ results, and does not evaluate rules.
|
|
|
113
147
|
The top-level profile shape is:
|
|
114
148
|
|
|
115
149
|
```ts
|
|
150
|
+
type ValidationProfileSyntaxVersion =
|
|
151
|
+
| "markdown-engine.validation@v1"
|
|
152
|
+
| "markdown-engine.validation@v2";
|
|
153
|
+
|
|
116
154
|
interface ValidationProfile {
|
|
117
|
-
syntaxVersion:
|
|
155
|
+
syntaxVersion: ValidationProfileSyntaxVersion;
|
|
118
156
|
documentVersion?: EngineDocumentVersion;
|
|
119
157
|
rules: readonly DeclarativeValidationRule[];
|
|
120
158
|
}
|
|
121
159
|
|
|
122
|
-
|
|
160
|
+
type DeclarativeValidationRule =
|
|
161
|
+
| DeclarativeValidationFlatRule
|
|
162
|
+
| DeclarativeValidationGroupRule;
|
|
163
|
+
|
|
164
|
+
interface DeclarativeValidationRuleFields {
|
|
123
165
|
id: string;
|
|
124
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;
|
|
125
196
|
select: DeclarativeSelector;
|
|
126
197
|
assert: DeclarativeAssertion;
|
|
127
198
|
}
|
|
@@ -134,6 +205,11 @@ evidence identify output by `ruleId`.
|
|
|
134
205
|
Rule `severity` defaults to `error` when omitted. Unsupported severity values
|
|
135
206
|
emit `profile.config.invalidShape`.
|
|
136
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
|
+
|
|
137
213
|
Profile values must be JSON-safe data properties after YAML materialization.
|
|
138
214
|
Functions, accessors, proxies, cyclic structures, sparse arrays, `undefined`
|
|
139
215
|
payloads in required positions, non-finite numbers, and `__proto__` properties
|
|
@@ -203,11 +279,27 @@ interface DeclarativeAssertion {
|
|
|
203
279
|
prefix?: string;
|
|
204
280
|
unique?: boolean;
|
|
205
281
|
caseSensitive?: boolean;
|
|
282
|
+
minCount?: number;
|
|
283
|
+
maxCount?: number;
|
|
206
284
|
};
|
|
207
285
|
references?: {
|
|
208
286
|
idsFrom: { section?: string; column?: string; prefix?: string };
|
|
209
287
|
mustAppearIn: readonly string[];
|
|
210
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
|
+
};
|
|
211
303
|
text?: {
|
|
212
304
|
contains?: string;
|
|
213
305
|
excludes?: readonly string[];
|
|
@@ -242,6 +334,7 @@ Selector/assertion compatibility is part of the public contract:
|
|
|
242
334
|
| `tableColumnsRequired` | `table` |
|
|
243
335
|
| `ids` | all supported selector targets |
|
|
244
336
|
| `references` | `document` |
|
|
337
|
+
| `tableColumnCoverage` | `document` |
|
|
245
338
|
| `text` | all supported selector targets |
|
|
246
339
|
| `textOccurrenceCount` | all supported selector targets |
|
|
247
340
|
| `textLength` | all supported selector targets |
|
|
@@ -258,9 +351,32 @@ resolves zero targets.
|
|
|
258
351
|
headings appear as an ordered subsequence in the normalized section tree
|
|
259
352
|
flattened in source order.
|
|
260
353
|
|
|
261
|
-
`ids.unique` must be `true
|
|
262
|
-
|
|
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
|
|
263
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.
|
|
264
380
|
|
|
265
381
|
`text` must include `contains` or a non-empty `excludes` array.
|
|
266
382
|
`textOccurrenceCount.count` is a finite number and counts non-overlapping
|
|
@@ -284,11 +400,17 @@ error severity. Validation diagnostics use the rule severity. Source ranges are
|
|
|
284
400
|
included when a selected target has source evidence; locations are omitted
|
|
285
401
|
rather than fabricated when unavailable.
|
|
286
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
|
+
|
|
287
409
|
| Code | Severity source | Emitted when |
|
|
288
410
|
| --- | --- | --- |
|
|
289
411
|
| `profile.config.invalidYaml` | `error` | YAML text cannot be parsed or materialized as JSON-safe profile data. |
|
|
290
412
|
| `profile.config.yamlWarning` | `warning` | YAML materialization produces a non-fatal parser warning. |
|
|
291
|
-
| `profile.config.unsupportedSyntaxVersion` | `error` | `syntaxVersion` is missing or is not `markdown-engine.validation@v1`. |
|
|
413
|
+
| `profile.config.unsupportedSyntaxVersion` | `error` | `syntaxVersion` is missing or is not `markdown-engine.validation@v1` or `markdown-engine.validation@v2`. |
|
|
292
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. |
|
|
293
415
|
| `profile.config.documentVersionMismatch` | `error` | Resolved profile `documentVersion` differs from the supplied `EngineDocument.version`. |
|
|
294
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. |
|
|
@@ -299,12 +421,17 @@ rather than fabricated when unavailable.
|
|
|
299
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. |
|
|
300
422
|
| `profile.validation.duplicateId` | Rule severity | An `ids.unique` assertion finds repeated IDs. |
|
|
301
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`. |
|
|
302
426
|
| `profile.validation.referenceMissing` | Rule severity | A source ID is absent from a required target section. |
|
|
303
427
|
| `profile.validation.sectionMissing` | Rule severity | A required section heading is absent. |
|
|
304
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. |
|
|
305
432
|
| `profile.validation.textExcluded` | Rule severity | A selected target contains forbidden literal text. |
|
|
306
433
|
| `profile.validation.textMissing` | Rule severity | A selected target lacks required literal text from a `text.contains` assertion. |
|
|
307
|
-
| `profile.validation.assertionUnsupported` | `error` | A compiled assertion has no evaluator implementation; this is an internal safety diagnostic. |
|
|
434
|
+
| `profile.validation.assertionUnsupported` | `error` | A compiled assertion or compiled assertion feature has no evaluator implementation; this is an internal safety diagnostic. |
|
|
308
435
|
|
|
309
436
|
## Result Shape
|
|
310
437
|
|
|
@@ -314,9 +441,12 @@ rather than fabricated when unavailable.
|
|
|
314
441
|
interface DeclarativeValidationResult extends ValidationResult {
|
|
315
442
|
valid: boolean;
|
|
316
443
|
diagnostics: readonly MarkdownDiagnostic[];
|
|
317
|
-
ruleResults: readonly
|
|
444
|
+
ruleResults: readonly (
|
|
445
|
+
| ValidationRuleResult
|
|
446
|
+
| DeclarativeValidationRuleResultV2
|
|
447
|
+
)[];
|
|
318
448
|
profile: {
|
|
319
|
-
syntaxVersion:
|
|
449
|
+
syntaxVersion: ValidationProfileSyntaxVersion;
|
|
320
450
|
documentVersion: EngineDocumentVersion;
|
|
321
451
|
ruleCount: number;
|
|
322
452
|
};
|
|
@@ -324,9 +454,61 @@ interface DeclarativeValidationResult extends ValidationResult {
|
|
|
324
454
|
}
|
|
325
455
|
```
|
|
326
456
|
|
|
327
|
-
|
|
328
|
-
validation
|
|
329
|
-
|
|
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.
|
|
330
512
|
|
|
331
513
|
Rule results are sorted deterministically. Each rule result includes the public
|
|
332
514
|
`ruleId`, `passed`, and cloned diagnostics. Results do not expose compiled rule
|
|
@@ -338,16 +520,27 @@ Evidence is emitted only when `DeclarativeValidationOptions.includeEvidence` is
|
|
|
338
520
|
`true`:
|
|
339
521
|
|
|
340
522
|
```ts
|
|
341
|
-
interface DeclarativeValidationEvidence
|
|
523
|
+
interface DeclarativeValidationEvidence<
|
|
524
|
+
RuleResult extends ValidationRuleResult = ValidationRuleResult,
|
|
525
|
+
> {
|
|
342
526
|
inputHash: string;
|
|
343
527
|
profileHash: string;
|
|
344
528
|
engineVersion: string;
|
|
345
529
|
runtimeVersion: string;
|
|
346
|
-
ruleResults: readonly
|
|
530
|
+
ruleResults: readonly RuleResult[];
|
|
347
531
|
diagnostics: readonly MarkdownDiagnostic[];
|
|
348
532
|
}
|
|
349
533
|
```
|
|
350
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
|
+
|
|
351
544
|
`inputHash` is a lowercase hexadecimal SHA-256 digest of the stable JSON
|
|
352
545
|
serialization of the supplied normalized `EngineDocument` after omitting only
|
|
353
546
|
the top-level `document.path` field. Structural target paths remain part of the
|
|
@@ -360,7 +553,7 @@ serialization of the resolved `ValidationProfile` after applying the resolved
|
|
|
360
553
|
the same profile hash for the same document version and rules.
|
|
361
554
|
|
|
362
555
|
`engineVersion` records the package version that produced the evidence. In the
|
|
363
|
-
|
|
556
|
+
3.0 release line this is `"3.0.0"` even though `documentVersion` remains
|
|
364
557
|
`"1.0.0"`.
|
|
365
558
|
|
|
366
559
|
Raw Markdown bytes, raw YAML bytes, YAML comments, caller file paths, and
|
|
@@ -384,7 +577,9 @@ validate the Markdown file.
|
|
|
384
577
|
|
|
385
578
|
After profile compilation succeeds, the CLI emits a validation-result JSON
|
|
386
579
|
shape whether the document passes or fails. Validation CLI results include
|
|
387
|
-
evidence.
|
|
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"`.
|
|
388
583
|
|
|
389
584
|
## CLI JSON Union
|
|
390
585
|
|
|
@@ -411,23 +606,72 @@ unsupported assertion members, and incompatible selector/assertion pairs. It
|
|
|
411
606
|
contains no `profile` and no `evidence`.
|
|
412
607
|
|
|
413
608
|
Validation-result JSON is used after profile compilation succeeds. It contains
|
|
414
|
-
`profile`, `ruleResults`, `diagnostics`, `valid`, and `evidence`.
|
|
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"`.
|
|
415
613
|
|
|
416
614
|
## Exit Codes
|
|
417
615
|
|
|
418
616
|
| Exit code | Meaning |
|
|
419
617
|
| --- | --- |
|
|
420
|
-
| `0` | Validation completed with no error-severity diagnostics. |
|
|
421
|
-
| `1` | Profile/config/compile, Markdown normalization, document-version mismatch, or validation diagnostics include at least one error. |
|
|
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. |
|
|
422
620
|
| `2` | CLI usage, unsupported format, unknown argument, missing argument value, repeated singleton flag, unsupported `--document-version`, or local file read error. |
|
|
423
621
|
|
|
424
622
|
## Compatibility And Migration
|
|
425
623
|
|
|
426
624
|
The v1 declarative validation syntax is a durable authoring contract for the
|
|
427
|
-
|
|
625
|
+
3.0 package release line. Changes to profile syntax names, selector names,
|
|
428
626
|
assertion names, result fields, diagnostic codes, CLI flags, CLI JSON shape, or
|
|
429
627
|
evidence hash inputs require explicit compatibility review.
|
|
430
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
|
+
|
|
431
675
|
Migration notes:
|
|
432
676
|
|
|
433
677
|
- Consumers using fixed `validate(document, config)` rule families can continue
|
|
@@ -438,6 +682,11 @@ Migration notes:
|
|
|
438
682
|
- Consumers parsing CLI validation output must handle the
|
|
439
683
|
`DeclarativeValidationCliJsonResult` union. Profile-stage failures do not
|
|
440
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.
|
|
441
690
|
- Consumers that compare evidence hashes must normalize expectations around
|
|
442
691
|
resolved `documentVersion`, default rule severity, stable key order, and
|
|
443
692
|
exclusion of only top-level `document.path` from `inputHash`.
|
|
@@ -501,6 +750,34 @@ rules:
|
|
|
501
750
|
count: 1
|
|
502
751
|
```
|
|
503
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
|
+
|
|
504
781
|
CLI invocation:
|
|
505
782
|
|
|
506
783
|
```sh
|
|
@@ -540,6 +817,11 @@ The v1 contract explicitly excludes:
|
|
|
540
817
|
- operational-design-spec, AGENTS.md, TASK.md, or other domain-specific rule
|
|
541
818
|
meaning in core engine code
|
|
542
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
|
+
|
|
543
825
|
The CLI reads only the caller-specified local Markdown and profile files. The
|
|
544
826
|
API owns no file traversal, daemon, database, browser runtime, network service,
|
|
545
827
|
agent adapter, MCP transport, runtime lens, or persistent cache.
|
|
@@ -553,7 +835,8 @@ npm run docs:declarative-validation-contract
|
|
|
553
835
|
npm run audit:declarative-validation-boundary
|
|
554
836
|
```
|
|
555
837
|
|
|
556
|
-
The documentation gate checks this contract, README links,
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jasonbelmonti/markdown-engine",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Deterministic Markdown parsing and validation engine package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
|
+
"dist-bundled",
|
|
35
|
+
"skills",
|
|
34
36
|
"docs/contracts",
|
|
35
37
|
"fixtures/declarative-validation/examples",
|
|
36
38
|
"CHANGELOG.md",
|
|
@@ -42,9 +44,11 @@
|
|
|
42
44
|
"scripts": {
|
|
43
45
|
"clean": "node scripts/clean-dist.mjs",
|
|
44
46
|
"build": "npm run clean && tsc -p tsconfig.json",
|
|
47
|
+
"build:cli:bundled": "node scripts/build-bundled-cli.mjs",
|
|
48
|
+
"build:cli-bundle": "node scripts/build-cli-bundle.mjs",
|
|
45
49
|
"prepack": "npm run release:verify",
|
|
46
50
|
"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",
|
|
51
|
+
"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
52
|
"release:check-clean": "git diff --check HEAD -- && git diff --exit-code HEAD --",
|
|
49
53
|
"snapshots:update:parser": "npm run build && vitest run tests/parser-fixtures.test.ts -u \"--exclude=.worktrees/**\"",
|
|
50
54
|
"snapshots:update:rules": "npm run build && vitest run tests/rules.test.ts -u \"--exclude=.worktrees/**\"",
|
|
@@ -65,7 +69,7 @@
|
|
|
65
69
|
"test:validation:profile": "npm run build && vitest run tests/declarative-validation-profile.test.ts \"--exclude=.worktrees/**\"",
|
|
66
70
|
"test:validation:compiler": "npm run build && vitest run tests/declarative-validation-compiler.test.ts \"--exclude=.worktrees/**\"",
|
|
67
71
|
"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/**\"",
|
|
72
|
+
"test:validation:assertions": "npm run build && vitest run tests/declarative-validation-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
73
|
"test:validation:diagnostics": "npm run build && vitest run tests/declarative-validation-diagnostics.test.ts \"--exclude=.worktrees/**\"",
|
|
70
74
|
"test:validation:cli": "npm run build && vitest run tests/declarative-validation-cli.test.ts \"--exclude=.worktrees/**\"",
|
|
71
75
|
"test:validation:examples": "npm run build && vitest run tests/declarative-validation-examples.test.ts \"--exclude=.worktrees/**\"",
|
|
@@ -83,6 +87,7 @@
|
|
|
83
87
|
"devDependencies": {
|
|
84
88
|
"@types/node": "^22.19.17",
|
|
85
89
|
"cmark-gfm": "^0.9.0",
|
|
90
|
+
"esbuild": "^0.27.7",
|
|
86
91
|
"typescript": "^5.8.3",
|
|
87
92
|
"vitest": "^3.1.3"
|
|
88
93
|
},
|