Repository navigation
fix(mapper): fall back to core baseline guides when generic is dropped - #68
Merged
devill merged 1 commit intoJul 1, 2026
Merged
Conversation
The mapper's baseline guides clean.md and uncoached.md lived only in the generic plugin, so a config that dropped generic (which the README allows) crashed render_finding and render_clean on a None guide. Moves them out of generic into the core, where the resolver falls back to them last, so the mapper always coaches and never crashes. Adds two spec tests that run the python plugin without generic.
devill
added a commit
that referenced
this pull request
Jul 1, 2026
Reworks Liina's swallowed-exception guide to reuse the shared
{% include "includes/line_level_issues.md" %} instead of inlining the
listing, keeping it consistent with every other guide. To let a
plugin use the shared partials with no generic installed, moves both
partials (line_level_issues.md, file_level_issues.md) from the generic
plugin into the core, where resolve.first() already falls back last —
the same move #68 made for clean.md/uncoached.md. This also fixes the
identical latent crash for php-only and typescript-only configs, whose
guides already use the include.
Drops the brittle full-prose case from habit-mapper.spec.md (those
cases run as exact-match tests; pinning guide prose there breaks on
every wording tweak, and the routing is already covered). Retargets
#68's unguided-smell fallback case from swallowed-exception (now
guided) to warning-comment, and updates the guide-includes contract to
note the core fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <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.
The bug
With a config that runs a plugin but drops
generic(which the README says is allowed),habit-hookscrashes instead of running. Withplugins = ["python"]it raisesAttributeError: 'NoneType' object has no attribute 'suffix', on any run: both an unguided smell and a plain clean run.Root cause
The mapper's two baseline guides,
clean.mdanduncoached.md, live only in thegenericplugin.render_findingandrender_cleanassume they always resolve, so whengenericis not configured the guide isNoneand the next line crashes.This contradicts two docs at once. The README says
genericcan be dropped, andhabit-mapper.spec.mdsays "rather than crash, the mapper falls back to uncoached."The fix
Moved
clean.mdanduncoached.mdout of the generic plugin and into the core, and the resolver now falls back to the core last. The resolution chain becomes project override, then plugin, then core. A plugin can still override with its own version, and the baseline is always there even with nogeneric.It is one fallback loop in
resolve.py, the two guide files in the core, and their removal from generic.Tests
Two new cases in
habit-mapper.spec.md, both running thepythonplugin with nogeneric:uncoached.mdAll existing tests stay green.