T04

The defect belongs in the shared mirror classifier, with caller-level regression coverage and authoring documentation updates. This is a static assessment; no behavior was executed.

Current behavior

In src/gzkit/governance/brief_path_validity.py:95, vendor_mirror_canonical appends a separator and matches literal prefixes without removing ./. Consequently ./.claude/skills/example/SKILL.md misses the mirror classification. If the file exists, the checker accepts it; if absent, it produces an existence error rather than canonical advice. If declared created, _normalize_for_creates removes ./ and the existence exemption can accept it. These outcomes follow from the code, not a test run.

The unprefixed equivalent is refused before existence or creates checks (check_brief_path_validity, line 209), with .gzkit/skills/example/SKILL.md advice. The mapping also covers Claude rules, GitHub skills/instructions, and Agents skills. Directory roots and descendants are supported; the refusal is independent of the enabled-vendor roster.

Implementation and coupled obligations

  • Normalize one literal leading ./ inside vendor_mirror_canonical, and use that SAME normalized string for prefix comparison and suffix slicing. Normalizing comparison alone corrupts the suggested canonical tail. Preserve the original input in diagnostics. Do not use lstrip("./"): the existing normalization documentation explains why this destroys dotfile roots. Avoid filesystem resolution, broad traversal normalization, or changes to the vendor map for this narrowly defined equivalence.
  • Preserve refusal-before-existence ordering. Creation declarations authorize missing canonical files, never generated mirrors. Existing glob-root, trailing-slash and no-Allowed-Paths behavior must remain intact.
  • Shared consumers already converge on this helper: commands/obpi_cmd.py:959–977 delegates through the brief wrapper; single and batch validation invoke it only with --authored. commands/plan_audit_cmd.py:395–420 unions brief and plan creates, then invokes the checker. Its compatibility helper re-export must keep working. commands/adr_promote.py:332–367 also checks promoted briefs. Verify these consumers rather than duplicating normalization in each CLI.
  • Reconciliation is a distinct existence/delta check (governance/brief_reconcile.py:609–637), already normalizing creates comparisons. It does not currently enforce even unprefixed mirror refusal. Do not silently broaden its lifecycle-sensitive contract; clarify whether “wherever” means introducing that additional policy or preserving parity at existing validity gates.
  • Update the path-validity explanation in .gzkit/skills/gz-obpi-specify/SKILL.md and the user manpages for obpi-validate and plan-audit: explain optional ./, canonical advice, and refusal despite CREATE declarations. The manpages currently omit these validity details. The plan-audit skill’s structural-check description is also coupled guidance. For skill edits, skill-surface-sync.md requires a version bump plus last_reviewed, canonical-first editing, then generated wheel/vendor synchronization and parity validation. Do not hand-edit mirrors.

Proposed verification

Write failing unittest regressions first, deriving expected canonical targets independently of the production mapping. Cover every mapped prefix, with/without ./, root/file/glob paths and trailing separators. Assert correct canonical suffixes; include near-prefix negatives and legitimate .gzkit paths. Exercise existing and absent mirrors, brief CREATE, Creates-these-files sections, scaffolded creation wording, and plan-only creates. All mirror cases must retain a mirror refusal; absent canonical paths with creates must remain allowed, and absent undeclared paths must still fail.

Integration tests should establish single/batch authored validation failure and advice, promotion diagnostics, and plan-audit FAIL output/receipt with creates from either document. Preserve lenient non-authored behavior. Subsequently run focused tests, required repository quality checks, documentation/skill checks and synchronization parity checks. None ran here; test availability and existing coverage remain unverified.

Read inventory and limits

Root R = /tmp/gzkit-remedy-snapshot. Full or excerpt reads: /tmp/gzkit-remedy-inputs/T04.md; R/src/gzkit/governance/{brief_path_validity,brief_reconcile}.py; R/src/gzkit/commands/{plan_audit_cmd,obpi_cmd,adr_promote}.py; R/.gzkit/skills/{gz-obpi-specify,gz-plan-audit,gz-agent-sync}/SKILL.md; R/.gzkit/rules/skill-surface-sync.md; R/docs/user/manpages/{obpi-validate,plan-audit}.md; R/.gzkit.json.

Additional filename/content searches scanned R/src, R/.gzkit, R/docs/user, R/data, and R/pyproject.toml; matched snippets were discovery evidence, not whole-file reads. One wildcard call failed before reading; attempted R/.gzkit/personas/main-session.md was unavailable. Search results included historical references embedded in supplied current files; no linked historical artifacts were opened or relied on. No tests, history, network, real checkout, or other answers were read.

Actual shell/read calls: 12, including task read and this response write. Only /tmp/gzkit-remedy-responses/T04.md was written. Implementation, execution evidence and exhaustive repository review remain outside this assessment.