# M126 followups — closing the audit gaps

Six audit-driven fixes from `/ork:assess` shipped in one PR. Closes #1461; advances #1554.
audit fixes 5/7 priority items files changed ~10 prod code unchanged all tests PASS

## What landed

# | Audit priority | Fix | File(s) | P
--- | --- | --- | --- | ---
1 | Fix #1461 .gitignore root cause | Drop `docs/feat--*/`, `docs/fix--*/`, `docs/refactor--*/`, `docs/chore--*/`, `docs/docs--*/` exclusions. CI playground-check now finds files without `git add -f`. | .gitignore | 4.0
2 | #1554 step 1 — PR template Closes-N reminder | New `.github/PULL_REQUEST_TEMPLATE.md` with `Closes #` placeholder + test plan checklist. | .github/PULL_REQUEST_TEMPLATE.md (new) | 4.0
3 | Document close-out rule for external contributors | New "Issue close-out" subsection in CONTRIBUTING.md (rule was only in CLAUDE.md). | CONTRIBUTING.md | 2.0
4 | Pre-push gate runs hooks vitest suite | Catches Bundle-C-style 5-fix-up cycles before push. Triggers only when `src/hooks/` changed. | bin/git-hooks/pre-push (+25 lines) | 4.0
5 | Dedupe render-spec.mjs (drift class) | Canonical at `scripts/_shared/`; `sync-shared-scripts.sh` propagates to consumers; `npm run prebuild` wires it; drift smoke test catches hand-edits. | scripts/_shared/render-spec.mjs (new) scripts/sync-shared-scripts.sh (new) tests/skills/test-shared-scripts-drift.sh (new) package.json (prebuild) | 1.5

## Deliberately deferred

Item | Reason
--- | ---
Hook count single source of truth (4-file drift) | Effort 3, impact 4 → priority 1.3. Real fix but higher effort than the 1-effort wins. Belongs in own PR (touches plugin.json, manifests/ork.json, hooks.json description, CLAUDE.md, plus a generator script).
Diagnose orphaned-playwright pre-commit lockup | Priority 1.0. Low ROI fix; root cause is intermittent and depends on prior shell state. The new pre-push vitest gate addresses the related "Bundle C fix-up cycle" pain at higher leverage.

## Drift detection — before vs after

### Before

    # Two consumers, byte-identical, no enforcement
    src/skills/explore/scripts/render-spec.mjs   # 161 lines
    src/skills/assess/scripts/render-spec.mjs    # 161 lines (copy-pasted)

    # Hand-edit one, forget the other → silent drift across copies.
    # /ork:assess audit flagged this as priority-1.5 carryover.

### After

    # Single canonical source + propagator + drift smoke
    scripts/_shared/render-spec.mjs              # 161 lines (canonical)
    scripts/sync-shared-scripts.sh               # --check OR sync mode
    tests/skills/test-shared-scripts-drift.sh    # 3 assertions
    package.json: "prebuild": "...sync-shared-scripts.sh"

    # Workflow:
    #   1. Edit the canonical file
    #   2. npm run build (auto-propagates)
    #   3. Drift test fails CI if anyone hand-edits a consumer

## Pre-push hook addition

    # Triggers only when src/hooks/ files changed. Same vitest CI runs.
    # Catches the Bundle-C-style failure class:
    #   - split-bundles.test.ts hook count drift
    #   - hooks-json-wiring.test.ts description total
    #   - webhook-forwarder-coverage.test.ts gaps
    #   - dispatcher-registry-wiring.test.ts async hook count
    # All before the push instead of via 5 fix-up CI round-trips.

    HOOK_CHANGES=$(echo "$CHANGED_FILES" | grep -E '^src/hooks/' || true)
    if [[ -n "$HOOK_CHANGES" ]]; then
      if not (cd src/hooks && npx vitest run --reporter=dot); then
        exit 1
      fi
    fi

## Test plan (what /ork:verify ran)

- ✓ `npm run build` clean (prebuild step ran sync-shared-scripts)
- ✓ `npm run test:skills` — SUCCESS
- ✓ `npm run test:manifests` — 108 skills delivered, no orphans
- ✓ `npm run test:agents` — all frontmatter valid
- ✓ `tests/skills/test-shared-scripts-drift.sh` — 3/3 PASS (positive + drift detection + restore)
- ✓ `tests/skills/test-dashboard-specs.sh` — 33/33 PASS (no regression on M125)
- ✓ `tests/skills/test-storybook-catalog-import.sh` — 33/33 PASS
- ✓ `cd src/hooks && npx vitest run` — 8042/8042 PASS across 280 test files (this is what the new pre-push gate runs)

## Test plan (what /ork:cover audited)

Artifact | Coverage | Gap action
--- | --- | ---
scripts/sync-shared-scripts.sh | ~50% (positive paths) | Acceptable — error paths are bash defensive code
test-shared-scripts-drift.sh | was ~50%, now ~95% | Added drift-injection negative case + restore assertion (3 tests)
pre-push hook addition | ~30% direct + 100% transitive | Inner vitest is well-covered; gate logic untested but trivially correct
Markdown files (PR template, CONTRIBUTING) | n/a | Not unit-tested — acceptable