Why
Part of #5 (covers globs + ghost-anchor coverage). That issue is a deferred research epic; this carves out the one piece that is small, safe, and shippable now: making the covers field exist and be authorable.
Today covers is forward-declared in the spec (§9.1) but the schema actively rejects it — a hub author who writes covers: gets a parse error (deny_unknown_fields), and there's a test (covers_field_is_rejected) asserting that. This issue flips that: accept and store the field, validate it, but do not let it touch the verdict. The advisory "louder coverage pass" that actually uses these globs stays in #5, gated on a recall study.
What
- Add optional
#[serde(default)] pub covers: Vec<String> to Frontmatter in surf-core/src/hub.rs. Globs are repo-root-relative, same dialect as config.hubs.
- Replace
covers_field_is_rejected with covers_field_is_accepted; add round-trip + default-empty tests.
- Validate the globs in
surf lint (reuse the glob::Pattern::new error path already used for --files in check.rs) so a malformed covers is a clear lint error, not a runtime surprise.
- Optional nicety:
surf lint warns if a hub's own anchored files aren't matched by its own covers (catches fat-fingered globs).
Non-negotiable constraints
- The verdict never reads
covers. surf check pass/fail must be byte-for-byte unchanged whether or not a hub declares covers. This is just parse + store + lint. Per §5/§8, the fuzzy layer can only ever advise.
Explicitly out of scope (stays in #5)
- The advisory coverage pass that diffs changed files against
covers globs.
- Any reviewer-plugin / LLM consumption.
Verification
cargo test -p surf-core — new accept/round-trip/default-empty tests pass.
- Author a hub with a
covers: block and confirm surf check exit code is identical to the same hub without it.
surf lint flags a malformed glob.
Design context: see the research comment on #5.
Why
Part of #5 (
coversglobs + ghost-anchor coverage). That issue is a deferred research epic; this carves out the one piece that is small, safe, and shippable now: making thecoversfield exist and be authorable.Today
coversis forward-declared in the spec (§9.1) but the schema actively rejects it — a hub author who writescovers:gets a parse error (deny_unknown_fields), and there's a test (covers_field_is_rejected) asserting that. This issue flips that: accept and store the field, validate it, but do not let it touch the verdict. The advisory "louder coverage pass" that actually uses these globs stays in #5, gated on a recall study.What
#[serde(default)] pub covers: Vec<String>toFrontmatterinsurf-core/src/hub.rs. Globs are repo-root-relative, same dialect asconfig.hubs.covers_field_is_rejectedwithcovers_field_is_accepted; add round-trip + default-empty tests.surf lint(reuse theglob::Pattern::newerror path already used for--filesincheck.rs) so a malformedcoversis a clear lint error, not a runtime surprise.surf lintwarns if a hub's own anchored files aren't matched by its owncovers(catches fat-fingered globs).Non-negotiable constraints
covers.surf checkpass/fail must be byte-for-byte unchanged whether or not a hub declarescovers. This is just parse + store + lint. Per §5/§8, the fuzzy layer can only ever advise.Explicitly out of scope (stays in #5)
coversglobs.Verification
cargo test -p surf-core— new accept/round-trip/default-empty tests pass.covers:block and confirmsurf checkexit code is identical to the same hub without it.surf lintflags a malformed glob.Design context: see the research comment on #5.