Exempt Hub-Hosted Paths From the Prose Gate's dead-path Rule - #731
Merged
Conversation
A repository that retires its copy of a hub-hosted file per a `retire` disposition still names the hub's copy, which is what GOVERNANCE.md "Hub-Hosted Tooling" requires of carried text naming a tool. The tree holds no such file and git once tracked it, so the dead-path rule reports every such mention. The rule's own exemption reads the scanning tree's spec/files.json, which no repository carries, so downstream the exemption set is empty and the class cannot be recognized. It surfaces at the develop -> main promotion, whose diff base brings the whole retirement into scope, leaving a ruleset bypass as the only local remedy for a linter false positive. Observed on ptr727/PhotoCleaner#51. The set is a literal because the prose-gate action fetches prose_lint.py alone with no hub tree beside it, and a test asserts it against the ledger's retire dispositions so a new retirement cannot land on one side.
There was a problem hiding this comment.
Pull request overview
Updates the prose gate's dead-path rule to exempt hub-hosted paths (like repo-config/configure.sh) so downstream repositories that correctly retire local copies can still reference the hub-hosted tooling without failing promotion gates.
Changes:
- Add a
HUB_HOSTEDexemption set toscripts/prose_lint.pyand compare exemptions using POSIX-form paths. - Add regression tests ensuring hub-hosted mentions are exempt and that
HUB_HOSTEDstays aligned withspec/divergences.jsonretiredispositions. - Document the new exemption rationale in
docs/fleet-map.md(G4).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| scripts/prose_lint.py | Adds hub-hosted path exemption and POSIX-normalized key comparison in the dead-path rule. |
| scripts/tests/test_prose_lint.py | Adds tests covering the hub-hosted exemption and validating HUB_HOSTED against the ledger. |
| docs/fleet-map.md | Records the downstream-measured hub-hosted exemption and why it must be literal in the gate. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The exemption lookup and the history lookup now agree on one canonical form, which is what rel() already assumes of a git pathspec.
ptr727
added a commit
that referenced
this pull request
Aug 15, 2026
The report was rewritten whole, which flattened it to LF and failed editorconfig-checker. Normalized back to CRLF, the endings the tree pins. Content: the #721 fix is credited to #731 rather than to this change, the carrier counts say they include the hub's own copy so they read one above the downstream carrier lists in reports/divergences.md, and the workflow model moves off the Types line onto its own.
ptr727
added a commit
that referenced
this pull request
Aug 15, 2026
… the Upstream Repo-Layout Segment (#734) Closes #719 Closes #720 Closes #721 Closes #722 Promotes six merged `develop` PRs to `main`: - #732 -- Reconcile the PlexCleaner registry entry and audit report after the 2026-08-15 resync (closes #719). - #731 -- Exempt hub-hosted paths from the prose gate's `dead-path` rule (closes #721). - #730 -- Fix the hub slug and the dead anchor in the canonical `copilot-instructions.md` (closes #720, #722). - #723 -- Refresh the PhotoCleaner audit report after the 0e84805 resync. - #733 -- Add an `upstream/` segment to the repo layout convention (addresses #725, not closed -- the fork-naming variant differs from the issue's proposal). - #724 -- Add the HomeAutomation-Config audit report and reconcile its registry entry. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ptr727
added a commit
that referenced
this pull request
Aug 15, 2026
…nc (#739) Follow-up to #723 after ptr727/PhotoCleaner#51 promoted `develop` to `main` (`f56178a`), carrying ptr727/PhotoCleaner#50 and ptr727/PhotoCleaner#52. `spec/audit.py PhotoCleaner` at hub `b09078e` reports **clean** at `main` (`audit run 2026-08-15T18:43:20Z | hub b09078e`) and at `develop`, including the two hub-only workflow findings that #736 settled. The report moves to **operational**: `readme-structure` and `agent-instruction-set` to pass, no defects, no drift, nothing in flight. It records the one-round `dead-path` block on the promotion (#721, fixed by #731, cleared by a re-run since the gate reads rules from hub `develop`) and closes both escalations (#721, #722). The registry entry is unchanged: `status` stays `cataloged` (the schema's only non-backlog value) and both `driftNotes` still describe reality (publish shape, private-for-now) and assert no outstanding work. Report lints clean (markdownlint, prose_lint), and `spec/validate.py` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Closes #721
A repository that retires its copy of a hub-hosted file, per the
retiredisposition inspec/divergences.json, keeps naming the hub's copy in its carried docs. That is whatGOVERNANCE.md"Hub-Hosted Tooling" requires of carried text naming a tool ("a pointer that resolves nowhere teaches the reader that a pointer in carried text is decorative"), so rewording is the wrong remedy. But the tree no longer holds the file and git once tracked it, which is exactly the signaturedead-pathkeys on, so every such mention is reported.The rule's own exemption reads the scanning tree's
spec/files.json, which no repository carries, so downstream the exemption set is empty and the class cannot be recognized at all. It surfaces at thedevelop -> mainpromotion, whose diff base brings the whole retirement into scope, leaving a maintainer's ruleset bypass as the only local remedy for a linter false positive. Observed on ptr727/PhotoCleaner#51, and PlexCleaner carries the sameGOVERNANCE.md:29mention.This is option 1 from the issue. Option 2 (reword the verbatim units to name no path) is the one
RESYNC.mdsection 4 warns against, since a layout sentence that names no path is the blind spot the wholedead-pathrule exists to narrow.HUB_HOSTEDis a literal inprose_lint.py, because the prose-gate action fetches that one file with no hub tree beside it to read the ledger from.retiredispositions, so a new retirement cannot land on one side only.repo-config/configure.shand asserts the mention is clean.docs/fleet-map.mdG4 records the second exemption and why it cannot be derived downstream.Verified: 246 tests in
test_prose_lint.pypass, every otherscripts/testsmodule passes,build_dist.py --checkis current, ruff format and check are clean, and the whole-tree prose gate,repo_gate.py, andspec/validate.pyall pass.