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
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
[rules] max_annotation_length and --max-length <N>: fail any annotation field
(Concern, Non-concern, IO) whose MAXIMAL SPAN runs over N characters — on a conforming
line that span is exactly the trimmed value (see Fixed, below). N itself passes. 200 by
default (see Changed); --max-length 0 normalizes to no bound, like --max-per-node 0.
annotation_too_long category, carrying defect.too_long (each offending part and its
length) and defect.max (the bound).
annotation::Outcome::TooLong variant. Outcome is a pub enum with no #[non_exhaustive], so a downstream exhaustive match must handle it.
Changed
BREAKING: the annotation length bound ships ON at 200 characters per field — default_config.toml now sets [rules] max_annotation_length = 200, the built-in layer every
other layer overrides. A repo that passed --strict-check on 0.4.0 with longer annotations now
FAILS with no config change. A bound nobody enables catches nothing: 0.4.0 in real repos let
agents write 500–1600 character fields. Raise it with [rules] max_annotation_length = <N> or --max-length <N>; --max-length 0 disables it. The failing TEXT report names that escape once.
--strict-check is form-only: every field present, non-empty, within the length
bound. Filler Concerns, inward Non-concerns, <placeholder> slots and an empty IO
operand (IO: (a) ->) all pass. The annotation guide still advises against filler.
An empty field is fatal as malformed_annotation, naming the field in defect.missing. A
line whose three keys are present but unextractable (Concern: a|Non-concern: b|IO: c, or
keys out of order) reports all three parts. Both carry a human detail clause.
annotation::Outcome::Malformed gains a detail field: any struct-variant pattern on Malformed must be updated.
annotation::analyze / analyze_charter / analyze_file take the length bound as a
trailing Option<usize> (None = no bound).
config::CliOverrides gains a public max_annotation_length field: a struct-literal
construction must supply it, or fall back to ..Default::default().
Cli gains a public max_length field. Cli derives no Default, so a struct-literal
construction must supply it.
suggestion is absent for annotation_too_long. The TEXT message never carried one for
this category either, so TEXT-only consumers see no change.
The suggestion stub passes the form check as printed. Its <…> slots are still judgments
an agent has to write out, and a configured max_annotation_length applies to it
(<concern owned elsewhere> alone is 25 characters).
--help output: the embedded annotation guide declares the Non-concern's where-it-lives
pointer OPTIONAL and carries a BREVITY section.
--githook-guide recipe and the commit-message attestation format: every per-principle line
carries a severity — none, N/A — reason, or MAJOR/MODERATE/MINOR plus the finding —
in place of a numeric score. MEDIUM: is renamed MODERATE:, no alias. A numeric MINOR:
count is now required, and never gated. The gate cross-checks the lines against the counts: a
line carrying MAJOR under a declared MAJOR: 0 fails. BREAKING for a shipped recipe: a repo
that wired the example hook in has every commit message rejected until it adopts the format.
--githook-guide defines the three severity tiers (MAJOR / MODERATE / MINOR).
Removed
--symbols, the [display] show_symbols key, the FileNode.symbols JSON field (and its --schema lines), the symbols module, and the symbols Cargo feature with its tree-sitter, tree-sitter-python, tree-sitter-rust, tree-sitter-go, tree-sitter-typescript and streaming-iterator optional dependencies. The tool reports on a
file as a NODE — its declared contract — never on its body; a parsed declaration list is a
second, derived map that can disagree with the annotated one.
BREAKING: the Symbol and SymbolKind crate-root re-exports are gone, and Display, CliOverrides, Cli and FileNode lose their public show_symbols/symbols fields; none is #[non_exhaustive], so a struct literal or field read must drop it. A repo config still
carrying show_symbols now fails to parse (deny_unknown_fields) — delete the key. mcp is
the only remaining Cargo feature.
--tokens, the [display] show_tokens key, the DirNode.tokens / FileNode.tokens JSON
fields (and their --schema lines), and the tokens module. It was a ~4 bytes/token
heuristic, and an unreliable estimate in a tool sold on ingest efficiency is worse than none
— an agent may budget against it.
BREAKING: Display, CliOverrides, Cli, DirNode and FileNode lose their public show_tokens/tokens fields; none is #[non_exhaustive], so a struct literal or field read
must drop it. A repo config still carrying show_tokens now fails to parse
(deny_unknown_fields) — delete the key.
The vacuity gate: the annotation_vacuous category, the defect.vacuous JSON key, and annotation::Outcome::Vacuous.
The annotation_on_orphan advisory, the strict report's top-level warnings array (and its Found N warning(s) TEXT block), and exit::code::ANNOTATION_ON_ORPHAN. The opt-in [rules] forbid_orphans / orphan_package rule is untouched.
Fixed
.githooks/commit-msg read the FIRST match for each count, so a body line at column 0 reading MAJOR: 0 blockers remained shadowed the real trailer and a commit with unresolved blockers
passed the gate. Every count now takes the LAST match.
The length bound under-measured a field whose prose quoted the | Non-concern: / | IO:
separators with their colons, in EITHER direction: the parser splits at the first occurrence, so
a quote ahead of the real key hid every character after it (a 300-character Concern measured
150 and passed --max-length 200), and splitting at the last occurrence instead merely moved the
shortfall onto a quote that FOLLOWS the real key (a 207-character IO measured 100 and passed).
The three fields partition the line, so choosing an occurrence only redistributes length; the
bound therefore no longer measures the parsed values at all. It measures each field over its
MAXIMAL extent — Concern up to the LAST | Non-concern:, Non-concern from the first of
those to the LAST | IO:, IO from the first of those to the end of the line. On a conforming
line each separator occurs once, so the spans are exactly the parsed fields and no reported
length changes; a line that quotes a separator over-measures and fails loudly, and can no longer
under-measure. Parsing and rendering are byte-for-byte unchanged.
The malformed_annotation suggestion seeded its Concern: from the text before the first bare |, so a Concern whose own prose held a pipe (a shell pipeline, a |x| closure, SQL ||)
was truncated mid-sentence in the suggested stub. It now cuts at the | Non-concern: separator
the parser splits on, so the seed is exactly the Concern the checker read.