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
./insidevendor_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 uselstrip("./"): 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–977delegates through the brief wrapper; single and batch validation invoke it only with--authored.commands/plan_audit_cmd.py:395–420unions brief and plan creates, then invokes the checker. Its compatibility helper re-export must keep working.commands/adr_promote.py:332–367also 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.mdand the user manpages forobpi-validateandplan-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.mdrequires a version bump pluslast_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.