Skip to content

kb check: Support targeting notes by glob pattern or changes vs a ref #761

Description

@williamthorsen

Problem

kb check validates an entire knowledge base and has no way to scope the run. The only inputs are --kb (which store) and --json (output format); every invocation checks every note.

During lazy migration this makes the exit code unusable as a gate. While an unmigrated backlog exists, the vault always carries error-severity findings (frontmatter.missing on the not-yet-migrated notes), so kb check always exits 1 regardless of whether the notes a contributor just touched are clean. Per-batch and pre-commit verification therefore cannot rely on the exit code, so callers have to capture the output and grep findings by path. The migrate-notes-batch workflow currently has to tell the agent to ignore the exit code and filter findings to the batch's folder by hand.

The predecessor local validator (scripts/check-notes) supported [paths...] and --vs=<ref>. That targeting capability was lost when validation centralized into kb.

Context

  • The vault is its own git repo. Batch migration is git mv-heavy, so the diff mode must follow renames and compare the working tree (not just committed state) so pre-commit verification sees in-progress edits.
  • Scope = what is reported, not what is loaded. Cross-note rules (wikilink resolution) build the full vault index, so check() continues to enumerate and validate the whole vault; targeting filters the reported findings to the selected notes and computes the exit code over them. A targeted check never false-positives on links pointing at untargeted notes.
  • Selection composes with the existing flags. --kb and --json work alongside any targeting mode; bare kb check keeps its whole-vault behavior.
  • Glob expansion is the command's job, not only the shell's. A pattern works whether or not the shell expands it first, so quoted globs behave identically across shells and inside scripts.
  • Design decisions reached during refinement: --branch from the prior tool is dropped (per-batch checks are served by <patterns...>, and a vs-default-branch gate can add it later, backed by a real consumer); --vs=<ref> is the sole git mode; unmatched-pattern handling distinguishes a typo (usage error) from a real non-note (silent drop).
  • Prior art: the retired scripts/check-notes CLI implemented both modes (resolve-targets.ts), including the --diff-filter=AMR plus working-tree diff for ref mode.

Proposed solution

Add two mutually-exclusive selection modes to kb check, both composing with --kb and --json:

kb check                  validate every note (unchanged default)
kb check <patterns...>    validate notes matching the given globs, paths, or
                          directories, still resolving cross-references against
                          the whole vault
kb check --vs=<ref>       validate notes changed between the working tree and
                          merge-base(<ref>, HEAD): follows renames, includes
                          uncommitted edits, excludes deletions
  • Pattern selection. Arguments are glob patterns, file paths, or directories, expanded by the command and matched against the vault's validatable notes. A bare directory selects its whole subtree. Shell-expanded paths arrive as literal patterns and self-match.
  • Unmatched handling. A pattern matching no validatable note is a usage error (exit 2) naming the argument, unless its leading literal path exists on disk (a real but non-validatable target such as a README, a triage note, or an excluded file), in which case it is dropped silently.
  • Ref selection. Changed notes are resolved from git merge-base(<ref>, HEAD) against the working tree with --diff-filter=AMR --name-only, then fed through the same selector, so non-notes among the changes drop and renames report their destination path.
  • Exit codes keep their meaning (0 no error findings, 1 error findings, 2 usage error) but are computed over the selected notes, so a batch or pre-commit gate passes while the rest of the vault still carries a migration backlog.

Acceptance criteria

Must have

  • kb check <patterns...> validates only notes matching the given globs, paths, or directories, while resolving cross-references (wikilinks) against the whole vault.
  • A directory argument selects every validatable note beneath it.
  • Glob patterns are expanded by the command itself, working whether or not the shell expanded them first.
  • kb check --vs=<ref> validates notes changed between the working tree and merge-base(<ref>, HEAD), including uncommitted edits, following renames (reporting the destination path), and excluding deletions.
  • <patterns...> and --vs are mutually exclusive; supplying both is a usage error (exit 2).
  • --kb and --json compose with both modes; bare kb check is unchanged.
  • A pattern or path matching no validatable note is a usage error (exit 2) naming the argument, unless its leading literal path exists on disk, in which case it is dropped silently.
  • Exit codes retain their meaning but are computed over the selected notes only, so a targeted run passes while the rest of the vault carries error findings.
  • A targeted run that selects zero notes exits 0 with a message distinct from the whole-vault zero-match line (which names the config targets).
  • An invalid or unknown --vs ref is a usage error (exit 2) with a clear message.
  • New and modified behavior is covered by tests, including git-backed --vs exercised against disposable temporary repositories.
  • kb check help text and usage docs are updated to document <patterns...> and --vs=<ref>.

Should have

  • Paths and patterns are interpreted relative to the store root (equal to the repo root for a standard single-repo vault); --vs git output is normalized to store-relative before matching.

Nice to have

  • Targeted human output indicates the selection scope (for example, N of M notes checked), so a caller can confirm the run covered what it intended.

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:kb

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions