What happened?
A single file with an uppercase markdown suffix anywhere under almanac/ makes every command that reindexes fail. search, show, health and reindex all exit non-zero:
codealmanac: wiki page must be markdown: ...\almanac\NOTES.MD
This is not Windows-only. macOS is case-insensitive by default, so it reproduces on the platform CodeAlmanac currently supports.
What did you expect?
Either the file is treated as a page, or it is ignored — but one stray filename should not take down the whole read surface of the wiki.
Reproduction
cd your-repo # any repo with an initialized almanac/
printf -- '---\ntitle: Notes\n---\n# Notes\n\nBody.\n' > almanac/NOTES.MD
codealmanac search notes
# codealmanac: wiki page must be markdown: .../almanac/NOTES.MD
Environment
- OS: Windows 11 (also expected on macOS — see below)
- Python version: 3.13
- CodeAlmanac version: 0.4.7
- Install method: local checkout
- Agent provider: none needed, this is on the read path
- Almanac root:
almanac/
Logs or output
$ ls almanac/
NOTES.MD README.md topics.yaml
$ codealmanac search notes
codealmanac: wiki page must be markdown: ...\almanac\NOTES.MD
$ codealmanac health
codealmanac: wiki page must be markdown: ...\almanac\NOTES.MD
Extra context
The cause is a disagreement between the producer and the validator in services/wiki/paths.py:
iter_page_paths globs rglob("*.md"). That glob is case-insensitive on Windows and on default macOS volumes, so it also matches NOTES.MD and Mixed.Md.
page_id_for_path then compares the suffix exactly: if relative.suffix != ".md": raise ValidationFailed(...).
load_page_document calls page_id_for_path unguarded, so the error propagates through load_documents → load_index_sources → the implicit reindex that every query command performs. load_documents does have a document is None → files_skipped path, but an exception bypasses it.
Linux is unaffected because rglob is case-sensitive there and never matches those files, which is also why CI is green — the same ubuntu-latest-only blind spot as #24.
Whether .MD should be accepted as a page rather than skipped is a product call. Skipping keeps Linux's existing behaviour and makes all three platforms agree; accepting would change indexing semantics, and the existing "slugs are kebab-case of the filename" canonicalization suggests you might prefer that instead.
I have a fix up in #66 that takes the skip route (one-line guard at the producer, so the index, health and frontmatter-rewrite callers are all covered at once) plus a regression test that pins producer/validator agreement on any runner. Happy to switch it to the canonicalizing version if that is the direction you want.
What happened?
A single file with an uppercase markdown suffix anywhere under
almanac/makes every command that reindexes fail.search,show,healthandreindexall exit non-zero:This is not Windows-only. macOS is case-insensitive by default, so it reproduces on the platform CodeAlmanac currently supports.
What did you expect?
Either the file is treated as a page, or it is ignored — but one stray filename should not take down the whole read surface of the wiki.
Reproduction
Environment
almanac/Logs or output
Extra context
The cause is a disagreement between the producer and the validator in
services/wiki/paths.py:iter_page_pathsglobsrglob("*.md"). That glob is case-insensitive on Windows and on default macOS volumes, so it also matchesNOTES.MDandMixed.Md.page_id_for_paththen compares the suffix exactly:if relative.suffix != ".md": raise ValidationFailed(...).load_page_documentcallspage_id_for_pathunguarded, so the error propagates throughload_documents→load_index_sources→ the implicit reindex that every query command performs.load_documentsdoes have adocument is None→files_skippedpath, but an exception bypasses it.Linux is unaffected because
rglobis case-sensitive there and never matches those files, which is also why CI is green — the sameubuntu-latest-only blind spot as #24.Whether
.MDshould be accepted as a page rather than skipped is a product call. Skipping keeps Linux's existing behaviour and makes all three platforms agree; accepting would change indexing semantics, and the existing "slugs are kebab-case of the filename" canonicalization suggests you might prefer that instead.I have a fix up in #66 that takes the skip route (one-line guard at the producer, so the index, health and frontmatter-rewrite callers are all covered at once) plus a regression test that pins producer/validator agreement on any runner. Happy to switch it to the canonicalizing version if that is the direction you want.