v2026.5.0
Previous release
AIWG v2026.5.0 — "Project-Local + Kernel-Pivot Maturity"
Released: 2026-05-11 Type: Major release (41 rc iterations folded in) Previous stable release: v2026.3.3 (2026.4.0 was never cut — the rc series rolled forward into 2026.5.0)
v2026.5.0 is two complementary stories landing in one stable cut:
1. Project-local artifacts — a complete operator surface for customizing AIWG per-project without forking, with a graduation path to upstream or a private corpus that's a hash-verified copy with zero rewrite. Epic #1033 delivered eight ADRs / design docs and four implementation phases. 2. Kernel-pivot maturity — the kernel-vs-standard skill split (introduced in 2026.5.0-rc.10) became the load-bearing model AIWG actually operates under. The late-rc work hardened the discover-first protocol, fixed the publish pipeline, audited the Hermes integration against upstream source, and shipped visual docs that finally make the mental model accessible without prose-only walls.
Highlights
| What changed | Why you care |
|---|---|
| Project-local artifact lifecycle (epic #1033) | Customize AIWG per project without forking. The full chain `new-bundle` → `use` → `doctor` → `remove` → `promote` ships in 2026.5.0. |
| `aiwg new-bundle <name>` (#1050) | One command produces a valid manifest + starter artifact + README under `.aiwg/{type}/{name}/`. Aliases: `new-extension`, `new-addon`, `new-framework`, `new-plugin` infer the type. |
| `aiwg promote <name>` (#1037) | Graduate a project-local bundle to upstream or to a private corpus path. SHA-256 verified copy with rollback on mismatch. `--dry-run`, `--cleanup`, `--force`. |
| `aiwg remove` is project-local-aware (#1037) | Reverts deployed files using artifact-hash detection. Source under `.aiwg/<type>/<name>/` is never deleted — `--force` only overrides the case-2 mutation prompt. |
| `aiwg doctor --project-local` (#1037) | Per-type counts, validation errors, shadows (informational vs blocking), drift detection, provider deployment matrix. |
| Activity log for project-local lifecycle (#1037) | 12 lifecycle events emitted to `.aiwg/activity.log` — discover / deploy / shadow-acknowledged / remove-mutated / promote / etc. — with `(name, type)` dedupe for read-only operations. |
| Override / shadow policy (#1036) | Project-local artifacts can shadow upstream cleanly with seven verdicts. Safety-critical denylist refuses to shadow without explicit `overrides:` declaration; `--force` does not bypass. |
| Identical-form portability invariant (ADR #1038) | A bundle at `.aiwg/extensions/foo/` is byte-identical to `agentic/code/addons/foo/` upstream. `aiwg promote` is a copy + verify, not a migration. |
| Path A / B / C customization model | Project-local (recommended for most users), Fork (for upstream contributions), Corpus (cross-project sharing). Mix freely; bundles move between paths by copy. |
| Comprehensive customization docs | New quickstart, lifecycle reference, troubleshooting, from-fork migration, and type disambiguation. Old `.aiwg/.project/` docs replaced with redirects to canonical sources. |
What's new in detail
Project-local artifact lifecycle (epic #1033)
The epic shipped in dependency order, child by child. Each phase produced a usable feature on its own; the complete operator surface lit up in #1037.
Discovery + manifest validation (#1034)
Read-only scan of `.aiwg/{extensions,addons,frameworks,plugins}/<name>/manifest.json`:
- Unified `BundleManifestSchema` (Zod) — discriminated nested config (`addonConfig`, `frameworkConfig`, `extensionConfig`, `pluginConfig`)
- Strict validation rejects unknown top-level keys, enforces DoS limits (64 KB manifest, 200 bundles, 50 keywords, 20 overrides), supports `safety-critical` and `overrides` fields
- Symlinked bundle dirs refused unless `--allow-symlinks` (per threat model #1042)
- Case-insensitive id collisions within a type are refused
- Surfaced in `aiwg list` with `[project]` source label; `aiwg list --project-local` filters with per-type counts
Deploy via `aiwg use` (#1035)
`aiwg use sdlc` now deploys project-local bundles automatically alongside the upstream framework. `aiwg use <bundle-name>` deploys a single bundle. `--no-project-local` skips discovery entirely. Registry tracks `source: 'project-local'` with `localPath`, `localType`, `manifestVersion`, and (new in #1037) `artifactHashes`.
Override / shadow policy + safety-critical denylist (#1036)
Seven verdicts from ADR #1041:
1. No collision → deploy 2. Non-safety shadow → deploy + warn 3. Safety-critical + explicit `overrides:` → deploy + prominent warn 4. Safety-critical without `overrides:` → refuse (`--force` does not bypass) 5. Phantom override → refuse 6. Two project-local bundles export same artifact → refuse both 7. Git-installed (cache) shadow → same path as cases 2/3/4 against the cache
Remove + doctor + promote + activity log (#1037)
Implemented in five phases following the design contracts:
| Phase | Commit | What |
|---|---|---|
| 1 | `fb540d50` | Activity log helper + integration |
| 2 | `2f7e4508` | Project-local-aware `aiwg remove` (cases 1–6, `--force`, `--dry-run`, `--keep-registry`) |
| 3 | `d2a21f2b` | `aiwg doctor` project-local section (counts, validation, shadows, drift, matrix) |
| 4+5 | `ae96d2e2` | `aiwg promote` + test strategy update |
| Fix | `81ce265c` | Register `promoteCommand` in command definitions registry |
Scaffolding (#1050)
`aiwg new-bundle <name> [--type {extension|addon|framework|plugin}] [--starter {skill|rule|agent|minimal}]` creates a complete bundle in one command. Aliases (`new-extension`, `new-addon`, etc.) infer the type from invocation. Output validates against `BundleManifestSchema` out of the box.
Activity log
Every lifecycle event writes a single line to `.aiwg/activity.log`:
## [2026-05-02 19:45] deploy | deploy: my-bundle:extension | claude: agents=0 commands=0 skills=1 rules=1
## [2026-05-02 19:46] delete | remove: my-bundle:extension | claude=2 reverted
## [2026-05-02 19:47] promote | promote: my-bundle:extension | agentic/code/addons/my-bundle
12 design events: `discover`, `deploy`, `deploy-failed`, `conflict`, `shadow-acknowledged`, `shadow-refused`, `remove`, `remove-mutated`, `remove-conflict`, `remove-force`, `promote`, `promote-failed`. Writes are non-blocking (failures emit a stderr warning, never break the underlying op). Discover events deduplicate by `(name, type)` against the recent log tail.
Identical-form portability (ADR #1038)
The load-bearing design invariant: a project-local bundle is byte-identical in shape to its upstream form. This makes `aiwg promote` a hash-verified copy — no rewrite, no migration, no schema gymnastics. The same manifest shape works at:
- `.aiwg/extensions/<name>/` (project-local)
- `agentic/code/addons/<name>/` (upstream)
- `<corpus-path>/<name>/` (private corpus)
- A marketplace-packaged plugin payload
Moving between any of these is `cp -r` + SHA-256 verify.
Customization paths (Path A / B / C)
The customization guide restructured around three paths. Pick by what you're customizing and how you want to share it:
| Path | When | Effort |
|---|---|---|
| A — Project-local | Per-project rules, agents, skills | 5 minutes — no fork |
| B — Fork | Cross-project customization, contributing back, modifying AIWG core | 30 minutes — fork + dev mode |
| C — Corpus | Cross-project sharing without going public | One-time setup per corpus |
The three paths compose. A project on Path A can later promote to Path B or Path C; a fork (Path B) can deploy alongside Path A bundles cleanly; a corpus (Path C) is just another `source` in the registry.
See docs/customization/README.md for the full decision tree.
Documentation
A comprehensive doc refresh shipped alongside the implementation:
| Doc | What it covers |
|---|---|
| `docs/customization/README.md` | Path A / B / C overview + decision tree |
| `docs/customization/project-local-quickstart.md` | First bundle in 5 minutes |
| `docs/customization/project-local-lifecycle.md` | Full operator reference |
| `docs/customization/project-local-troubleshooting.md` | Common failures + fixes |
| `docs/customization/from-fork-to-project-local.md` | Migrate existing fork-based work |
| `docs/customization/extensions-vs-addons-vs-frameworks-vs-plugins.md` | Pick the right bundle type |
| `docs/cli-reference.md` | Updated entries for `new-bundle`, `promote`, `remove`, `doctor --project-local` |
| `examples/project-local/README.md` | Working example via `aiwg new-bundle` |
The old `docs/project-local/` directory (which documented a superseded `.aiwg/.project/` design) was replaced with redirect stubs pointing at the canonical docs above.
Architecture decisions
The epic produced eight new ADRs / design docs in `.aiwg/architecture/`:
| File | Issue |
|---|---|
| `adr-identical-form-portability.md` | #1038 |
| `adr-aiwg-directory-layout.md` | #1039 |
| `adr-unified-registry-shape.md` | #1040 |
| `adr-override-shadow-policy.md` | #1041 |
| `threat-model-project-local.md` | #1042 |
| `design-reference-resolution.md` | #1043 |
| `design-manifest-schema.md` | #1044 |
| `design-aiwg-remove-revert.md` | #1048 |
| `design-doctor-log-promote.md` | #1049 |
Test coverage
The 2026.5.0 work added 33 new unit tests across 4 new test files for the project-local lifecycle, plus integration and UAT coverage:
| File | Tests | Coverage |
|---|---|---|
| `test/unit/extensions/project-local-activity.test.ts` | 6 | Activity log helper + dedupe + non-blocking writes |
| `test/unit/extensions/project-local-remove.test.ts` | 15 | Cases 1–6 from #1048 design |
| `test/unit/extensions/project-local-doctor.test.ts` | 8 | DC-1: counts, validation, drift, quiet mode, matrix |
| `test/unit/extensions/project-local-promote.test.ts` | 10 | PR-1..PR-5: bundle-not-found, dry-run, copy+verify, destination-exists, project-local @-refs |
| `test/unit/extensions/project-local-scaffold.test.ts` | 11 | All four types, all four starters, validation, refuse-on-exists |
| `test/unit/extensions/project-local.test.ts` | 9 | Cross-cutting matrix (D-8 path-traversal, D-9 unicode, C-2 three-way, C-3 cross-type) |
| `test/integration/project-local-deploy.test.ts` | 6 | Real `deploy-agents.mjs` against synthesized bundles |
| `test/uat/project-local-flow.uat.ts` | 2 | End-to-end round-trip + safety-critical shadow refusal |
Plus the full test matrix mapping in `.aiwg/testing/test-strategy-project-local.md`.
Migration notes
From v2026.4.x
No breaking changes. Existing `aiwg use` and `aiwg remove` invocations work unchanged — project-local awareness is additive.
The two surfaces that gained behavior:
1. `aiwg use` now auto-discovers `.aiwg/{extensions,addons,frameworks,plugins}/<name>/` bundles after the upstream deploy. Pass `--no-project-local` to skip. 2. `aiwg remove <name>` now routes to a project-local handler when `<name>` matches a project-local entry in `aiwg.config.installed`. Otherwise falls through to the existing plugin-uninstaller.
Upgrading an existing project to take advantage
npm install -g [email protected]
aiwg refresh # re-deploy with project-local discovery enabled
aiwg new-bundle my-team-rules --type extension --starter rule
# edit the bundle, then:
aiwg use my-team-rules
aiwg doctor --project-local
Operators currently maintaining a fork
See `docs/customization/from-fork-to-project-local.md` for the per-category migration guide. Common case: rules / skills / agents move to project-local; AIWG core changes stay in the fork.
Late-cycle additions
Two user-reported issues landed in the rc.10 cut and ship in 2026.5.0:
- `#107` — Claude `settings.json` hooks field shape. The hook installer (and the CLI extension hook auto-registration from `#480`) wrote `hooks` as an array of `{matcher, hooks}` objects. Claude Code requires an object keyed by event name with matcher-group arrays as values, and `/doctor` was flagging the array shape: `"hooks" must be an object mapping event names to matcher arrays; received array. This field was ignored.` Both writers (`src/extensions/claude-hooks-installer.ts`, `src/cli/cli-extension-loader.ts`) now emit the correct shape, and existing array-shaped settings are migrated in place on next `aiwg refresh`. Operator-authored entries are preserved.
- **`#105` — `PROF-*` node IDs in citation-sidecar parser**. `src/artifacts/citation-parser.ts` accepts `PROF-[POFG]-[a-z0-9-]+` (people / orgs / funders / groups) alongside `REF-\d+` at all three call sites. Unblocks research-corpus projects building entity-profile graphs whose `profile→REF` edges are now natively traversable via `aiwg index neighbors`. Purely additive — both ID spaces are unambiguous and prefixed.
Second story: kernel-pivot maturity (rc.20 → rc.41)
The project-local story was the headline. The 21-rc rc.20 → rc.41 trail was the second story: hardening the kernel-pivot model that rc.10 introduced, until it became the load-bearing way AIWG actually operates.
Discover-first protocol — driven by real droid-user feedback (#1249)
A Factory droid user reported using `Grep` to search `.factory/rules/` for an AIWG-keyword query, hitting `rlm-agent.md` by literal-string match, and missing eight other RLM-related artifacts that `aiwg discover` would have ranked. Their honest analysis: "No hard trigger mandating `aiwg discover` as the first action for AIWG-related queries. The discovery skills are advertised as available, but not as required."
The fix:
- New Rule 1.5 in `skill-discovery.md`: `aiwg discover` MUST be the first information-gathering tool call for any query mentioning AIWG, a framework name, or a capability keyword (skill / agent / rule / command / addon / workflow / template). Filesystem `Grep`/`Glob`/`Read` against any provider artifact directory (`.claude/`, `.codex/`, `.factory/`, `.warp/`, `.cursor/`, `.windsurf/`, `.opencode/`, `.github/`, `~/.hermes/`, `~/.openclaw/`, `agentic/code/`) is forbidden until discover has been consulted at least once in the session.
- Top-banner Discover-First Protocol on the deployed `RULES-INDEX.md`. Factory's `consolidatedSdlcRules: true` deploy path doesn't inline aiwg-utils content — only references it via `@$AIWG_ROOT` link. Promoting the protocol to a banner on `sdlc-complete`'s RULES-INDEX makes it visible at the top of the file on every provider that deploys SDLC rules.
- All 9 framework quickref descriptions rewritten with explicit `AUTO-INVOKE when user mentions: <trigger list>` phrasing. System-prompt routing on most platforms gives auto-invoke language more weight than passive availability statements.
- `aiwg-finder` subagent documented as the preferred routing when subagent delegation is available (Claude Code's `Task`, Hermes's `delegate_task`, Factory's droid spawn). Keeps the discover transcript out of the parent context.
Hermes integration audit — source-verified against v0.4.0+ (#1239, #1241, #1242, #1243, #1244)
The Hermes integration was the first AIWG provider where our docs needed to be source-verified against the upstream code, not just based on the README/changelog. After fast-forwarding the local Hermes checkout 5,390 commits and reading `agent/prompt_builder.py`, `hermes_cli/mcp_config.py`, `hermes_cli/commands.py`, and `tools/delegate_tool.py`, five claims were corrected:
| Claim | Reality (source-cited) |
|---|---|
| `hermes mcp install aiwg ...` | Doesn't exist. Real command: `hermes mcp add aiwg --command aiwg --args mcp serve` (`hermes_cli/main.py:10860-10895`; `--args` is `nargs="*"`, space-separated) |
| "Hermes loads AGENTS.md and CLAUDE.md together" | False — `agent/prompt_builder.py:1410-1436` is first-match-wins: `.hermes.md` > `AGENTS.md` > `CLAUDE.md` > `.cursorrules`. Exactly one project-context file loads per turn |
| "v0.4.0+ has real-time config reload" | Partially false — config reload is operator-driven via `/reload-mcp` slash command (`hermes_cli/config.py:1228` `mcp_reload_confirm` flag) |
| Session reload via chat restart | `/reload-skills` and `/reload-mcp` are in-session slash commands (`hermes_cli/commands.py:178`). No chat restart needed |
| `CONTEXT_FILE_MAX_CHARS` undocumented | 20,000-char cap per source with head/tail truncation (`agent/prompt_builder.py:1284`) |
Concrete deliverables shipped:
- AGENTS.md is now a 579-byte thin pointer (was 30 KB+ on a typical SDLC deploy) referencing `AIWG.md` and `aiwg discover` / `aiwg show`. Eliminates four warning classes across all 10 AGENTS.md providers (auto-split, spillover, approaches-cap, per-entry sanitizer-rejection).
- `.hermes.md` twin file diverges from AGENTS.md with a Hermes-MCP-specific suffix pointing readers at `artifact-read`, `aiwg discover/show`, and `delegate_task` instead of the dead-end AIWG.md link (Hermes doesn't auto-load AIWG.md).
- `aiwg-orchestrate` skill auto-installs to `~/.hermes/skills/` on first deploy. Idempotent on rerun — operator edits preserved. Provides ~95% per-workflow context reduction via `delegate_task`.
- Hermes Capabilities Reference in the quickstart catalogs 10 capabilities (`/kanban`, `/handoff`, ACP adapter, `/agents`, `/goal`, `/cron`, `/snapshot`, `/background`, gateway platforms, plugin system) with file:line citations and AIWG composition notes.
- Steward agent gained a "Hermes Composition Reference" routing table for operator-level integration questions.
Per-platform session reload notice (#1240)
Every `aiwg use` now ends with a "Session reload required:" section that names the action, rationale, and consequence per provider — covering all 10 platforms (claude, codex, copilot, cursor, warp, windsurf, factory, opencode, hermes, openclaw). The notice diagnoses the "Agent type 'X' not found" symptom that occurs when a running session predates the most recent deploy.
The Steward agent's Post-Deploy Session Reload table makes this triage rule explicit: when a user reports "Agent type not found" for an agent that exists on disk, the first move is to check whether their session predates the most recent `aiwg use` and instruct them to reload accordingly.
`aiwg-regenerate` promoted to kernel skill (#1245)
The kernel set grew from 9 to 10 self-maintenance ops (`steward`, `aiwg-doctor`, `aiwg-refresh`, `aiwg-status`, `aiwg-help`, `use`, plus the new `aiwg-regenerate`). Natural-language invocation works for "regenerate my CLAUDE.md" without an `aiwg discover` round-trip. Per-provider variants (`aiwg-regenerate-claude`, `aiwg-regenerate-codex`, etc.) stay non-kernel — the umbrella delegates to them.
Publish pipeline fixes (#1246, #1247)
After rc.27, Gitea Release objects stopped being auto-created and public npmjs.org publishes stopped landing — but CI reported green. Two silent-failure bugs:
- `.gitea/workflows/gitea-release.yml`: doubly-escaped inline JSON body returned `"[]: json: string unexpected end of JSON input"` from Gitea, swallowed by `|| echo "Release may already exist"`. Rewritten with `jq -n` JSON construction + explicit HTTP-code handling (201/200 = created, 409 = already exists, anything else = `exit 1`).
- `.gitea/workflows/npm-publish.yml`: `npm publish ... 2>&1 | tee ...` returned `tee`'s exit code (always 0) without `set -o pipefail`. Added `defaults.run.shell: bash` at the job level, `set -o pipefail` to all four publish steps, and refined error-pattern allowlist (drops spurious 403 match).
`NPMJS_TOKEN` rotation by the operator closed the loop. Every rc tag from rc.38 forward actually creates a Gitea Release and publishes to public npmjs.org.
Architecture overview docs (#1248)
A new canonical `docs/architecture-overview.md` lands with 8 mermaid diagrams giving the visual mental model:
1. AIWG is a deploy-time tool — runtime-invisible 2. Two-tier skill model — kernel vs standard 3. Discover → show flow (the optional layer) 4. What's optional — Minimal vs Standard vs Full 5. The `.aiwg/` lifecycle 6. Hermes context-file priority (first-match-wins) 7. Multi-platform deploy — one source, ten targets 8. Session reload after `aiwg use`
Cross-linked from `docs/how-it-works.md`, `docs/discovery-and-kernel-skills.md`, `docs/integrations/hermes-quickstart.md`, and the README. Image placeholders at `docs/architecture-overview/images/` ready for polished Gemini-generated illustrations — three prompt-set aesthetics (illustrated computing iconography, monospace/terminal, editorial) catalogued on issue #1248 for whatever channel needs them.
Acknowledgements
The 2026.5.0 work was scoped in epic #1033 with companion issues #1034–#1037 (implementation), #1038–#1044 (decisions), #1045–#1052 (parallel design / docs / test). All children resolved.
Late-cycle bug reports from `@sebuh-infsol` (#107) and the research-papers downstream consumer audit (#105).
Install
# Pre-release (current)
npm install -g aiwg@next # latest 2026.5.0-rc.X
# Stable (when cut)
npm install -g aiwg # latest stable
Or use the Claude Code plugin:
/plugin marketplace add jmagly/ai-writing-guide
/plugin install sdlc@aiwg
Reference
- Customization README — Path A / B / C
- Project-local quickstart
- CLI reference
- CHANGELOG entry
- Epic #1033 — full child issue list