Skip to content

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 30 Jul 18:14
· 49 commits to main since this release
d5dda55

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.