perf(templates): mtime-aware caches for cross_links + parsed templates#5
Merged
silversurfer562 merged 2 commits intomainfrom May 8, 2026
Merged
Conversation
The schema in attune-rag has carried `guide` in the type enum since v1, but `attune-help`'s prefix maps had no entry for it. A new `type: guide` template would have been silently dropped from cross-linking (`_find_template_file` would return None for any `gui-*` id; `_COMPOUND_PREFIXES` would not match a `gui-` template during retrieval ranking). Found while resolving an open question in the template-corpus-tidy spec — the spec asked which prefix `quickstart` should use, and the answer was already-correct (`qui`). The investigation surfaced the `guide` gap as a sibling problem. Changes: - `templates._PREFIX_MAP` gains `"gui": "guides"`. Map reordered alphabetically; behaviour unchanged. - `progression._COMPOUND_PREFIXES` gains `"gui-"`. Order tweaked so the base prefixes are alphabetical (compounds for ref/tas/con stay first per the longest-first contract documented in the comment above the list). - New `tests/test_template_prefixes.py` (4 tests) pins both maps against the expected enum and explicitly asserts `qui` and `gui`. Future schema-enum additions will fail this test until both maps are updated, surfacing the kind of silent drop this commit fixes. The schema enum lives in attune-rag and the prefix maps live here. The new test mirrors the enum as a literal set with a comment pointing at the schema; introducing a runtime dep on attune-rag would violate ADR-002 (attune-help ships with zero required deps beyond python-frontmatter). 250 attune-help tests pass; ruff clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two related fixes from code-review 2026-05-07: 1. ``_load_cross_links`` cached cross_links.json by directory path alone — no mtime check. Long-running processes served stale data after a regen until callers remembered to invoke ``invalidate_cross_links_cache``. Switch the cache key to include ``st_mtime_ns`` so file rewrites invalidate themselves. 2. ``_parse_template_file`` had no cache at all. Every ``populate()`` call re-read and re-parsed the .md (frontmatter + section split). Add a module-level ``(path, mtime_ns) -> parsed_dict`` cache with a thread lock. Same self-invalidating mtime model as #1. Also expose ``invalidate_template_cache()`` for symmetry with the existing ``invalidate_cross_links_cache()`` — useful for tests and hard-reset scenarios; not needed for normal file edits. Tests: 8 new in test_cross_links_cache.py covering first-call load, mtime-stable cache hit, mtime-change reload, missing-file no-cache, manual invalidation. Tests use ``os.utime`` to bump mtime explicitly because macOS HFS+ stores 1s-resolution mtimes and naive rewrites in the same second can otherwise look unchanged. 258 passed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Two related fixes from this morning's code-review (templates.py:198 and :301):
_load_cross_linksnow keys its cache by(dir, mtime_ns)so a regen run automatically invalidates instead of relying on callers rememberinginvalidate_cross_links_cache()._parse_template_filegets a new(path, mtime_ns) -> parsed_dictcache. Everypopulate()call previously re-parsed the markdown.Same self-invalidating mtime pattern in both. 8 new tests. 258 passed.
🤖 Generated with Claude Code