feat(skill-drift): multi-channel drift detection from D-AuditC-5 - #65
Merged
Conversation
…C-5 channel 1) Implement edit-time channel of D-AuditC-5 multi-channel skill-drift detection per README invariant 'every rule fails at earliest reachable channel'. Script scans .claude/skills/, agents/, and skills/ for: - Broken internal markdown refs (file existence verification) - Missing 'name:' or 'description:' YAML frontmatter on skill+agent files - Trigger-overlap inventory (WARN-only, does not fail) Repo-local scope ONLY — does not scan ~/.claude/skills/ (per Phase -1 amendment: user-home is non-portable for pre-push / CI). User-home drift is a separate session-bound concern. T16 problem-class statement in the script's top comment block — ADAPT of audit-ai-docs.test.sh pattern, not ADOPT (different problem class). Per decisions.md D-AuditC-5 verdict A+B (2026-05-16).
…-5 channel 2) Wire scripts/check-skill-drift.sh into .husky/pre-push as new section 3b, positioned between hook-stub-completeness (section 3a) and manifest render drift (section 4). Uses [ -x ] guard so missing/non-executable script = silent pass. Intentional bypass-by-design: scripts/check-skill-drift.sh lives outside packages/core/audit-self/ so the hook-stub-completeness audit does not require stub entries for it. The guard makes 'absent script' benign for contributors who haven't pulled the script. Hook smoke-test (§1.8) confirmed: - hook-stub-completeness.test.sh still passes post-wire. - scripts/check-skill-drift.sh runs cleanly on current repo state. Per decisions.md D-AuditC-5 verdict A+B (2026-05-16).
…channel 3) Slot 14 (NOT 11) — respect 1A workstream's reservation of 11-13 for the BFR-default / ai-laziness-traps / phase-research-coverage cascade. Vitest enumerates principles/**/*.test.ts via glob; non-contiguous slot numbers are fine. Temporary gap at 12-13 closes when 1A ships. Test delegates to scripts/check-skill-drift.sh (channel 1) — minimum-LOC path. Does not re-implement check logic in TypeScript. Stays under 80 LOC capability-commit threshold (45 LOC); no Prior-art trailer required. Per decisions.md D-AuditC-5 verdict A+B (2026-05-16).
This was referenced May 22, 2026
artyhoo
added a commit
that referenced
this pull request
May 22, 2026
#165) * docs(meta-factory): N8 A-phase gate — list D1/D2/D3 explicitly in Track-1 row + dep diagram (§7 link) Track-1 row 1.3 and the dependency diagram showed only Depends-on 1.1; the D1/D2/D3 maintainer gate lived only in the §0 prose snapshot. An orchestrator picking work from the operational table/diagram could start A-phase impl before the cost-lever / bench / priority decisions are made. Now both operational touchpoints name D1·D2·D3 + link findings §7. Prior-art: skipped — doc-only edit, no new capability (sequencing-plan prose, no code/dep/artifact added). * docs(meta-factory): clarify N5/N6b readiness + SSOT-ID collision in §0 (anti-confusion) Sessions kept reading 🔲 as 'blocked' regardless of cause. Disambiguate §0: - N5: 🔲 **BLOCKED** — gated on N7 live-dogfood trial (decision=C done, repo-side applied, live trial pending) + N2; can't give back before dogfooding reveals what's unique. - N6b: 🔲 **NOT blocked** — deps met (N3 portable TS-core = packages/core/hooks/pre-push.ts+checks/; the 7 .claude/hooks/*.sh are thin CC-event glue, not engine; + N6a ✅). Sequenced 'last' by choice, startable anytime. - 🔲 legend added: blocked (unmet dep) vs deprioritized (deps met, startable) — the exact distinction sessions confuse. - ⚠ SSOT-ID collision flagged: N7 took #64/#65; N8 findings §7 proposed #64–#68 → N8 A-phase renumbers to #66+ at admission. N7 row left untouched (freshly applied by its owning session). Status reconciled against origin/staging + Wave-10 TS file inventory.
Merged
6 tasks
artyhoo
added a commit
that referenced
this pull request
May 22, 2026
…E Superpowers + SSOT #64/#65 + retention=A coexist (#166) N7 (DECISION=C) repo-side application. Source-verified the Superpowers adoption against shipped SKILL.md (dual-channel DeepWiki + raw WebFetch, 2026-05-22) instead of assuming from name. - .claude/rules/parallel-subwave-isolation.md §4: drop the homegrown AST-detection build-target; REFERENCE Superpowers `using-git-worktrees` (Step 0 GIT_DIR!=GIT_COMMON skip → compatible with isolation:"worktree"). Stays Class C; new §5 §1.7 forward/backward note. - prior-art-evaluations.md: append SSOT #64 (SDD, ADOPT process-layer) + #65 (using-git-worktrees, ADOPT + REFERENCE). NOT #60/#61 — those were taken by the parallel channel-selection wave (the exact ID-collision §6 warned about). "#27 = Git-Isolation" was a misattribution (#27 is HANDOFF_MODE) — corrected, void #27-update skipped. - N7 patch §9 closure: source-verification findings, retention verdict A (coexist), ID corrections, classifier-blocked items. - roadmap banner reconciled (DECISION=C set, original framing preserved append-only); sequencing-plan N7 status updated. Retention=A: SDD review is post-implementation, orchestrator Phase -1 is pre-dispatch + owns quota/Mode/bootstrap meta-layer SDD lacks → coexist. Blocked (maintainer-applied): global Superpowers install + orchestrator- skill annotation — both denied by the auto-mode classifier (untrusted external code / self-modification). Live-dogfood trial pending those. §1.7: Forward — demotion complies with build-first-reuse-default.md (REFERENCE-over-BUILD) + no-paid-llm-in-ci.md (using-git-worktrees pure-git); Backward — scope-reducing, only edited bullet is parallel-subwave-isolation.md:37 (§4), SSOT cross-ref at prior-art-evaluations.md row #65, full self-reflexive note at parallel-subwave-isolation.md:46 Prior-art: skipped — N7 process-layer dogfood adoption; SSOT #64/#65 appended documenting ADOPT verdicts, no new dependency or capability code added
This was referenced May 23, 2026
artyhoo
added a commit
that referenced
this pull request
May 24, 2026
…p-3 (#202) * docs(ssot): add row #71 — delegation-vs-decision discipline (round-1 BUILD evidence trail) ATTN-1 follow-up from round-2 audit (PR #201, commit d212dae Sub-wave B Invariant 1). Documents the external-prior-art check that justified round-1's BUILD verdict over ADOPT for the problem class «delegation-vs-decision discipline in skill priority-tie resolution». Row #71 records: - Candidate: Superpowers `using-superpowers` Red Flags table (13-entry skill-invocation rationalisation tracker) - Verdict: REJECT (T16 problem-class non-match — match score ~5%) - T16 evidence: upstream addresses *whether* to invoke a skill; ours addresses *who decides* among ranked priority candidates - ADAPT credit (internal, no SSOT row per §1 scope): reviewer-discipline §2 «Surface-as-decision-needed» 4-step protocol Format follows the §3 entry template + existing row precedent (#67-#70). Last reviewed 2026-05-24. Trigger to revisit: Superpowers ships a delegation-vs-decision skill; OR /meta-orchestrator §2 scope expands to autonomous-pick-without-confirmation. Not a capability commit (docs-only — §4 entry table append; no new dep, no ≥80 LOC under packages/, no ≥50 LOC under packages/core/<new-dir>/). Prior-art: skipped — append to existing SSOT register (one row, no new upstream-tool adoption); the row itself IS the prior-art evidence trail for an already-shipped BUILD decision. §1.7: forward-check applied — row format complies with prior-art-evaluations.md §3 entry template (next-ID 71, all 8 columns populated, rationale cites round-2 commit d212dae + reviewer-discipline §2 with file:line); T16 problem-class check explicit per ai-laziness-traps.md §2 T16 (upstream-class vs our-class enumerated with match-score). Backward-check sweep — extends existing append-only register; does not edit prior rows; reviewer-discipline.md §2 path verified (.claude/rules/reviewer-discipline.md exists, §2 «Surface-as- decision-needed pattern» at line 17 of that file). * feat(meta-orchestrator): add globs+inject markers per round-2 Invariant 4 ATTN-2 follow-up from round-2 audit (PR #201, commit d212dae Sub-wave B Invariant 4 «recommend path-scoped injection via inject-matching-rule.sh + globs marker. Follow-up annotation»). Adds <!-- globs: --> and <!-- inject: --> markers to both SKILL.md copies (.claude/skills/ runtime + skills/ shipped), targeting: - .claude/orchestrator-prompts/** (kickoff authoring) - docs/meta-factory/wave-sequencing-plan.md (wave plan edits) When extended to scan .claude/skills/*/SKILL.md, the existing inject-matching-rule.sh hook (today scans .claude/rules/*.md per rule-enforcement-channel-selection.md §4) will JIT-inject the meta-orchestrator one-liner reminder on the matched edits — narrowing discoverability from manual recall to per-edit deterministic injection. Forward-going annotation: the hook does NOT yet scan skills/ — that is a separate scope expansion (out of round-2 follow-up scope). Markers are honest annotation pending that extension; the inject summary itself carries this status note. Marker format follows the dogfood precedent in .claude/rules/rule-enforcement-channel-selection.md (the first repo file to carry <!-- globs: --> / <!-- inject: --> markers). 500-line gate respected: markers placed without surrounding blank lines (2-line net addition) so .claude/skills/meta-orchestrator/SKILL.md stays at 500 lines (the gate limit). Dual-file annotation per dual-implementation-discipline §7: both copies get markers so consumer installations (via install.sh) inherit them unchanged when the consumer-side hook supports skills/ scanning. Not a capability commit (annotations + comments only — no new dep, no ≥80 LOC under packages/, no ≥50 LOC under packages/core/<new-dir>/). Prior-art: skipped — annotation-only addition implementing an already- shipped round-2 audit recommendation (Invariant 4); no new upstream-tool adoption (the hook itself is the existing ADAPT of OhMyOpencode `rulesInjector` per SSOT #61). §1.7: forward-check applied — markers conform to rule-enforcement-channel-selection.md §4 grammar (globs subset: prefix/**, exact path; inject summary self-documenting) verified by re-reading .claude/hooks/inject-matching-rule.sh:53,69 parsing regex; dual-file addition complies with dual-implementation-discipline.md §3 (consumer-facing artefact, both copies updated atomically); forward- going annotation discipline follows rule-enforcement-channel-selection.md §6 «Existing rules — forward-going, not retroactive». Backward-check sweep — inline note in inject summary prevents future readers from assuming markers are active (they activate only on hook extension); does not modify existing § content, See also entries, or section ordering; extends but does not supersede prior round-2 Sub-wave B Invariant 4 finding. * fix(meta-orchestrator): plan-currency-check fetches + cross-checks origin/staging Gap-2 follow-up from round-2 audit (PR #201, §1.5 «plan-currency-check.sh не cross-check'ит git log origin/<branch> против локального — пропускает свежие PR'ы»). Before this fix the helper relied on whatever local copy of origin/staging the user happened to have — days stale in long sessions or after a fresh worktree, making fresh merges since last sync invisible to the §1 plan-currency check that consumes this output. Adds a fail-soft `git fetch --quiet origin staging` before the JSON PR-list queries, then surfaces the count of remote-only commits via `git rev-list HEAD..origin/staging`. If non-zero, the oneline log of those commits is printed (capped to 10) as «likely merged PRs since last local sync» — the explicit fresh-PR detector. Fail-soft contract: offline / auth-failure / no-network → echoed warning, helper continues to exit 0 (matches existing graceful- unavailability pattern for `gh` and `git status` blocks at lines 18 / 30 / 38). Dual-file: both `skills/meta-orchestrator/helpers/plan-currency-check.sh` (authoring) and `.claude/skills/meta-orchestrator/helpers/plan-currency-check.sh` (runtime) updated atomically per dual-implementation-discipline §3. Smoke test verified: helper runs clean (exit 0), new section integrates between branch + PR-list blocks, current-branch behaviour confirmed (0 remote-only when synced, lists oneline when stale). Not a capability commit (helper enhancement — no new dep, no ≥80 LOC under packages/, no ≥50 LOC under packages/core/<new-dir>/). Prior-art: skipped — fix to existing helper (shipped #186, audited #192/#201) addressing a specific stale-data gap; no new upstream-tool adoption (git rev-list + git fetch are existing capabilities). §1.7: forward-check applied — fail-soft fetch complies with no-paid-llm-in-ci.md §1 (deterministic git ops, no API-billed calls), dual-implementation-discipline.md §3 (both copies updated atomically; diff -q reports identical post-patch), ai-laziness-traps.md §2 T3 (no-prose-only findings — smoke test verifies exit 0 + correct output on current branch state above). Backward-check sweep — addition is between existing sections (not modifying them); the existing left-right ahead/behind block at lines 22-23 stays unchanged (it benefits from the fetch immediately above when re-run); does not modify §1 SKILL.md consumer logic (helper output remains a superset of prior output — purely additive section), so SKILL.md §1 read of this helper output is backward-compatible. * feat(meta-orchestrator): meta-kickoff template ships worktree setup boilerplate Gap-3 follow-up from round-2 audit (PR #201, §1.5 «worktree symlink slot в template — каждый worker re-discovers packages/core/node_modules symlink discipline»). Adds §4a «Worker worktree setup» between §4 (dispatch instructions) and §5 (AI-traps). The slot ships the boilerplate every worker dispatched into a `git worktree add`-created directory needs as the first session step, otherwise the worker rediscovers (burning Opus) the workspaces / remark requirement that `git worktree add` does NOT copy from the primary workdir. Detection contract uses `git rev-parse --git-dir != --git-common-dir` (absolute path vs relative `.git`) — the same probe Superpowers `using-git-worktrees` uses for its nested-worktree skip, per `parallel-subwave-isolation.md §4`. Idempotent: the `if` body is a no-op in the primary workdir; symlinks are created only when missing. Plumbing reconstituted: - `node_modules` → symlink to primary's `node_modules` (saves an `npm install` cycle inside the worktree) - `packages/core/node_modules` → symlink to `../../node_modules` (workspaces hoisting marker — empirically the load-bearing one) Dual-file: both `skills/meta-orchestrator/templates/meta-kickoff.template.md` (authoring) and `.claude/skills/meta-orchestrator/templates/meta-kickoff.template.md` (runtime) updated atomically per dual-implementation-discipline §3; diff -q reports identical post-patch. The slot lives in the template (not the helper), so it travels with every meta-kickoff generated by `/meta-orchestrator` automatically — the dispatch instructions {{DISPATCH_INSTRUCTIONS}} are sub-wave- specific, this is universal worker boilerplate that precedes them. Not a capability commit (template enhancement — no new dep, no ≥80 LOC under packages/, no ≥50 LOC under packages/core/<new-dir>/). Prior-art: skipped — template enhancement closing a §1.5-surfaced gap in an already-shipped artefact (#186 + #192 + #201); no new upstream- tool adoption (the worktree-detection probe is ADAPT from upstream Superpowers `using-git-worktrees`, SSOT #65, already in the register). §1.7: forward-check applied — slot complies with no-paid-llm-in-ci.md §1 (pure-git deterministic ops, no API-billed calls), parallel-subwave-isolation.md §4 (REFERENCE — uses the same GIT_DIR/GIT_COMMON_DIR worktree-detection pattern Superpowers ships), dual-implementation-discipline.md §3 (both copies updated atomically), ai-laziness-traps.md §2 T15 (the slot itself self-applies — it codifies the boilerplate workers were re-discovering; recursive). Backward-check sweep — addition is purely additive (new §4a section between existing §4 and §5; no edits to existing sections); meta-kickoff.template.md consumers (the launch-table-generator + downstream workers reading the generated kickoff) see the slot as static text post-template-substitution — no placeholder logic depends on the slot's absence.
This was referenced May 26, 2026
artyhoo
added a commit
that referenced
this pull request
May 29, 2026
….6 antipattern bug #39886 backstop + template §4a removal (PR #271 §8 item 4) Extension of commit 193758a per amended kickoff scope. PR #279 hook (WorktreeCreate `.claude/hooks/worktree-setup.sh`) shipped on its own branch → unblocks PR #271 §8 item 4 «DELETE template §4a IFF D2 hook lands first». §4a content is replaced with a brief migration note pointing to PR #279 + parallel-subwave-isolation.md §1 fallback for unwired-hook / non-CC harness setups (forward-going annotation per dual-implementation-discipline.md §9 — not silent deletion). * SKILL.md §7.6 antipattern (line 353, `#worker-dispatch-via-subagent`): add empirical-backstop reference to bug #39886 (anthropics/claude-code#39886, closed-as- duplicate; Agent tool + isolation:"worktree" for WRITE tasks silently fails; read-only Agent dispatch remains OK). Applied via /tmp/iphase-skill-edit.py (idempotent + reversible recipe; state in /tmp/iphase-skill-revert-state.json; revert via /tmp/iphase-skill-revert.py). * meta-kickoff.template.md §4a (was lines 126-148): REMOVED. Replaced with one-paragraph migration note: PR #279 hook handles symlinks when registered; unwired-hook / non-CC consumers fall back to parallel-subwave-isolation.md §1. Stays out of scope (separate batches per PR #271 §8): * item 6: parallel-subwave-isolation.md §1 rule edit (add `claude -w` preferred channel) — Class-A rule, separate atomic per Artifact Ownership Contract. * item 7: .gitignore for .claude/worktrees/ — separate trivial atomic. * item 8: 3 new SSOT entries in prior-art-evaluations.md — separate append-only batch. Prior-art: skipped — prose migration following on the capability commit in PR #279 (which already cited SSOT #65 Superpowers using-git-worktrees ADOPT + tfriedel ADAPT); no new dep, no new ≥80 LOC file, no new packages/core subdir. Bug-#39886 is an external evidence citation, not a new SSOT entry.
This was referenced May 29, 2026
artyhoo
added a commit
that referenced
this pull request
May 30, 2026
… base-ref fix (#300) Implements the dual-channel worktree-create capability (verdict combo b+c) from the 2026-05-30 R-phase. Two delivery channels share the `worktree-create-setup` dual-pair anchor: (b) BUILD scripts/create-worktree.sh — portable CLI/CI/agent-callable worktree setup. Accepts <name> [<project-dir>] [<base-ref>]; mirrors the hook's semantic check but reads CLI args instead of JSON stdin. No jq dependency. Base-ref is configurable (explicit arg → $WORKTREE_BASE_REF → refreshed origin/HEAD → fallback chain) — no hardcoded trunk name, per cold-QA Finding 1. Bug 1 fix (.claude/hooks/worktree-setup.sh): `git remote set-head origin --auto` before the base-ref candidate loop. A stale local origin/HEAD (frozen at main, pre the 2026-05-22 staging migration) was silently basing new worktrees on the wrong branch. Reproduced empirically this session: origin/HEAD pointed at origin/main; --auto corrected it to origin/staging. Marker: swapped the hook's @cc-only-rationale → @dual-pair worktree-create-setup (a portable equivalent now exists; dual-implementation-discipline.md §6 + patch §6.3 / cold-QA Finding 2). First dual-channel pair in the repo. Tests (paired-negative discipline, principle 02): create-worktree.test.ts (11 cases incl. configurable base-ref + 2 paired-negatives); worktree-setup.test.ts gains a BUG-1 regression that fails on the unfixed hook (stale origin/HEAD → main) and passes on the fix (→ staging). (c) REFERENCE Superpowers `using-git-worktrees` (SSOT #65) for the AI-session axis — unchanged; this BUILD serves the orthogonal human/CI axis. Prior-art: docs/meta-factory/research-patches/2026-05-30-worktree-create-dual-channel.md (BUILD verdict for scripts/create-worktree.sh — BFR §3 6-layer survey, 4 candidates surveyed, no portable bash equivalent upstream) + SSOT #65 (Superpowers using-git-worktrees, ADOPT — AI-session axis only, REFERENCE here).
artyhoo
added a commit
that referenced
this pull request
May 30, 2026
…te + SSOT #87 (#301) Follow-up to PR #300 (worktree-create dual-channel I-phase core). Wires the shipped capability into the discipline surfaces that point at it: - parallel-subwave-isolation.md §1: replace the raw `git worktree add ... main` block (a stale-base footgun since the 2026-05-22 staging migration — Bug 1's class) with `bash scripts/create-worktree.sh <name>`, plus a Bug 1 note on why base-ref must come from refreshed origin/HEAD, never a hard-coded branch. - meta-kickoff.template.md §4: non-CC / unwired-hook fallback now points at the portable script instead of the manual git-worktree path. - prior-art-evaluations.md: new SSOT row #87 (worktree-create dual-channel, verdict BUILD + REFERENCE #65; 4-candidate adversarial survey, T16 check, first dual-channel pair → dual-implementation-discipline.md §9 counter = 1). Closes I-phase items 4/5/7 from the worktree-create-dual-channel umbrella. Prior-art: skipped — doc-wiring only (rule/template/SSOT pointers to PR #300's already-evaluated capability), no new capability artifact in this commit.
artyhoo
added a commit
that referenced
this pull request
May 31, 2026
…и версии) (#309) Продолжение хроники с места обрыва (v1/v3 ~22 мая, v2 до «большого переезда»): - Чужой меч в руке: мост к рантайму aif-handoff (#289/290/293/296/298/299) + superset REJECT/KEEP-NARROW/REFERENCE (SSOT #86) + N7-догфуд worktree (SSOT #65) - Распорядитель над распорядителями: /meta-orchestrator (#239-245) + inflight-check (#303) - Застава, что не выдержала испытания: recommendation-laziness — FP=84.2% → снято, оставлены H1 + ловушка T20 (#206/207/210/211/212/215) - Сторожа стерегут сторожей: Stryker-порча (#183), git.ts 0 тестов → 486 строк - v1: догоняющие главы (Wave 10, staging-ствол, аудит памяти, worktree dual-channel #297/300/301) со сносками [^6]-[^13] на первоисточники; v2: догоняющая Часть XIV (переезд+двор+память) Все falsifiable-утверждения сверены с git/research-patches/SSOT (T3-протокол). Примечание: ~468 строк pre-push верны для .husky/pre-push (bash, до миграции, история 468/476) — не путать с pre-push.ts (TS-порт, 447); строки 6/439 — историч. факт-чек, оставлены как есть. Prior-art: skipped — docs/narrative chronicle edit, no new capability
7 tasks
This was referenced Jun 1, 2026
Merged
12 tasks
artyhoo
added a commit
that referenced
this pull request
Jul 23, 2026
… pre-push preflight (#1101) * fix(worktree): SSOT provisioning helper + doctor sweep + self-healing pre-push preflight .claude/hooks/worktree-setup.sh has NEVER been registered: `git log -S'WorktreeCreate' -- .claude/settings.json` is empty and `jq '.hooks.WorktreeCreate'` is null in both the repo and the user-global settings. The hook shipped in PR #279 with its registration delivered as a PR-body HEREDOC for manual application; it was never applied, and .claude/settings.json is agent-uncommittable, so no agent could close the gap. CLAUDE.md:182 nevertheless stated the hook "auto-creates the worktree + node_modules symlinks". PR #1072 later added a self-heal block INSIDE that hook for this same incident class — it cannot help, because the hook it lives in never runs. Live census: 63 of 125 registered worktrees under .claude/worktrees/ are unprovisioned; 32 of them hold a real node_modules directory containing nothing but vitest's .vite caches. Root cause of the unrecoverable state: the principles section of this very hook shells out to vitest, which materialises node_modules/.vite inside the worktree. The path then EXISTS, so both channels' `[[ ! -e … ]]` guards are permanently false, and `ln -sfn TARGET node_modules` against that directory creates node_modules/node_modules — a link nested INSIDE the cache. Changes: - scripts/worktree-node-modules.sh (new) — single source of truth. Separates "free to replace" (absent | symlink | dir holding only .vite* caches) from "already provisioned" (conflating them was a real bug: a correct symlink is both). --check never writes. - .claude/hooks/worktree-setup.sh + scripts/create-worktree.sh — both now call the helper instead of carrying byte-identical copies of the block, which was #sync-by-copy-paste under a shared @dual-pair anchor (dual-implementation-discipline.md §7-§8). The hook's early "worktree exists → reuse" return now re-provisions before returning. - scripts/worktree-doctor.sh (new) — operator sweep over `git worktree list`; --fix applies. - packages/core/hooks/pre-push.ts — `worktree-provisioning` section, FIRST in ALL_SECTIONS so the symlinks land before any section can invoke vitest. Self-heals; blocks only when the primary itself has no node_modules, and then names the remediation. - CLAUDE.md — states what is actually true, including that the hook is not registered and how to verify it. - worktree-setup.test.ts + create-worktree.test.ts — fixtures now ship the helper the hooks depend on; without it both silently no-op on `|| true` and every symlink assertion fails. Paired fixture: packages/core/hooks/worktree-node-modules.test.ts. Verified red->green — 4 of 8 arms fail against the pre-fix inline logic (cache-poison heal, dangling-symlink re-point, unfixable-exit-2, --check-never-writes), 8/8 with the fix. Live: a real vite-poisoned worktree went cache-dirs -> symlinks with no nesting and tsx reachable again. Prior-art: prior-art-evaluations.md#87 (portable worktree-creation CLI landscape, verdict BUILD — unchanged). This commit extracts the shared provisioning block of that entry's own dual pair into one home and adds a sweep over it; no new capability area, no new dependency. Last reviewed updated in this commit. Superpowers `using-git-worktrees` (#65, ADOPT) remains the AI-session axis and is untouched. * chore(install-sh): regenerate npm-stack fingerprints after pre-push.ts edit The 8 npm-stack baselines carry a content hash of packages/core/hooks/pre-push.ts, which ships to consumers; adding the worktree-provisioning section changed it. Diff is exactly one hash line per baseline — the new scripts/worktree-*.sh are maintainer tooling and are NOT in the shipped fingerprint, which is why the section guards on existsSync(helper) and is tagged owner: 'maintainer' (composeSections filters it out of a consumer layout entirely). Pre-push runs test:principles, not the install-sh bash battery, so this surfaced only in CI shard C — the known regen path (SNAPSHOT_MODE=capture bash tests/install-sh/snapshot.sh). Prior-art: skipped — mechanical baseline regeneration after a shipped-file edit, no new capability and no new dependency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements D-AuditC-5 verdict A+B multi-channel skill-drift detection across three channels per README invariant «every rule fails at earliest reachable channel; CI = last resort»:
npm run check:skill-driftinvokes scripts/check-skill-drift.sh for ad-hoc verification.[ -x ]guard so missing script is benign.Detects: (a) broken internal markdown refs in
.claude/skills/**/*.md,agents/**/*.md,skills/**/*.md; (b) missingname:/description:YAML frontmatter on skill+agent files; (c) trigger-overlap inventory (WARN-only). Repo-local scope ONLY — does NOT scan~/.claude/skills/**(non-portable for pre-push / CI).3 atomic commits:
feat(skill-drift): bash drift detector for skill/agent files (D-AuditC-5 channel 1)(b4ed685)feat(skill-drift): pre-push hook wires skill-drift detector (D-AuditC-5 channel 2)(a110318)feat(skill-drift): principle test as CI last-resort gate (D-AuditC-5 channel 3)(1845a96)Slot 14 rationale (NOT slot 11)
1A workstream reserves slots 11-13 for the BFR-default / ai-laziness-traps / phase-research-coverage cascade (per
2026-05-16-1a-drafts-substantive-review.md+decisions.md §D-AuditC-5 Known parallel work). This PR takes slot 14 to avoid cascading renumbering onto 1A. Temporary gap at 12-13 closes when 1A ships. Vitest enumerates principles via glob — non-contiguous slot numbers are fine.Test plan
--no-verify)scripts/check-skill-drift.shis bypass-by-design — outsidepackages/core/audit-self/scope)scripts/check-skill-drift.shreturns exit 0 on current repo state (0 broken refs, 0 missing frontmatter, 0 trigger-overlaps)ls packages/core/principles/14-*→ absent before commit)packages/core/<dir>/, all new files < 80 LOC or outsidepackages/)ATTN
§1.7 Forward-check applied
Existing disciplines checked against this PR's new rule (skill-drift detection):
.husky/pre-push:136-160detector behaviour); no Prior-art trailer required. Confirmed by clean pre-push run..test.tsfile is code, not a doc requiring an Authoritative-for header; the bash scriptscripts/check-skill-drift.shis code too. No header requirement triggered.result.statusint comparison viaspawnSyncreturn type) not narrative prose; vitest framework provides the type-system guarantee.§1.7 Backward-check applied
Sweep of existing artefacts under the new rule's scope (skill+agent files):
.claude/skills/**/*.md+agents/**/*.md+skills/**/*.md— exhaustive sweep by scripts/check-skill-drift.sh:1 returned 0 broken refs, 0 missing frontmatter. Confirmed by standalone run during Wave 3 Phase 2 verification.7c19477) — the brokenreferences/self-testing-docs.mdref in agents/docs-auditor.md (former line 41) and the wrong-tense tool-bootstrapping/SKILL.md phrasing were exactly the class of drift this new rule catches. Post-merge sweep confirms the new detector returns 0 findings → Wave 2 cleanup AND new detection are mutually consistent..husky/pre-push:59-66section 3b is bypass-by-design (script outsidepackages/core/audit-self/scope) and the audit still passes cleanly.🤖 Generated with Claude Code (orchestrator session, Wave 3 of 2026-05-16 D-items execution)