Repository navigation
fix: linter blind spots — frontmatter comments, bad status/dates, published personal store - #7
Merged
Merged
Conversation
The README documents the entry format with trailing comments:
status: current # or: superseded / obsolete
verified: 2026-01-01 # optional; bump after a re-verify ...
files: [.github/workflows/ci.yml] # exact path, dir prefix ...
The frontmatter parser kept them as part of the value, so an entry written
that way parsed as
status -> 'current # or: superseded / obsolete'
verified -> '2026-01-01 # optional; bump after a re-verify ...'
files -> '[.github/workflows/ci.yml] # exact path, ...' (one string)
and each field then misbehaved quietly:
- status: anything not in staleStatuses is live, so
`status: superseded # replaced by X` served a dead entry as LIVE guidance.
- dates: recall's age flag parses the whole value and gave up, so the
"verified N months ago" warning vanished (the linter happened to tolerate
it, so the two disagreed about the same entry).
- files: the list collapsed into one bogus glob -- edit-time recall never
matched the file and the linter reported it as missing.
Drop a trailing `# comment` as YAML does: a `#` that opens the value or
follows whitespace, outside quotes. `C#`, `"Why #1 wins"` and `"b # c"` in a
list keep theirs. One behavior change follows YAML too: an UNQUOTED value
with ` #` in it (`title: Fix issue #12`) now ends before the `#`; quote it to
keep it -- the documented examples already quote titles.
A `'#' not in line` fast path keeps the hooks at their previous latency
(measured at 2,000 entries).
Tests: comments on scalars, lists, block-list items and an empty key; `#`
inside quoted and unquoted values kept; and the README's documented example
must parse to the values it documents. All three fail without the change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMXx6BJswH6xiwdqrwQnEf
`/lore:lint --strict` checked only that `files:` exist, so values the hooks
silently misinterpret went through clean:
status: superseeded recall: not a stale status -> LIVE guidance
date: last week no age flag, no drift triage -- silently
verified: 2026-02-30 same
--strict exit 0, "all entries have valid frontmatter"
The status typo is the dangerous one: the entry was retired on purpose, and
recall resurrects it as current guidance with no [SUPERSEDED] marker.
The default mode now also reports, for live entries, a `status:` that is
neither `current` nor one of `staleStatuses` (the message names the valid
values, config-defined ones included) and a `date:`/`verified:` that is not
a real YYYY-MM-DD date. Both are actionable, so `--strict` -- the pre-push
check and the CI guard -- fails on them. Retired entries are not value-
checked: they drive no live guidance and no freshness flags. The report
header drops "file-ref" since it now covers both, and each kind of problem
gets its own advice line.
This depends on the previous commit: without it, every entry written in the
README's documented format (trailing `# comments`) would be flagged here.
Behavior change for CI: a store with such values will fail `--strict` once
the project refreshes its `.lore/` copies (re-running /lore:init).
Tests: a typo'd status and bad dates fail --strict (both fail without the
change); valid values, a config-defined stale status, and a retired entry
with a bad date stay clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMXx6BJswH6xiwdqrwQnEf
`personalStoreDir` may resolve inside the repository (this repo uses
`.lore/personal`). It is then private only while .gitignore covers it, and
/lore:init adds that rule only when it creates the directory. Set the key by
hand, or drop the rule later, and the store is one `git add -A` away from a
PR -- with no warning anywhere:
.lore.json {"personalStoreDir": "notes"}
/lore:lint OK learnings: all entries have valid frontmatter file refs.
git status ?? notes/
The personal store is exempt from the secret scan and the linter precisely
because it is never supposed to be pushed, so this is the one check that
keeps that assumption true. It holds preferences about how a person likes
to work -- the content the two-store split exists to keep out of teammates'
PRs.
`/lore:lint` and `/lore:stats` now add a note when an in-repo personal store
has files committed to git (published already, even if ignored since: the
note gives the `git rm -r --cached` fix) or is not ignored. A store outside
the repository, or no git, stays silent. It is a note, not a `--strict`
failure; the pre-push hook prints it on every push.
Tests (with git): unignored and committed stores are flagged, an ignored
one and one outside the repository are not, and both commands print it.
The lint/stats test fails without the change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMXx6BJswH6xiwdqrwQnEf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three places where an entry or setting silently misbehaved while the linter said OK. Each is its own commit.
# comments, but the parser kept them in the value.status: superseded # …was then read as an unknown, i.e. live, status; recall lost the age flag on commented dates; andfiles:collapsed into one bogus glob, so edit-time recall never matched. Trailing comments are now dropped as YAML does (outside quotes, after whitespace), with a fast path that keeps hook latency unchanged at 2,000 entries.superseeded) was served as live guidance, and a non-ISOdate:/verified:switched off the entry's freshness checks, yet--strictpassed. The default mode now reports both for live entries, and--strictfails on them.personalStoreDirthat isn't gitignored (or already has committed files) is onegit add -Aaway from a PR, and nothing said so./lore:lintand/lore:statsnow add a note. It's a note only, not a--strictfailure.Behavior changes to review:
--strict(pre-push and CI) now fails on a bad status or date. This reaches users' CI once they re-run/lore:init.#(title: Fix #12) now ends before the#, as in YAML. The documented examples already quote titles.Test plan
python -m unittest discover -s tests: 181 passed, 1 skipped.🤖 Generated with Claude Code
https://claude.ai/code/session_01DMXx6BJswH6xiwdqrwQnEf
Generated by Claude Code