T03
The necessary behavior change is in _collect_source_path_literal_issues: resolve the scan directory as project_root / config.paths.source_root / "gzkit". The existing config argument already reaches this function. Replace the default location; do not scan both locations or fall back to src/gzkit.
Evidence and coupled obligations:
-
Configuration → scan population.
config.pydeclaresPathConfig.source_root, defaulting tosrc;GzkitConfig.loadpreserves suppliedpaths.commands/common.py::ensure_initializedloads the project’s.gzkit.json.check_config_paths_cmdalready uses that configuration for required-directory validation and passes it into the collector. The collector nevertheless hardcodessrc/gzkitand returns no issues when that package directory is absent. Thus a relocated tree can satisfy directory validation while its literals escape inspection. This is static code evidence, not an executed reproduction. Config-first policy in the hardcoded-root-eradication chore supports removing that resource-location assumption. The task settles that the package suffix remainsgzkit. -
Population selection must preserve classification. Keep the AST walk, recognized-prefix regex, URL/length exclusions, central exemptions, and per-module declaration handling unchanged.
_flatten_manifest_pathsadds ancestor mappings;_flatten_config_pathscontributes normalized effective values without deriving ancestors. Their union uses exact or segment-boundary ancestor/descendant coverage. Module_AUDIT_SUBJECT_LITERALSdeclarations instead grant only normalized exact, same-module exemptions, and only from module-level assignments. Existing tests explicitly defend siblings, declaration names, scope and parent boundaries. Relocation does not authorize expanding recognized literal prefixes or adding exemptions. -
Consumer output and proof must still witness scanning. The handler aggregates issues into
{valid, issues}, renders human output or JSON, and exits 1 on issues. Parser registration already forwards--json; no new flag or schema is needed. Both chore acceptance files consume this exit status, so a false clean scan weakens their evidence. Preserve project-relative POSIX issue paths under the new directory, consistent with cross-platform rules. The real-repository acceptance test currently passesGzkitConfig()rather than loading the repository’s config: update that consumer to use the actual project configuration, or relocation would leave its apparent acceptance witness pointed at the old tree. -
Explanatory surfaces. Update the collector docstring and manpage to explain
<paths.source_root>/gzkit, its default, replacement semantics and the existing governed/exempt classification. The manpage’s current checklist omits source scanning. The hardcoded-root-eradication chore and scanner/test comments call a census restricted tosrc/“COMPLETE”; make that census guidance follow the configured source population, retaining the exact declaration-name requirement. The primary skill and runbook already invoke the correct command and promise no incompatible output form; no routing change is indicated. Tool/skill/runbook alignment requires checking these relationships, not manufacturing new CLI surfaces.
Proposed verification, not performed:
- Add a failing tempfile/unittest case with configuration loaded from
.gzkit.json, a nested relocated root, and a genuinely unmapped recognized literal. Assert the relocated relative issue path. - Put distinguishable violations in both old and configured packages: only the configured package must contribute. Also test a missing configured package with an existing old package to rule out fallback; preserve existing missing-package behavior separately from required-directory errors.
- Exercise governed manifest/config literals and all exemption boundaries under the relocated root, alongside an unexempt negative control so an empty scan cannot pass.
- Add command-level human/JSON checks with otherwise valid fixtures: failure for relocated unmapped content, success after its legitimate disposition, unchanged schema and exit semantics. Existing default-layout tests remain regression coverage.
- Subsequently run focused tests, required repository checks and documentation validation, retaining real outputs. No execution evidence exists here.
Reconciliation and limits: scanner prose says config “defaults,” but implementation uses effective configured values; preserve that behavior and clarify wording. Manifest generation can prefer detected structure over config, so manifest and config may disagree; the requested scan authority is configuration, while manifest coverage remains unchanged. Broad chore language about eliminating all literals is qualified by its explicit audit-subject carve-out. Absolute/outside-root configurations, skipped unreadable or invalid Python, and general manifest-resolution hardcoding are independent leads, not required expansion. Their disposition and omitted historical authorities remain unverified.
Read inventory (relative to /tmp/gzkit-remedy-snapshot; excerpts where noted): src/gzkit/{config.py,commands/config_paths.py,commands/common.py (excerpt),sync.py (excerpt),sync_surfaces.py (excerpts),cli/parser_maintenance.py (excerpt)}; tests/{test_config_paths.py,commands/test_audit.py (excerpts)}; .gzkit.json; .gzkit/skills/gz-check-config-paths/SKILL.md; .gzkit/rules/{tool-skill-runbook-alignment,tests,chores,cli,cross-platform}.md; src/gzkit/chores/{hardcoded-root-eradication,config-paths-remediation}/{CHORE.md,acceptance.json}; docs/user/{manpages/check-config-paths.md,runbook.md (excerpt)}. Rules batch output was partly truncated. Also read /tmp/gzkit-remedy-inputs/T03.md; searches/listings stayed inside the corpus. Actual shell/read calls: 13, including this output write. This bounded trace is not proof of completeness.