Commit 2eede5c
schema: unify section entry shape under heading: discriminator (plan 156) (#295)
Plan 156 collapses the section-entry vocabulary to one
discriminator (`heading:` — null, string, or mapping) with a
single matcher (`regex:` as a Go RE2 body with `\#(digits)` and
`\#(fmvar(name))` helpers) and one cardinality field
(`repeat: { min, max }`). Hard cutover: `aliases:`, `required:`,
`{unlisted: true}`, scope-level `repeats:`/`sequential:`/
`min:`/`max:`, and `require.filename:` all parse-error with a
"removed; see plan 156" diagnostic naming the replacement.
Core changes:
- internal/schema: new Matcher / Repeat structs, parse_inline.go
/ parse_file.go rewritten for the new shape, matcher.go
centralises RE2 compilation with a bounded cache keyed on the
pattern plus a frontmatter fingerprint (collision-safe via
strconv.Quote).
- validate.go: matchScope state machine (step / claimMatch /
handleNonMatch / flagExtrasBeyondMax / finishRun) drives
contiguous-run claiming with min/max enforcement, broad-and-
after-min yield, out-of-order recovery, and non-contiguous
flagging via claimedScopeMatches (claimCounts tracks per-scope
occurrences so overlapping matchers don't inflate counts).
- ScopeRunIndices helper shared with validate_content.go,
acronyms.go's walkRanges, and requiredstructure/scope_rules.go
so per-scope walkers honour the same run / yield semantics.
- acronyms.go walkRanges surfaces the matched heading text so
scope-name allowlists work with disjunctive regexes
(`Symptoms|Indicators` + `scope: ["Indicators"]`).
Config and fixtures:
- .mdsmith.yml inline schemas migrated to the new shape.
- .mdsmith.pinned.yml restates the same inline schemas in the
pre-156 form so the mdsmith-fixed-version CI gate (pinned at
v0.15.0) can lint the tree via `-c`; merge-queue.yml swaps it
in over .mdsmith.yml with `git update-index --skip-worktree`
to keep the worktree clean for merge-queue-action's git ops.
- MDS020 good/bad fixtures updated to the new shape.
- docs/guides/schemas.md and docs/reference/section-schema.md
rewritten; the `aliases: [A, B]` → `regex: 'A|B'` row sits in
prose because GFM's pipe-escape inside code spans renders
inconsistently.
- Reference acknowledges that MDS020's file-schema path still
uses the legacy parseSchema pipeline; the new parser is the
in-memory shape behind inline schemas.
Regression coverage (TestPlan156_*):
RegexMatchesRenderedPlainText, DigitsCaptureSequential,
FmvarInterpolates, RepeatBoundsEnforced,
RepeatMaxEnforcedInOpenSchema, RejectsUnknownInterpHelper,
RepeatYieldsToOptionalLaterScope, SequentialDiagOnPartialRun,
FmFingerprintCollisionGuard, RepeatSpansDeeperHeadings,
FlagExtrasBeyondMaxSkipsDeeper, RejectsMultipleDigitsInline,
OptionalSpecificClaimsOwnSlot, FlagsExtrasMatchingClaimedScope,
OutOfOrderSequentialDiagFires, OptionalYieldsToBroadFollower,
ScopeRunStopsAtBoundary, FlagsExtrasInIterationStream,
UnboundedRepeatDoesNotFlagAsExceeded,
BroadMatcherYieldsBeforeMin, LateClaimFlagsRepeatMin,
WrongLevelMatchCountsTowardRepeat, RejectsInvalidFmvarPath,
OptionalMatcherSkipsTolerated, BroadRepeatYieldsAcronymScope,
BroadRepeatYieldsToLaterScopeInPerScopeWalkers,
RejectsMultipleNTokensProto, AcronymScopeOnRepeatedScope,
ContentOnRepeatedScope, RulesOnRepeatedScope,
AcronymScopeMatchesByHeadingText,
OutOfOrderRunCountsAvailableMatches,
NonContiguousClaimedScopeFlagged,
LateClaimChildRecursionStopsAtParentLevel,
OverlappingMatcherDoesNotInflateClaimCount.
https://claude.ai/code/session_012GGH62fZUzLuzP8T4ocGkJ
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4704dc5 commit 2eede5c
38 files changed
Lines changed: 5574 additions & 1230 deletions
File tree
- .github
- workflows
- docs
- development
- guides
- reference
- internal
- rules
- MDS020-required-structure
- bad
- good
- requiredstructure
- schema
- plan
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
97 | | - | |
| 97 | + | |
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
| |||
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
227 | 233 | | |
228 | 234 | | |
229 | 235 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
185 | | - | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
186 | 192 | | |
187 | 193 | | |
188 | 194 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
39 | 57 | | |
40 | 58 | | |
41 | 59 | | |
| |||
0 commit comments