Context
Surfaced by #162 (bound frontmatter YAML parsing). The same frontmatter block is
parsed 2-3 times per compile of a module: build_scope_from_frontmatter,
parse_frontmatter_mapping (feeds @extends), and the lint facts pass
(collect_frontmatter_vars). Each parse now flows through the bounded
parse_frontmatter_yaml choke point, so each pays the full bounded parse
(size cap + node-budget deserialize + pre-parse flow-depth scan).
Not a correctness or security issue
The bounds from #162 are enforced identically on every parse — this is purely a
redundant-work perf refactor, not a safety gap.
Proposal
Parse the frontmatter once and thread the already-parsed
serde_yaml_ng::Value through the callers, e.g. have
resolver.rs::build_scope_from_frontmatter accept a parsed Value instead of
re-parsing the raw string, and reuse it for the @extends mapping and the lint
facts pass. Cost/benefit scales with MAX_MODULE_COUNT.
References
Refs #162
Context
Surfaced by #162 (bound frontmatter YAML parsing). The same frontmatter block is
parsed 2-3 times per compile of a module:
build_scope_from_frontmatter,parse_frontmatter_mapping(feeds@extends), and the lint facts pass(
collect_frontmatter_vars). Each parse now flows through the boundedparse_frontmatter_yamlchoke point, so each pays the full bounded parse(size cap + node-budget deserialize + pre-parse flow-depth scan).
Not a correctness or security issue
The bounds from #162 are enforced identically on every parse — this is purely a
redundant-work perf refactor, not a safety gap.
Proposal
Parse the frontmatter once and thread the already-parsed
serde_yaml_ng::Valuethrough the callers, e.g. haveresolver.rs::build_scope_from_frontmatteraccept a parsedValueinstead ofre-parsing the raw string, and reuse it for the
@extendsmapping and the lintfacts pass. Cost/benefit scales with
MAX_MODULE_COUNT.References
Refs #162