v2026.5.13
v2026.5.13 — Deploy-Scope Fix and Stale Hook-Path Heal
Tag: v2026.5.13 · Released: 2026-05-29 · npm: npm install -g aiwg@2026.5.13
Two deploy-path regressions in the 2026.5.x stable line: every aiwg use was scaffolding a duplicated workspace layout that immediately tripped the legacy detector, and every upgrade from a pre-be3ee551 install left stale .js hook command paths in .claude/settings.json that crashed Claude Code's SessionStart hook with MODULE_NOT_FOUND. Both fixed here. Also picks up the @pagenary/publisher 2026.5.4 adoption that was queued in Unreleased.
What's fixed
Fresh aiwg use no longer reports migration: partial (Closes #1516)
Every fresh aiwg use was creating two parallel workspace trees under different parents — the intended scoped layout at .aiwg/frameworks/<id>/... (per PR #54) and a legacy top-level layout at .aiwg/<name>/... driven by each framework's memory.creates manifest schema. Because the SDLC legacy-dir detector treats top-level dirs like intake/, requirements/, architecture/ as legacy markers, every newly-deployed workspace immediately reported migration.status: "partial" (legacy AND scoped both present) and migrate-workspace could not fully resolve it.
The six non-SDLC framework manifests (forensics-complete, knowledge-base, media-curator, media-marketing-kit, research-complete, security-engineering) now declare their memory.creates scaffolding under the scoped .aiwg/frameworks/<id>/... location, so both scaffolding passes converge on one directory tree. SDLC's documented top-level artifact dirs are unchanged — they remain the canonical user-facing layout per CLAUDE.md.
The two divergent legacy detectors in workspace-status.mjs and framework-detector.ts are unified on a single definition:
- SDLC canonical top-level dirs alongside
.aiwg/frameworks/= the intended SDLC layout, not "partial migration". - Orphan non-SDLC top-level dirs left over from pre-#1516 installs (
forensics/,kb/,media/,marketing/,security-engineering/) still register as a migration signal, so users on affected workspaces continue to see the prompt until they migrate.
Stale .js hook paths refreshed on aiwg refresh (regression on Claude Code 2.1.157)
Pre-be3ee551 installs (May 10) registered hook scripts as .js in .claude/settings.json. The package declares "type": "module", so .js was loaded as ESM where require() is undefined — every hook invocation failed with ReferenceError. That fix renamed the scripts to .cjs so Node would always load them as CommonJS.
The hooks installer's idempotency check matched existing entries by _aiwg_id only (extension-stripped), so once a stale aiwg-session.js entry was present in settings.json, the upgrade pass on every subsequent aiwg refresh saw "already present" and skipped it — leaving the stale .js command path behind. Claude Code 2.1.157 invokes that path on every session start, the file no longer exists on disk, and the user sees:
SessionStart:startup hook error
Failed with non-blocking status code: node:internal/modules/cjs/loader:1459
(MODULE_NOT_FOUND for the missing .js script.)
The installer now rewrites the command, type, and _aiwg_managed fields on existing AIWG-managed entries when they're out of date, surfacing the rewrite in result.warnings so refresh CLI users see what changed. Regression test added.
@pagenary/publisher bumped to ^2026.5.4
Picks up the page-renderer frontmatter strip (pagenary#19) — collection blog posts no longer render their YAML frontmatter as visible text above the title on docs.aiwg.io. The collection manifest is unchanged. Adopted via the documented npm install --min-release-age=0 first-party override per docs/contributing/versioning.md. docs/contributing/publishing-blog-posts.md updated to drop the now-stale frontmatter-leak caveat.
User impact
- Projects that already have stale
.jspaths in.claude/settings.jsonheal automatically on the nextaiwg refresh/aiwg use. No manual edit required. - Projects with the duplicated workspace layout from the pre-#1516 deploy bug (any of
.aiwg/{forensics,kb,media,marketing,research,security-engineering}/present alongside.aiwg/frameworks/) will still show as flagged byaiwg statusuntil the orphan top-level dirs are moved or pruned. The template stubs (forensics/chain-of-custody.md,kb/index.md) carry the only content and can be relocated under.aiwg/frameworks/<id>/. - Documentation blog readers on docs.aiwg.io no longer see raw YAML frontmatter rendered above blog-post titles.
Verification
npm run check:versions
npm run typecheck
npm run build
npx vitest run test/unit/plugin/framework-detector.test.ts
npx vitest run test/integration/forensics-complete.test.ts
npx vitest run test/unit/extensions/claude-hooks-installer.test.ts
npm run uat