Skip to content

Add frontmatter-completeness and stale-pattern drift checkers - #126

Open
narendranathe wants to merge 3 commits into
mex-memory:mainfrom
narendranathe:claude/easy-issue-fixes-oyf0gl
Open

Add frontmatter-completeness and stale-pattern drift checkers#126
narendranathe wants to merge 3 commits into
mex-memory:mainfrom
narendranathe:claude/easy-issue-fixes-oyf0gl

Conversation

@narendranathe

Copy link
Copy Markdown

What

Adds two new drift checkers to mex check:

  • checkFrontmatterCompleteness (src/drift/checkers/frontmatter-completeness.ts) —
    flags context/*.md and patterns/*.md files missing recommended
    frontmatter fields (name, description, last_updated).
  • checkStalePatterns (src/drift/checkers/stale-pattern.ts) — flags
    pattern files with no inbound reference from ROUTER.md or any
    context/*.md file.

Why

Closes #53
Closes #51

  • Frontmatter completeness: a missing last_updated already silently
    breaks the existing staleness checker elsewhere in the pipeline. This
    checker surfaces that root cause directly, instead of it showing up later
    as a confusing, unrelated-looking symptom.
  • Stale patterns: checkIndexSync already verifies patterns/INDEX.md's
    table matches the files on disk, but that only catches bookkeeping drift
    in the index itself. A pattern can be correctly listed there and still be
    unreachable in practice, because nothing in the routing table or context
    docs actually points an agent at it. checkStalePatterns closes that gap.

Both checkers reuse existing plumbing (parseFrontmatter, and the same
link/backtick-extraction approach checkIndexSync already uses), so
behavior stays consistent with the rest of the checker suite.

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Docs
  • CI/Tooling

How to test

  1. npm install && npm run build
  2. Run mex check --verbose against a scaffold containing:
    • a context/*.md or patterns/*.md file missing name, description,
      or last_updated → expect a MISSING_FRONTMATTER_FIELD warning
    • a patterns/*.md file not linked from ROUTER.md or any
      context/*.md file → expect a STALE_PATTERN warning
  3. Or run the new unit tests directly:
    npm test -- checkers.test.ts (see the checkFrontmatterCompleteness
    and checkStalePatterns describe blocks)

Checklist

  • Tests pass (npm test) — 379/379 passing, including 10 new tests
  • No breaking changes — two new IssueCodes added
    (MISSING_FRONTMATTER_FIELD, STALE_PATTERN); no existing checker
    behavior changed
  • Tested locally with a real project — smoke-tested with
    mex check --verbose against this repo's own .mex/ scaffold

Code-graph changes

Not applicable — this PR doesn't touch the code graph, LanguageExtractor,
or FrameworkResolver in any way.

## What
Implements the two "good first issue" checkers from the upstream
repo (mex-memory#53 and mex-memory#51):

- checkFrontmatterCompleteness (src/drift/checkers/frontmatter-completeness.ts)
- checkStalePatterns (src/drift/checkers/stale-pattern.ts)

## Why the fix works
- Frontmatter completeness: mex already parses YAML frontmatter for
  every scaffold file via parseFrontmatter/extractFrontmatter
  (src/drift/frontmatter.ts). This checker reuses that existing parse
  pass and asserts that context/*.md and patterns/*.md files declare
  the three fields the rest of the tooling depends on: name,
  description, last_updated. A missing last_updated already silently
  breaks checkStaleness elsewhere in the pipeline; this checker
  surfaces that root cause directly instead of leaving it to show up
  as a confusing downstream symptom.
- Stale pattern: mex already has checkIndexSync, which verifies that
  patterns/INDEX.md's link table matches the files on disk. That only
  catches bookkeeping drift in the INDEX table itself — a pattern can
  be correctly listed in INDEX.md and still be unreachable in
  practice, because nothing in ROUTER.md's routing table or
  context/*.md actually points an agent at it. checkStalePatterns
  closes that gap: it scans ROUTER.md and every context/*.md file for
  a markdown link or backtick reference to each pattern file and
  flags any pattern with zero inbound references. INDEX.md/README.md
  are excluded (they aren't patterns), and the link/backtick
  extraction mirrors the regexes checkIndexSync already uses, so
  behavior stays consistent with the rest of the checker suite.

## Enhancement
`mex check` now catches two classes of scaffold drift it previously
missed silently:
1. context/patterns files with incomplete frontmatter (no name,
   description, or last_updated).
2. Pattern files that exist on disk — and may even be correctly
   indexed — but are orphaned from the routing table an agent
   actually reads, so they'd never get loaded for a matching task.

## How it's solved
- New IssueCode entries MISSING_FRONTMATTER_FIELD and STALE_PATTERN
  added to the closed IssueCode union in src/types.ts (per
  CONTRIBUTING.md, the build fails until a checker's code is listed
  there).
- Both checkers registered in runDriftCheck (src/drift/index.ts):
  frontmatter-completeness runs in the existing per-file frontmatter
  loop next to checkEdges; stale-pattern runs alongside the other
  structural checkers next to checkIndexSync.
- 10 new unit tests added to test/checkers.test.ts, covering the
  triggering and clean cases for both checkers, per CONTRIBUTING.md's
  checker-contribution checklist.
- Verified locally: npm run typecheck, npm test (379/379 passing),
  and npm run build all pass. Also smoke-tested with
  `mex check --verbose` against this repo's own .mex/ scaffold —
  runs clean with no crashes.

Addresses mex-memory#53 and mex-memory#51.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TY1X7PRpE6ChLFmJq1A86s

@theDakshJaitly theDakshJaitly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The focused checker tests, typecheck, and build pass, but both new checkers miss valid cases from their acceptance criteria. Please address the two inline findings and add regression coverage.

Comment thread src/drift/checkers/frontmatter-completeness.ts Outdated
Comment thread src/drift/checkers/stale-pattern.ts
claude added 2 commits August 11, 2026 19:32
Fixes two gaps flagged in review on mex-memory#126 by @theDakshJaitly:

- checkFrontmatterCompleteness returned early on null frontmatter,
  silently skipping files with no frontmatter block at all — the
  strongest case of missing name/description/last_updated. Now
  treats null as an empty object once the file is confirmed in-scope,
  so all three fields are correctly flagged.
- checkStalePatterns only recognized Markdown links and backticked
  filenames, missing mex's canonical frontmatter `edges[].target`
  navigation. A context file referencing a pattern only via
  `edges: [{ target: "patterns/auth.md" }]` was incorrectly flagged
  as STALE_PATTERN. Now also parses each referencing file's
  frontmatter edges and counts matching `patterns/*.md` targets as
  inbound references.

Added regression tests for both cases per review request.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TY1X7PRpE6ChLFmJq1A86s
Self-review follow-up to b13cbbb. Treating null frontmatter as an empty
object was correct for content files, but it made the checker flag
patterns/INDEX.md and patterns/README.md, which mex's own templates ship
without frontmatter because they are navigational files rather than
patterns. On a freshly scaffolded project `mex check` emitted six
spurious MISSING_FRONTMATTER_FIELD warnings and the shipped template
self-flagged — the same failure mode as mex-memory#108.

Both sibling checkers (index-sync, stale-pattern) already exclude these
two filenames; frontmatter-completeness now does the same, with a
regression test so the exemption cannot silently disappear.

Also in stale-pattern: parse frontmatter edges from the file content
already read instead of re-reading each file from disk, and guard
against a malformed non-array `edges` value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TY1X7PRpE6ChLFmJq1A86s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a frontmatter-completeness drift checker Add a stale-pattern drift checker

3 participants