T07
The fix is to resolve the scanner’s directory as project_root / config.paths.source_root / "gzkit". Use only that directory; do not retain a second scan or fallback to src/gzkit.
Evidence and current behavior
src/gzkit/commands/config_paths.py, _collect_source_path_literal_issues, currently hardcodes project_root / "src" / "gzkit" and returns no issues when that directory is absent. Consequently, relocated source can escape inspection, or an obsolete default tree can supply findings. This is a static conclusion, not observed execution.
The command already obtains configuration through ensure_initialized() and passes it to the collector. commands/common.py loads .gzkit.json; config.py declares PathConfig.source_root = "src" and loads supplied path settings. Required-directory checking already uses the configured root. No new parameter, configuration key, schema field, dependency, or parser option is necessary.
Preserve the audit’s classification independently of its filesystem scope:
- Keep the existing known-prefix regex, string filtering, recursive sorted Python traversal, and unreadable/syntactically invalid file handling. A custom directory name does not justify widening the literal vocabulary.
- Keep manifest mappings, including derived parents, unioned with actual configured path values. Config flattening intentionally derives no parents. Coverage then uses exact or slash-delimited ancestor/descendant matching; it is not universally exact-only matching.
- Retain the two explicit exemptions and normalized, exact, module-local
_AUDIT_SUBJECT_LITERALSdeclarations. Never grant prefix exemptions, cross-module credit, or credit to differently named/function-local declarations. - Preserve project-relative diagnostic filenames, result shape
{valid, issues}, and failure exit status.
Coupled obligations
Update the collector docstring that currently promises scanning src/gzkit/. Extend docs/user/manpages/check-config-paths.md: its current check list omits source-literal auditing entirely. Explain <paths.source_root>/gzkit, the default, replacement semantics, and governed/exempt literals. This omission belongs with the correction.
The canonical skill and its packaged copy describe a generic workflow and require output scope verification; neither specifies a hardcoded scan root, so no procedural rewrite is needed. The hardcoded-root chore distinguishes resource resolution from audit subjects: the scanner’s directory is a resource it reads and must use configuration. Its exemption-census example hardcodes src/; qualify that example as the default layout or describe substituting the configured source root, preserving its exact-name and per-module rules. Apply the same clarification to corresponding census comments in code/tests if retained as general guidance. Any canonical skill changes would require mirror synchronization, but this fix does not inherently require such changes.
Proposed verification, not executed
Write failing unittest regressions in tests/test_config_paths.py before changing the collector:
- Put an unmapped
artifacts/unknown/reportsliteral under a nested custom root, with no default tree; assert the precise relocated filename and finding. - Put distinguishable bad literals in both trees; assert only the configured tree contributes. Also test an absent configured package with a populated default tree to forbid fallback.
- Preserve default-root behavior and sibling-package exclusion. Check nested modules are scanned.
- Exercise mapped/configured literals, the undeclared config sibling boundary, explicit exemptions, and module-local declarations under the relocated tree, including cross-module, wrong-name, nested-declaration, and parent-prefix negative controls. Existing tests already encode these semantic boundaries.
Add command-level coverage in tests/commands/test_audit.py: load a custom root from .gzkit.json, prepare other required surfaces, and assert JSON findings/exit 1 for bad source and valid/exit 0 after repair. Retain text-output and missing-required-root behavior. Subsequently run focused tests, appropriate repository checks, and documentation validation; record actual results then.
Uncertainty: absolute/outside-project roots can conflict with relative_to(project_root); the model itself accepts arbitrary strings. This assessment assumes project-local relocation and does not silently add path-policy changes. Historical ownership and full governance readiness cannot be established from the supplied corpus.
Read inventory: prefix all relative paths below with /tmp/gzkit-remedy-snapshot/. Full reads: src/gzkit/commands/config_paths.py, src/gzkit/config.py, tests/test_config_paths.py, docs/user/manpages/check-config-paths.md, docs/user/skills/gz-check-config-paths.md, .gzkit/skills/gz-check-config-paths/SKILL.md, src/gzkit/skills/gz-check-config-paths/SKILL.md, src/gzkit/personas/main-session.md, src/gzkit/chores/hardcoded-root-eradication/CHORE.md, .gzkit.json, src/gzkit/schemas/manifest.json. Excerpts: src/gzkit/commands/common.py, src/gzkit/cli/parser_maintenance.py, tests/commands/test_audit.py. Search-only inventory/content: corpus filenames, src/gzkit, tests, .gzkit/rules; attempted tests/test_cli.py was absent. Also read /tmp/gzkit-remedy-inputs/T07.md.
Actual shell/read calls: 9, including task read and this output write. No checks, workflows, or source edits executed.