You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
§DA-config-concern-records, §AR-config, §FS-distribution.3.1, §REQ-backwards-compatibility.2: grund-core deprecates Findings, Config, KindConfig and CitationRules at its root, to be removed in 0.19.0. The engine now reads a grund.toml into Project (its schema, rules and presentation, inside an envelope of name, version and workspace), Run and Compiled, and the scan returns a Catalog. All four are public beside the old names. Findings is now an alias of Catalog, and Config is a façade built from the records. Code that names an old type still compiles, with a deprecation warning that names the replacement. Only a build with -D warnings fails. No grund command, LSP response, JSON report or written file changes, for any v1 config. Closes issue #453. (PR #501)
§FS-init.2.3.4.3.1, §FS-init.2.3.7.1: the managed AGENTS.md block moves v12 → v14, and v13 → v15 where a rule kind is enabled. It gains one bullet teaching grund list --selector "<selector>" --format json | jq -c '{id,section}' | grund show --batch --toc --format json and linking the new Querying grund guide. Who this breaks: every repository with a grund block — grund check reports it outdated until it is re-rendered. Migration: run grund init. (#491)
§DF-canonical-slug-declarations, §REQ-backwards-compatibility.5, §REQ-no-wrong-citation.2, §FS-declarations.line.configured-slug: configured slug punctuation retains its canonical declaration identity.
Before the correction, a valid repository declaring and citing FS-* or FS-tail*,
with Markdown-link index entries, failed check at exit 1 with off-format,
unknown-reference and missing-index-entry errors. After the correction it prints success at exit 0; explicit and bare show return the actual lead, and
declaration-only refs no longer emits the typo note.
No repository edit or migration is required. Consumers expecting the erroneous
findings must accept their removal; genuinely off-grammar tokens and unresolved
citations retain their findings.
The verdict changes from failure to success for the valid fixture; every finding
that remains keeps its location and corrective action.
§FS-rules.2.1, §FS-rules.5.2, §FS-rules.8: a chapter subject's NAME is the
chapter's whole path.grund list --selector FS.requirements.terms, the
sentence The requirements.terms chapter of each FS, --size, and FS:requirements.terms under a : separator list the nested requirements.terms chapter where they listed nothing, and check evaluates
a rule over that subject on the chapters that exist where it reported every
FS has no requirements.terms chapter. A one-component NAME selects only a
chapter directly under its declaration in list, as it already did in check: list --selector FS.terms no longer lists a nested requirements.terms. A nested chapter's row is titled by its display name, Terms, where an exact FS-login.requirements.terms row repeated the
heading's requirements.terms: coordinate
(§FS-rules.5.1.1). Who this breaks: a script that read nested chapters
through a one-component list --selector or --sizeNAME, or matched a
nested chapter row's title; a dotted
prohibition such as The requirements.terms chapter of each FS must not cite any AR., which passed without reading a chapter and now reports the sites it
forbids; a run that ignored unreached-declaration over a dotted positive
rule, which now reports the chapters that miss their citation; and a run that
ignored orphan-section over a heading nested without its parent, such as ### extra.terms: Terms with no extra. There The terms chapter of each FS must cite at least one AR. took the orphan for
its terms chapter and no longer does, and Each FS must have at most 1 Terms chapter. now counts it by its display name Terms. No deprecation window is owed
(§REQ-backwards-compatibility.4).
The dotted subject had no defined meaning, and the only must runs it let
pass are the dotted prohibition and the dotted positive rule with unreached-declaration ignored, which read no chapter at all. An orphan's
standing as a chapter had no defined meaning either, because §FS-declarations.checks.orphan-section
addresses a name-bearing descendant only once every proper prefix is
recorded, and plain check refuses that tree as an error. Closes issue #511. (PR #523)
§FS-check.3.24.3: where a declaration-local section citation names a section
its owner does not have, the finding says so and offers the escape. Inside a
declaration whose sections stop at 2, a marked 5.1 used to be told to write
the owner's full citation of section 5.1, which the same run reports as missing section on the same line. Its local-section-citation finding now
reads local section citation <token>; <owner> has no section 5.1, so write a full citation or <§>5.1 to show the shape without citing it, followed by the
same release attribution and never by the grund fmt --write clause. A site
whose section exists keeps every byte, the command clause included. Who
this breaks: a script matching the exact message of a local-section-citation finding, in text or JSON, from check or the
language server, at an owned site whose section is absent, including one that
extracts write <citation> from it to apply. The code, severity, location,
count, exit code, the text through local section citation <token>; and the
attribution at the end do not move, and missing section does not change.
Closes issue #515.
§FS-rules.3.5.2: with named sections off, a rule subject that needs them
is answered with one they make valid.grund check --rule and a configured
rule declaration's invalid-rule finding no longer suggest the subject as
typed after accepted form after enabling it: when enabling named sections
would refuse it again. FS-*.requirements and FS.requirements are answered
with The requirements chapter of each FS, and FS-login.Requirements with FS-login under a plain accepted form:, because the repository accepts that
as configured. Where no configured kind can be recovered, as with POLICY.requirements, nothing is suggested: check --rule prints the reason
and then known kinds: …, and the finding ends at the reason. Who this
breaks: a script matching the exact stderr of check --rule, the exact message of an invalid-rule finding, or the exact failure message of the
Python check(rule=…) or Node check(root, { rule }), for such a subject.
That failure message changes as check --rule's stderr does, and where no
kind is recovered it gains the known kinds: line as a second line. Exit
codes, stdout, the finding code and location, and every documented refusal
row do not move. Closes issue #520.
§FS-config.3.5.16, §FS-config.requirements.5, §REQ-backwards-compatibility.4: a [scan] exclude entry containing / is now a config error.exclude = ["docs/plans"] was accepted and excluded nothing, because an entry is one directory name; it now fails the config load at its line — error: grund.toml:4: [scan] exclude entry `docs/plans` contains `/`, not a directory name; remove it to keep the scan unchanged, or use `plans` to exclude that name at any depth — with check exiting 2 and config validate exiting 1, nothing on stdout. Who this breaks: a config holding such an entry, on every command that loads it. The two repairs are not the same: removing the entry keeps exactly the scan you had, while writing plans excludes every directory of that name at every depth. A path-specific exclusion has no v1 spelling. Well-formed names and [fmt] exclude globs are unchanged. (PR #486)
§FS-rules.8.1: a refused grund list --selector is answered with a selector,
not a rule sentence. Every refused selector's accepted form: <rule sentence> tail becomes accepted selector: <selector>, built from what was
typed and the configured kinds, or a line known kinds: … where no kind can
be recovered. FS.requirements.1 and The requirements.1 chapter of each FS are refused for being numbered, FS.*
for its wildcard and Each chapter of each FS for its quantifier, and each of
those adds a hint: grund show --batch --toc … line, after known kinds:
where no kind is recovered. Each */FS is refused for its namespace. A pasted
rule sentence is answered with the subject check --rule reads from it. With
named sections off, the suggestion is one that --selector accepts once they
are on, and is labelled accepted selector after enabling it: only when it
needs them. Who this breaks: a script matching a refused
selector's exact stderr, or its text after accepted form:. Exit codes,
stdout and the accepted selectors do not move, and check --rule prints
every byte it did. Closes issue #505. (PR #509)
§FS-show.3.1.3.1, §FS-output-shapes.4, §DF-show-anchor-data: every successful show --format=json object, single or --batch, now carries anchor, the heading fragment grund fmt --cross-refs derives for it, between kind_title and the closing path, line pair, and each --toc section entry carries its own after depth. It is null where there is no heading anchor: the none profile, source homes, JSON values and E2E manifests. Readers that ignore unknown keys are unaffected; a strict decoder or a whole-output snapshot must accept the new key. Closes issue #497. (PR #500)
§FS-fmt.6.2.1.1, §DF-stub-heading-from-unscanned-target, §REQ-backwards-compatibility.5, §REQ-no-wrong-citation.3: a bare-ID link through a stub anchors on its target's heading whether or not [scan] include reaches it.grund fmt --write linked a bare citation whose stub points at a Markdown file the scan does not reach to an anchor built from the stub's own line, #fs-a where the target opens # FS-a: A, which no heading in that file carries. It now links the target's heading, #fs-a-a, as it did with the target scanned and as grund show <ID> --format=json reports. A target that declares the ID more than once and a broken stub link as before. Who this breaks: the verdict moves from passing to failing for grund fmt --check on a tree an older grund formatted: each such link is a markdown link row at its line, and grund fmt --write repairs it. A link that already carries the target's anchor moves the other way and now passes. grund check and the editor's diagnostics do not move. Every finding that replaces the old verdict names its location and the action to take: run grund fmt --write. Closes issue #549. (PR #554)
§FS-declarations.checks.duplicate.1, §FS-declarations.checks.duplicate.2, §FS-declarations.checks.duplicate.3, §DF-stub-pairs-with-unscanned-target, §REQ-backwards-compatibility.5, §REQ-no-wrong-citation.1: a stub pairs with its target whether or not [scan] include reaches it. Stubs of one ID that point at one file outside the scan are one home, so check no longer reports a duplicate declaration, show no longer refuses an ambiguous ID, and list no longer tags them; a duplicate or ambiguity that involves such a home names the target's path:line, never the stub's. Who this breaks: the verdict moves both ways for a run that leaves the old false duplicate out of its report, by a path such as grund check docs/fs or by a selection: --only with a code a rule produces, such as forbidden-citation, --ignore duplicate, or a trial --rule "<sentence>" --only-rule. Such a run now counts the edge to a citation of such an ID, so a prohibition or an at most or exactly count can fail where the run exited 0, and an at least count can pass; where a duplicate's sites have moved out of the path, the run can pass. Every finding that replaces the old verdict is a rule's existing error, naming its location and the action to take, and a plain grund check, with no path and no selection, already failed over the same tree. Closes issue #532. (PR #533)
§FS-check.3.2.1, §DF-stub-sections-from-unscanned-target, §REQ-backwards-compatibility.5, §REQ-no-wrong-citation.1: a stub's sections are its target's whether or not [scan] include reaches it. A citation of a section the target declares is no longer missing section (or section not found) when the target lies outside the scan, as it never was with the target scanned; rules count it, a value binding to it is compared, a malformed binding into a value it declares is the invalid value binding the scanned tree reports, which grund fmt --cross-refs now leaves unlinked as it does there, and a bare index entry of it is the unlinked-index-entry that grund fmt --write repairs rather than missing-index-entry. A section the target does not declare is reported in the same words as before. Who this breaks: the verdict moves both ways for a run that leaves the old false finding out of its report: --only unlinked-index-entry, --ignore missing-section or --only value-mismatch over a binding of the wrong value, --ignore missing-section or --only invalid-value-binding over a malformed binding, or a rule reached by --ignore missing-section, by --only with a code a rule produces such as forbidden-citation, by a trial --rule "<sentence>" --only-rule, or by a path that holds what an inbound count judges but not the citation. Such a run now counts the citation, so a prohibition or an at most or exactly count can fail where the run exited 0, a numbered section warning until grund 0.18.0, and an at least count can pass. Every finding that replaces the old verdict is an existing error naming its location and the action to take, and a plain grund check, with no selection, already failed over the same tree. Closes issue #529.
§FS-declarations.checks.duplicate.1, §FS-declarations.checks.duplicate.3, §DF-stub-target-declared-twice, §REQ-backwards-compatibility.5, §REQ-no-wrong-citation.1: a stub's target that declares its ID twice is two homes, whether or not [scan] include reaches it. A plain grund check over a tree where a stub points outside the scan at a file that declares the stub's ID twice no longer passes: it reports the duplicate declaration the same tree with the target scanned reports, named at both of the target's lines, where show and refs already refused the ID as ambiguous; list tags the stub, and the editor reports the duplicate from the target's unsaved text. A duplicate that already involved such a target now names each of its declarations rather than the first. Who this breaks: the verdict moves from pass to fail for a plain grund check over such a tree, and both ways for a run that leaves the new duplicate out of its report while it reads a citation of the ID, by a path or by a selection: --ignore duplicate, --only with a code a rule produces such as citation-cardinality, or a trial --rule "<sentence>" --only-rule. Such a run now reads the citation as ambiguous and counts no edge to it, so an at least count can fail where the run exited 0, and a prohibition or an at most or exactly count can pass. Every finding that replaces the old verdict is an existing error naming its location and the action to take. Closes issue #556. (PR #559)
§FS-declarations.checks.broken-stub.2, §REQ-no-wrong-citation.1, §REQ-backwards-compatibility.5, §DF-stub-target-fenced-heading: a heading inside a fenced code block of a stub's Markdown target no longer counts as the target's declaration of the stub's ID, as the scan never counted it. The broken-stub test read every line of the target, fenced or not, so a stub whose target declared its ID only in a fenced example passed grund check with no body behind it, and grund show <ID> answered ID not found for an ID grund list names. The verdict changes from passing to failing on such a tree, whether or not the target is inside [scan] include: check reports stub link target lacks <ID>: <path> at the stub's line, and show refuses with the broken stub: line instead of ID not found. A target that holds a fenced example beside the real declaration stays healthy. Every finding that replaces the old verdict names its location and the action to take: point the stub at the file that holds the real declaration, or move the declaration out of the fence. Closes issue #536. (PR #537)
grund check --watch [<path>] now checks immediately and stays resident, rechecking effective local inputs after saves. Ctrl-C returns the last completed status; interruption before any completion and fatal watcher errors return 2. Previously this flag was rejected. Ordinary one-shot reports and verdicts remain unchanged. Eligible text terminals use an alternate screen restored on exit; redirected output appends. JSON remains finding-only NDJSON with invisible clean runs. Native notifications are required; notification-silent mounts have no polling fallback (§FS-check.6).
Configured markers ending in word characters, such as _, now recognize unqualified full-ID
citations. refs, cover, and editor definition navigation recover the missing edges, and check stops calling their targets unused. Repositories using such markers may now fail
existing dangling, missing-section, or citation-policy checks for citations previously missed.
Follow the located finding to correct or declare the target, or escape an illustration with
the configured marker wrapped in angle brackets, such as <_>FS_login.
This verdict change is the correction recorded in §DF-word-character-citation-markers.2, under §REQ-backwards-compatibility.5, for the prior violation of §REQ-no-missed-citation.2.
Every finding names its location and an action the maintainer can take; the existing remedies
apply to recovered citations.