Immutable. This exact content is served forever at /api/v1/blob/5cc3dfb622e989dc.
# CLAUDE.md — ARIA ## What This Is ARIA (Applied Reasoning and Insight Architecture) — an active knowledge and development discipline plugin for Claude Code. Three pillars: a five-phase knowledge lifecycle (capture → govern → promote → apply → refresh), decision discipline (Rule 22 enforcement at every edit), and codebase & task mapping (/codemap for repo traces, /stitch for cross-repo contract binding, /distill for task spec shaping). The "Applied" framing emphasizes the apply phase: trusted knowledge actively shapes the next decision via /context, /rules, /codemap, /stitch, /distill, and Rule 22 — not just stored and recalled. **Repository:** GitHub (`mikeprasad/aria-knowledge`) — **public repo** ## Cowork Port (plugin-claude-cowork/) The Claude Cowork port lives at `plugin-claude-cowork/` — consolidated into this repo in v2.20.0 (2026-05-24) from the previously standalone `mikeprasad/aria-cowork` (last standalone release: v1.1.0, 2026-05-19). **Current cowork release: v1.7.0** (2026-08-19, with aria-knowledge v2.46.3 — `/intake` absorbs `/clip`+`/clip-thread`+`/extract-doc` (breaking), `/audit-knowledge` gains Step 2f, `/interview` defaults to `guided`, working-rules preamble + `retrospect-patterns.md` land; 27 → 24 skills; tag `cowork-v1.7.0`, NOT marked Latest so the canonical release keeps the 6 stable aliases). Prior: v1.5.0 (2026-06-29, with aria-knowledge v2.38.0 — working-rules synced to canonical parity: added Rules 35/36/37, strengthened Rules 15/21; working-rules.md 34 → 37 rules; no skill change). Prior: v1.4.0 (2026-06-18, with aria-knowledge v2.31.0 — `/interview` skill ported, cowork-adapted; the one genuine parity gap with canonical v2.31.0, closed; summed-description cap-relief trim included). Prior: v1.3.0 (2026-06-11, with aria-knowledge v2.30.0 — `/foundational-review` + `/readiness-audit` ported; 2 audit aliases removed for cap relief). Prior: v1.2.0 (2026-06-10, with aria-knowledge v2.28.0 — `snap` mode parity; tag `cowork-v1.2.0` + GH release w/ `.plugin` asset). Prior: v1.1.5 (2026-06-04, with aria-knowledge ~v2.24.x — `/index` ephemeral-tag exclusion + `/wrapup` picker fix). Prior: v1.1.4 (2026-05-29, with aria-knowledge v2.20.3 — Opus 4.8 readiness: `working-rules.md` `Why` clause de-versioned, mirroring plugin-claude-code; Cowork is skills-only so the v2.20.3 hook hardening does not apply here). Prior coordinated cowork release: v1.1.3 (2026-05-25, with aria-knowledge v2.20.2 — wrapup/handoff spec fixes: closing-heading labeling correction + auto-mode extract-always-runs invariant). Both ports share the user's `~/Projects/knowledge/` folder and write to the same canonical config (`aria-config.md`) under an additive-only schema (per ADR-002). Edits to shared surfaces — `aria-config.md` field names, `template/rules/` content, `working-rules.md` rule numbering — must preserve cross-port compatibility. 27 skills (27 distinct; v1.3.0 removed the 2 aliases, v1.4.0 added `/interview`). Cowork-specific authoring constraints documented in `knowledge/guides/claude/cowork-plugin-validation.md`. **Cowork-specific release constraint**: aria-cowork release.sh enforces a 9000-char hard cap on summed SKILL.md description chars (empirical install-fail at 9233, documented v0.2.1 + v1.0.0); v2.20.1's trailing-parenthetical port-id uses a short form on cowork (`(Cowork variant — namespaced-only.)` ~36 chars) versus Code's verbose form (~96 chars), with the full ADR-094 narrative in the Runtime Gate body where no cap applies. **Bidirectional feature flow (since v0.3.0 / v2.17.0):** Features may originate in either port and port to the other; plugin-claude-code remains the schema source-of-truth (output formats, knowledge-folder conventions, archive structures). v0.3.0's `/handoff brief` and `/intake doc` modes are the first cowork-originated features ported into aria-knowledge. See plugin-claude-cowork ADR-014 for the architectural rationale. **Bare-slash ownership (ADR-094, v2.19.1):** When both ports are loaded in the same session (most common in Claude Desktop), 24 colliding skill names (`/handoff`, `/wrapup`, `/extract`, `/intake`, etc.) deterministically resolve to **plugin-claude-code** as canonical owner. plugin-claude-cowork's variants are namespaced-only (`/aria-cowork:handoff`, etc.). Each colliding skill carries a Runtime Gate in its body that surfaces a notification when invoked from the wrong runtime (Bash-availability is the fingerprint). The gate applies even in `auto` modes — auto's "implicit-yes" rule is suspended for the runtime-mismatch check per ADR-094 §Part 3. Edits affecting cross-port compatibility (description prepend conventions, gate clause text, anti-trigger language) should preserve this ownership rule. Full design: [`~/Projects/knowledge/projects/aria/decisions/094-bare-slash-canonical-owner-and-dual-runtime-gate.md`](../../knowledge/projects/aria/decisions/094-bare-slash-canonical-owner-and-dual-runtime-gate.md). ## Cursor Port (plugin-cursor-template/) The Cursor port is a **repo skeleton** (not a Claude marketplace plugin). Users unzip `aria-knowledge-cursor-<version>.zip` into the root of their own project. **Current Cursor release: `2.46.2-cursor.0`** (2026-08-19, parity with plugin-claude-code v2.46.2; `.mdc` verified by recompiling `port-skills-to-mdc.py` and reproducing the committed files byte-for-byte). Prior: `2.30.0-cursor.0` (2026-06-11, parity with v2.30.0). Prior: `2.24.2-cursor.0` (2026-06-04, statusline-only alignment). **What ships:** `.cursor/hooks.json`, `.cursor/rules/*.mdc` (5 compiled rule files), `.cursor/aria-knowledge.local.md`, root `AGENTS.md` (Cursor's equivalent of `CLAUDE.md`), `scripts/aria/*.sh`, and a root-level `knowledge/` mirror of `plugin-claude-code/template/`. **Skill surface (27 commands in `aria-commands.mdc` + audits in `aria-audit.mdc`):** 22 core workflow commands + 3 aliases (documented in preambles) + 5 MCP-consuming skills (`/clip-thread`, `/extract-doc`, `/meeting-notes`, `/digest`, `/sync-decisions`) + `/help` + `/audit-share`. Includes v2.17.0 `/intake doc`, v2.20.2 wrapup/handoff auto-mode `/extract` invariants. **Intentional Cursor divergences (do not port ADR-094 Runtime Gates per-skill):** aria-cowork is not loaded in typical Cursor sessions. A single preamble note in `aria-commands.mdc` replaces per-skill gates. Rule 22 uses an edit-intent marker (`record-edit-intent.sh`) — advisory `beforeFileEdit`, no transcript proof. No PreCompact; `stop` → `capture-task-boundary.sh` substitutes. MCP servers are user-configured in **Cursor Settings → MCP** (no bundled `.mcp.json` in the template). See `plugin-cursor-template/PORTING.md` and `plugin-cursor-template/audit/ARIA_CURSOR_AUDIT_REPORT.md` §5. **Maintainer re-sync after canonical skill edits:** ```bash python3 plugin-cursor-template/scripts/port-skills-to-mdc.py ./release-cursor.sh ``` `port-skills-to-mdc.py` strips Runtime Gate blocks, adapts paths (`AGENTS.md`, `.cursor/aria-knowledge.local.md`), and upserts MCP skill sections idempotently. ## Codex Port (plugin-openai-codex/) The OpenAI Codex port lives at `plugin-openai-codex/` — an independent installable adapter that uses the shared ARIA knowledge folder and content schema while diverging on plugin manifest shape, hook registration, and tool-boundary behavior for Codex. **Current Codex release: `2.46.4-codex.0`** (2026-08-20; content parity with canonical, port suite 24/24. ⛔ Three canonical `post-*-check.sh` scripts were shipped here unwired and are REMOVED — Codex routes every hook through `bin/codex-hook.py`, which already inlines them as `tautology_message()`, `auto_prospect_message()` and `auto_retrospect_message()`. Do NOT re-copy them on a parity sync; see `PORTING.md`.) Prior: `2.30.0-codex.0` (2026-06-11, parity with v2.30.0 where Codex has an equivalent runtime surface). Wires MCP servers via `.mcp.json` (Codex manifest convention uses `mcp_servers` snake_case key vs. Claude's `mcpServers` camelCase — both are correct for their target runtime). Strips ADR-094 Runtime Gate sections from ported skills (gates are Bash-availability-fingerprint-dependent and don't fire in Codex). Ships `/foundational-review` + `/readiness-audit` with the bundled canonical process doc; keeps `/statusline` and `/aria-assist` as explicit non-equivalents for now (no Codex statusline/usage payload, no bundled launchd/headless scheduler path). Ships a port-specific test suite at `plugin-openai-codex/tests/run.sh` that release-codex.sh gates on (skills carry codex metadata, no ADR-094 gates leaked through, review skills present, `apply_patch` denial shape current, transcript reader doesn't scan without `turn_id`). **Build with** `./release-codex.sh` from repo root. Reads version from `plugin-openai-codex/.codex-plugin/plugin.json` (single source of truth, strips `-codex.N` suffix for filename). Produces `aria-knowledge-codex-<canonical>.zip` + version-stable `aria-knowledge-codex.zip`. Verification gates: Codex port tests, port-drift report-only gate, MCP manifest present, `tests/` excluded from artifact, no junk, clean zip rebuild before archive creation. ## Antigravity Port (plugin-antigravity/) The Antigravity IDE port lives at `plugin-antigravity/` — targets **Antigravity IDE** (VS Code fork) and **Antigravity CLI** (`agy`) from Google's Antigravity team. **Current Antigravity release: `2.46.2`** (2026-08-18, parity with plugin-claude-code v2.46.2; skill set identical to canonical's 36). Prior: `2.20.2` (2026-05-28, parity with v2.20.2; same-day refresh added native workflow + rules scaffolding and expanded plugin.json — commit `f635e61`). The setup skill's **Step 7ca** scaffolds `.agents/workflows/` (10 thin-shim workflows) and `.agents/rules/aria-rules.md` into the user's workspace, enabling **true native slash-command invocation** (`/setup`, `/handoff`, `/wrapup`, `/extract` fire as first-class Antigravity workflows) and **native Always-On rule enforcement** — distinct from Claude Code's hook-based enforcement model. **Version sources (two, kept in sync by the maintainer):** `plugin-antigravity/plugin.json` carries the full standard plugin manifest including a `version` field (Antigravity's manifest schema ignores unknown fields, and the standard plugin shape is now used here for parity with sibling ports). `plugin-antigravity/version.txt` is a sidecar that `build.sh` auto-syncs from canonical `plugin-claude-code/.claude-plugin/plugin.json` — `bin/` scripts and the setup skill read from the sidecar. **Maintainer responsibility:** when bumping canonical version, also hand-bump `plugin-antigravity/plugin.json`'s `version` field. `build.sh` auto-syncs `version.txt` but does NOT touch `plugin.json` (it's in the preserved hand-authored files list per `build.sh` line 284). Candidate for `build.sh` automation later — flag as follow-up if the manual two-step becomes a friction point. **Custom setup behavior is preserved via the overlay pattern.** `build.sh` (lines 120-145) copies canonical skills from `plugin-claude-code/skills/`, then applies `plugin-antigravity/overlays/skills/<name>/SKILL.md` overlays LAST — so port-specific bodies survive canonical resyncs. ⛔ **CORRECTED 2026-08-26 — this said "the setup skill currently has an overlay snapshot at `plugin-antigravity/overlays/skills/setup/SKILL.md` (byte-identical to the live file)". That file DOES NOT EXIST and there is no evidence it ever did.** Measured: `overlays/skills/` holds exactly three entries — `audit-config`, `audit-knowledge`, `snapshot`. So canonical's `setup/SKILL.md` flows straight through to this port with only the uniform path substitution applied, and there is no port-specific setup body to protect. ⚠ **Why that false claim mattered, and it is not a trivia correction.** It reads as "antigravity's setup is insulated from canonical", which is the opposite of true, and it was load-bearing while adding a Claude-Code-only step to canonical `/setup`: the natural fix looked like "edit the overlay", and there was none to edit. Creating one would have frozen antigravity's setup against every future canonical change — and its own drift detection is admitted future-work. The step was instead made **self-gating** on hook registration, which needs no overlay and is correct in every port. **Do not restore the overlay claim, and prefer a self-gating canonical step over a new overlay** unless a port genuinely needs a divergent body. **Two-script model** (different from sibling ports' one-script model): 1. `plugin-antigravity/build.sh` — *regenerates* port content from canonical sources (copies skills from `plugin-claude-code/skills/`, applies overlays from `plugin-antigravity/overlays/`, syncs `version.txt`, patches setup/SKILL.md paths). Run when canonical sources change. 2. `release-antigravity.sh` (at repo root) — stages regenerated port content with junk exclusions and emits `aria-knowledge-antigravity-<version>.zip` + version-stable copy. **Zip structure is flat (no top-level wrapper dir).** This differs from claude-code/codex/cursor zips which nest content under a plugin-name wrapper, matching Antigravity IDE's install machinery. `release-antigravity.sh` verifies this invariant (`wrapper` count must be 0). ## Project Structure ``` aria/ ├── README.md ← GitHub-facing intro ├── LICENSE ← CC BY-NC-SA 4.0 ├── CHANGELOG.md ← Version history ├── CLAUDE.md ← You are here ├── plugin-claude-code/ ← The installable plugin │ ├── .claude-plugin/ │ │ └── plugin.json │ ├── bin/ ← Hook scripts (bash) │ ├── skills/ ← Skill definitions (SKILL.md files) │ └── template/ ← Knowledge folder templates ├── plugin-openai-codex/ ← Codex port (independent installable unit) │ ├── .codex-plugin/ │ │ └── plugin.json │ ├── hooks.json ← Codex hook registration │ ├── bin/ ← Claude-standard scripts + Codex adapter │ ├── commands/ ← Codex command entrypoints │ ├── skills/ ← Copied ARIA skills (schema-compatible) │ └── template/ ← Copied Claude-standard knowledge templates ├── plugin-claude-cowork/ ← Cowork port (skills-only; no hooks API in Cowork runtime) │ ├── .claude-plugin/ │ │ └── plugin.json │ ├── skills/ ← 26 skills (24 distinct + 2 aliases) │ ├── template/ ← Knowledge folder templates (schema mirror of plugin-claude-code/) │ ├── .mcp.json ← 12 MCP servers across 4 categories │ └── release.sh ← Builds aria-cowork-<version>.plugin ├── plugin-cursor-template/ ← Cursor port (repo-skeleton, not a plugin install) │ ├── .cursor/ ← Cursor-native config │ │ ├── hooks.json │ │ ├── aria-knowledge.local.md │ │ └── rules/ ← 5 compiled .mdc files (27 commands in aria-commands + audits) │ ├── AGENTS.md ← Cursor's equivalent of CLAUDE.md (ships to user projects) │ ├── QUICKSTART.md ← Cursor-adapted quickstart │ ├── PORTING.md ← Maintainer drift tracking + skill→.mdc map │ ├── knowledge/ ← Knowledge folder (hoisted to root, not under template/) │ ├── scripts/aria/ ← Hook scripts (instead of bin/) │ │ └── VERSION ← Port version (e.g. 2.20.2-cursor.0) │ ├── scripts/port-skills-to-mdc.py ← Re-sync from plugin-claude-code/skills/ │ └── audit/ ← Frozen audit artifacts (2.16.1 baseline; see PORTING.md for current) ├── plugin-antigravity/ ← Antigravity IDE / CLI port (flat-zip install) │ ├── plugin.json ← Manifest (no version field per Antigravity docs) │ ├── version.txt ← Port version sidecar (source of truth — synced by build.sh) │ ├── mcp_config.json │ ├── hooks.json │ ├── bin/ ← Canonical bin scripts + Antigravity adapter (bin/antigravity/) │ ├── skills/ ← Regenerated from canonical via build.sh │ ├── template/ ← Regenerated from canonical via build.sh │ ├── overlays/ ← Per-skill overrides applied by build.sh │ ├── build.sh ← Regenerates port content from canonical sources │ └── tests/ ← Port test suite (smoke + structural) ├── RELEASING.md ← Build→publish flow + stable-alias asset contract (read before cutting a release) ├── publish-release.sh ← Attaches all 6 stable aliases to the canonical release so site /latest/ links resolve ├── release.sh ← Builds claude-code zip (canonical) ├── release-codex.sh ← Builds codex zip ├── release-cursor.sh ← Builds cursor zip ├── release-antigravity.sh ← Builds antigravity zip (flat layout) └── docs/ ← Extended documentation (future) ``` ## Key Conventions - **`plugin-claude-code/` is the installable unit** — everything inside it is what users copy to their plugins directory - **`plugin-openai-codex/` is the Codex installable unit** — independent adapter surface, same knowledge schema. Claude `plugin-claude-code/` remains the standard for template/content shape. - **`plugin-cursor-template/` is the Cursor repo-skeleton** — not a plugin install. Users clone or unzip its contents into the root of their own project. Cursor compiles 29 commands (24 core + 5 MCP) into 5 `.cursor/rules/*.mdc` files because Cursor's Rules system doesn't have a one-skill-per-folder concept. Port version tracks canonical via `scripts/aria/VERSION` (currently `2.30.0-cursor.0`). Maintainer re-sync: `python3 plugin-cursor-template/scripts/port-skills-to-mdc.py`. ADR-094 Runtime Gates are omitted in Cursor. Knowledge folder schema stays compatible with `plugin-claude-code/template/`. - **Template files** in `plugin-claude-code/template/` are either plugin-managed (diffable on `/setup`) or user-owned (created once, never overwritten). See `plugin-claude-code/skills/setup/SKILL.md` for the authoritative list. - **Version** lives in `plugin-claude-code/.claude-plugin/plugin.json` - **Hook scripts** in `plugin-claude-code/bin/` are bash — they read config from `~/.claude/aria-knowledge.local.md` - **Skills** are markdown files — each skill is a `SKILL.md` with YAML frontmatter - **Codex hooks** require Codex `plugin_hooks` enabled; the adapter reads `~/.codex/aria-knowledge.local.md` first, then falls back to `~/.claude/aria-knowledge.local.md` - **`plugin-claude-cowork/` is the Claude Cowork installable unit** — sibling to plugin-claude-code/, both share schema-identical knowledge-folder outputs (per ADR-013). Cowork runtime is skills-only (no hooks API); enforcement is skill-embedded. Per ADR-094, bare-slash skill names resolve to plugin-claude-code as canonical owner when both ports are loaded in the same session; cowork-namespaced variants are `/aria-cowork:handoff` etc. - **Cursor hooks** use `.cursor/hooks.json` and resolve script paths via `git rev-parse --show-toplevel`. Some Claude enforcement is weaker on Cursor (no transcript access, no documented pre-edit deny) — port uses an edit-intent marker file as the closest available mechanism. See `plugin-cursor-template/audit/ARIA_CURSOR_AUDIT_REPORT.md` §5. - **`plugin-antigravity/` is the Antigravity IDE/CLI installable unit** — independent port targeting Google's Antigravity IDE (VS Code fork) and `agy` CLI. **Two version sources**: `plugin.json` carries the standard plugin manifest including `version` (Antigravity ignores unknown manifest fields); `version.txt` sidecar is auto-synced by `build.sh` from canonical and read by `bin/` scripts. Maintainer must hand-bump `plugin.json` on canonical bumps (`build.sh` preserves it). Two-script build model: `plugin-antigravity/build.sh` regenerates port content from canonical sources + applies overlays at `overlays/skills/<name>/SKILL.md`; `release-antigravity.sh` (repo root) zips. Zip layout is **flat** (no top-level wrapper dir) vs. sibling ports' wrapped layout. Setup skill's **Step 7ca** scaffolds Antigravity-native `.agents/workflows/` + `.agents/rules/` so slash commands fire as first-class workflows. ## Development Workflow 1. Edit files in `plugin-claude-code/` 2. To test, copy `plugin-claude-code/` to `~/.claude/plugins/marketplaces/local-desktop-app-uploads/aria-knowledge/` 3. Restart Claude Code to pick up changes ### Codex Port Workflow 1. Edit Codex adapter files in `plugin-openai-codex/` 2. Keep durable knowledge template/schema changes in sync with `plugin-claude-code/` — Claude remains the schema standard 3. Enable Codex plugin hooks with `codex features enable plugin_hooks` before testing automatic hooks 4. Install via `.agents/plugins/marketplace.json` or copy `plugin-openai-codex/` into a Codex local marketplace ### Cursor Port Workflow 1. Edit canonical skills in `plugin-claude-code/skills/` first (schema source-of-truth), then re-sync the Cursor port: ```bash python3 plugin-cursor-template/scripts/port-skills-to-mdc.py ``` 2. Keep durable knowledge surfaces in sync with `plugin-claude-code/template/` — apply the same edits to `plugin-cursor-template/knowledge/` (root-level, not nested under `template/`). See `plugin-cursor-template/PORTING.md` §A for the lockstep file list. 3. The 5 `.mdc` rule files are *compiled* views of canonical `SKILL.md` bodies. `port-skills-to-mdc.py` refreshes `aria-commands.mdc` (core + MCP skills, wrapup/handoff patches, `/help` table) and strips ADR-094 Runtime Gates. Hand-edit `aria-audit.mdc`, `aria-context.mdc`, `aria-core.mdc`, or `aria-rule-22.mdc` when those surfaces change outside the scripted path. 4. Bump `plugin-cursor-template/scripts/aria/VERSION` (`<canonical>-cursor.0`) and run `./release-cursor.sh` from repo root. Zip: `aria-knowledge-cursor-<canonical>.zip`. 5. Users install by unzipping the artifact into the root of their own project, then restarting Cursor. End-user doc: `plugin-cursor-template/QUICKSTART.md`; project instructions file: `AGENTS.md` (not repo-root `CLAUDE.md`). ### Cowork Port Workflow 1. Edit Cowork-specific files in `plugin-claude-cowork/`. Most skills mirror `plugin-claude-code/` via ADR-013 schema-identical outputs; cowork-specific skills (`daily-audit`, cowork-modified `/extract-doc`, etc.) live only here. 2. Keep MCP-consuming skills (clip-thread, extract-doc, meeting-notes, digest, sync-decisions) byte-faithful between ports per ADR-014; plugin-claude-code remains schema source-of-truth. 3. Per ADR-094, when both ports load in the same session, bare-slash command names (`/handoff`, `/extract`, etc.) resolve to plugin-claude-code as canonical owner; cowork-namespaced variants are `/aria-cowork:handoff` etc. 4. Build with `./release.sh` in `plugin-claude-cowork/` — produces `aria-cowork-<version>.plugin`. Install by dragging into a Cowork conversation or via Settings → Plugins → Install from file. 5. Cowork runs as a skills-only plugin (no hooks API). The `/daily-audit` skill substitutes for SessionStart on first message. ### Antigravity Port Workflow 1. Edit canonical skills in `plugin-claude-code/skills/` first (schema source-of-truth). For Antigravity-specific adapter behavior, edit hand-authored files preserved by build.sh: `plugin.json`, `hooks.json`, `mcp_config.json`, `GEMINI.md`, `bin/antigravity/*`, `PORTING.md`, `README.md`, `SMOKE-TEST.md`. Place per-skill overrides in `plugin-antigravity/overlays/`. 2. Regenerate port content from canonical sources: ```bash ./plugin-antigravity/build.sh ``` This copies skills/template from `plugin-claude-code/`, applies overlays, syncs `version.txt` from the canonical `plugin.json` version, and patches setup/SKILL.md to read version from the sidecar instead of JSON. 3. Bump `plugin-claude-code/.claude-plugin/plugin.json` version first (canonical), then re-run `build.sh` — `version.txt` syncs automatically. **Also hand-bump `plugin-antigravity/plugin.json`'s `version` field** — it's in build.sh's preserved hand-authored files list (line 284) and won't be touched automatically. Forgetting this creates silent drift between `version.txt` and `plugin.json`. 4. Build the release zip from repo root: ```bash ./release-antigravity.sh ``` Produces `aria-knowledge-antigravity-<version>.zip` (flat layout) + version-stable `aria-knowledge-antigravity.zip`. Verification gates: `plugin.json` present, `version.txt` present, no top-level wrapper dir, no junk. 5. Users install per Antigravity IDE / CLI conventions; see `plugin-antigravity/README.md` and `plugin-antigravity/SMOKE-TEST.md`. ## Rules - Follow the universal rules in `Projects/CLAUDE.md` - **This is a public repository** — never commit personal information, API keys, secrets, credentials, internal URLs, or any sensitive data. Content here is visible to anyone on GitHub. - **That rule is now mechanically enforced — `release.sh` Gate D (`plugin-claude-code/bin/check-public-hygiene.sh`, added 2026-08-25) is FATAL.** It fails a release when a private project identifier appears in **tracked** content. Why it exists: a repo-wide census that day found **113 occurrences across 35 files in all five ports** — client project directory names, a private domain with its file count, design-system artifact names inside the shipped Rule 22 template, and a portfolio inventory with per-repo commit counts. None malicious; every one entered as a worked example in a design doc or test fixture, and nothing connected "internal name" to "public artifact". ⛔ **Exit 2 means the gate's own self-test failed — that is NOT a clean result** and `release.sh` dies distinctly on it. ⚠ **Its bound, stated in its header: it detects the identifiers in its TERMS/CODES/ARTIFACTS lists, so a NEW client project is invisible until added there — add it when one appears.** Placeholders this repo uses: `proj-a` / `proj-b` / `proj-c`. ⚑ Three instrument lessons are baked in because each cost a re-census: patterns are **boundary-anchored** (an unanchored two-letter code plus a slash also matches the tail of `docs/` — 499 of those here). ⚑ Note this bullet cannot quote the banned forms literally: the gate scans every tracked file, so a specimen written here is itself a finding — which is how this very line first failed the gate, the scan is **case-insensitive** (the last real leak referenced two private projects by their UPPERCASE initials, which every case-sensitive sweep before it missed), and it scans **tracked files only** (an untracked scratch tree produced ten hits that could never ship, which is the noise that gets a gate muted). - The plugin's own template content (working-rules, change-decision-framework, enforcement-mechanisms) is both shipped content AND documentation of how the plugin works — edits to these have dual impact - Bump version in `plugin.json` when making release-worthy changes ## Knowledge Repository Project-specific architecture decisions live in `~/Projects/knowledge/projects/aria/`: - `decisions/002-knowledge-extraction-architecture.md` — task-based /extract + audit promotion model - `decisions/006-full-rule22-format-every-edit.md` — full format on every edit (no compression) - `decisions/008-skill-knowledge-connections.md` — skill-knowledge connection discovery + drift detection Cross-project knowledge that applies to ARIA: - `knowledge/rules/working-rules.md` — the 37 universal rules (ARIA's source of truth ships in plugin-claude-code/template) - `knowledge/rules/change-decision-framework.md` — Rule 22 framework - `knowledge/rules/enforcement-mechanisms.md` — enforcement tier model - `knowledge/guides/claude/plugin-development.md` — Claude Code plugin patterns - `knowledge/guides/claude/cowork-plugin-validation.md` — Claude Cowork plugin patterns (sibling guide; relevant if coordinating with aria-cowork or shipping a Cowork-side plugin) - `plugin-cursor-template/PORTING.md` — Cursor skill→`.mdc` compilation map and drift tracking - `plugin-cursor-template/audit/ARIA_CURSOR_AUDIT_REPORT.md` — Cursor enforcement-gap matrix (§5) Pre-staged ADR candidates live in `~/Projects/knowledge/intake/decisions-backlog.md` — check there for what's currently queued for next `/audit-knowledge`. Themes queued here historically drift as ADRs promote; the live backlog is the source of truth. Use `/context aria` to load relevant knowledge by project tag. --- *Last reviewed: 2026-08-27 — plugin-claude-code **v2.49.0** (**SHIPPED + PUSHED + GH-RELEASED + LIVE-VERIFIED**; `origin/main`=`ddfc99b`, verified by `ls-remote` SHA match **and** an ancestor check rather than the push exit code; `/releases/latest` resolves to v2.49.0 with all 6 assets, all 5 site `/latest/download/` links 200 **with a negative control returning 404**, and the **published** zip downloaded and found byte-identical to the local build — 584,367 B, carrying `skills/audit-rules/SKILL.md` and zero surviving `/aria-cowork:audit-style` references): **a new `/audit rules` sub-audit, the audit family committing to its verb forms, and a pre-release retrospective that found the fix itself had the defect it was fixing.** **W1 — `/audit rules`** mines the distilled corpus (memory feedback rows, the rules backlog — never transcripts) for corrections recurring across ≥2 distinct sessions, verifies every quote **at its source file** because an index row's slug is not evidence, and writes a rule only on an explicit approval naming the candidates. Ships `bin/check-rule-lead-bytes.sh`: the always-on digest truncates leads at 240 **bytes**, so a chars check passes leads that truncate mid-claim. **W2 — the verb migration.** `/audit <verb>` is canonical and advertised; the hyphen forms survive as **unadvertised** compat. 111 occurrences across 34 files, argument passthrough added, a permanent ratchet holding advertised hyphen forms at zero. ⛔ **`share` is NOT a verb** — the grammar accepts knowledge, config, style, usage, rules, all, and an unrecognized first token hits the unknown-verb branch, so a blanket hyphen sweep converts working `/audit-share` into a rejected form (measured, with a firing control: `share` 0, `rules` 3). **The retrospective — two patterns, both about verification scope, neither about the edits.** *A guard scoped to the wrong unit, on my own cleanup:* the leftover self-referential parenthetical was fixed in the knowledge nudges and missed in the identical config twins, because the fix keyed on one string instead of censusing the class the original sweep had used. *A full-file rewrite owns every claim in it, inherited ones included:* the dispatcher re-shipped false claims it inherited — `/audit` asserting a Cowork variant that does not exist, and `audit-style` both offering **and invoking** a nonexistent `/aria-cowork:audit-style`, so a `y` reply simply failed. ⛔ **A redirect gate is only honest when a redirect target exists**; where none does the right shape is a capability precondition, which is what `audit-style` and `audit-usage` now carry. Verified against the shipped tree, not reasoned: Cowork ships `audit-knowledge` + `audit-config` and no dispatcher, so the surviving redirects are true and were correctly left alone, and the two ports carry zero `aria-cowork` references. Gates: plugin suite **280/0**, hook-repro suite **38 suites / 484 assertions**, both bare exit 0 — ⚠ **two independent test trees, neither runner invoking the other, so "the suite passed" is ambiguous here unless you name which.** `ariaknowledge.com` synced the same day (badge, the 37th skill, verb forms) and read back from the live site.* *Session 2026-08-26 (later) — **the cap is not a constant, and that is why this arc did not converge.** Read out of the LIVE binary (`~/.local/share/claude/versions/2.1.245`, Bun-compiled with the JS embedded; ⛔ the homebrew `cli.js` is **2.0.8** and reading it would have been the same wrong-unit error a third time): `Rae(toolName, maxResultSizeChars, ceiling, skipAggregate)` returns `min(maxResultSizeChars, ceiling)` unless a **per-tool override map keyed by TOOL NAME** — behind the gate `"tengu_velvet_ibis"` — supplies a value. ✅ `K5 = 2000` and `V5 = "<persisted-output>"` **confirmed**. ⇒ **The threshold is PER-TOOL and (strong inference, not measured — `tengu_*` is this binary's gate namespace and no settings key exists; a gate fetch was not observed) REMOTELY MUTABLE.** Three consequences: it is *structural* confirmation that the Bash-tool probes never transferred (corroborated in-session — a **26,389 B** Bash result came back whole while a **19,557 ch** hook payload was wrapped, and later a 47.7 KB Bash result WAS wrapped, bracketing that consumer separately); the gate is **not a user lever**; and ⛔ **no payload may be sized against the cap, so locating it exactly would not make a hook design safe.** ⭐ **The composition measurement that replaces the four candidate designs:** the emission is assembled at `bin/session-start-rules.sh:35-39` and is **61% static / 39% computed** — static digest 11,960 ch (**12,166 B, already under probe A's proven 13,101 B** — ⚠ and that comparison is exactly the reasoning the 2026-08-27 correction below invalidates: "under the proven floor" was treated as the safety test, when the floor was never the constraint) plus 7,598 ch of blocks computed from `autonomy`, `session_state`, the project tag index and `user-rules.md`. ⛔ **So option Z is NOT a superset of the hook channel** — a file written once cannot carry a config-conditional block — and the split is by **MUTABILITY**, not by audience (§8.1) or fidelity (§10.3): the file carries the *behaviour*, the hook carries only the resolved *values*, which makes hook truncation non-damaging instead of cap-fitted. ✅ **PROBE RESULTS.** Probe A: all eight sentinels incl. the tail at 13,051 ⇒ the user-scope `~/.claude/rules/*.md` channel carries **13,101 B** (was 2,338 B, a 5.6× improvement). ⛔ **SUPERSEDED — do not quote this as the channel's capacity. 13,101 B is a FLOOR: the largest payload probe A happened to test.** A probe that fully delivers proves the channel carries *at least* that much and says nothing about the ceiling. ⛔⛔ **The live defect this file had until 2026-08-27 was not a missing measurement — it was PROPAGATION: probe C's result is recorded in `docs/superpowers/plans/2026-08-26-rules-file-hook-split.md:253` as "the channel at 32,056 B in one file and 34,394 B aggregate", and 32,056 already appears elsewhere in THIS footer — so both numbers sat in one always-loaded file with the stale one stated as the capacity.** A stale sentence reads exactly like a current one. **Authoritative figures: 32,056 B single-file, 34,394 B aggregate (probe C).** ⚑ Independently corroborated 2026-08-27 by a different instrument — not a sentinel-gradient probe file but the running session's own context: **29,875 B across three files delivered in full**, verified by three **tail sentinels**, one per file, *including the last file in alphabetical load order* (which is what rules out an aggregate budget exhausting mid-directory), plus a **38-of-38 rule census with section membership** on the 21 KB `aria-rules.md` (Coding 1–18 · Process 19 20 21 22 27 36 37 · Meta 23 24 25 26 28 29 30 31 32 33 34 35 38), which catches a mid-file hole *and* a reorder that tail sentinels alone cannot. **29,875 is LOWER than probe C's figure and is not a replacement for it** — its value is being obtained a different way, at zero cost, from a session's delivered context rather than from an armed probe file. ⚠ Every one of these is a floor, and per this same arc's binary read the cap machinery is per-tool and plausibly remotely mutable, so any figure here measures a moment. ⛔⛔ **AND THE SHARPER FINDING, which is not about size at all: this channel loads ONCE at session start, so a rule added mid-session is silently absent from every running session** — measured live, a parallel session grew `user-rules.md` from 19 to **25** U-rules at 20:19 and **U20–U25 were not in the running session's context**, with no marker of any kind. That is a *temporal* gap, and unlike the digest's 240-byte truncation (which appends `…`) it announces nothing. It also means the directory now stands at **31,822 B, above the verified figure and unverified.** Probe B: `PROBE-B-QX7K` **absent** ⇒ the `claudeMd` settings key is **inert at user scope and fails SILENTLY** — no warning, no error, no log line; readable only because probe A was the positive control in the same arm. ⛔ **A claim made and retracted inside this one session: "Z is unproven by 51%" compared probe A's capacity against the hook's *composed* emission rather than against what a file would carry (12,166 B). Same wrong-unit shape as probe A itself, in the session that named the pattern.** ⛔ **RULED (Mike): the file channel is `~/.claude/rules/`, not the `CLAUDE.md` `@`-import** — accepting one probe session in exchange for never writing the user's repo. ⏳ **PROBE C ARMED** at `~/.claude/rules/_probe-c-size.md`, **32,056 B**, nine markers at **703 / 4,052 / 8,067 / 12,008 / 16,023 / 20,038 / 24,053 / 28,068 / TAIL 32,009** — deliberately ABOVE the ~25,800 B worst case so a pass settles the channel permanently. ⚠ It costs ~8k tok in EVERY session in EVERY project until deleted: `rm ~/.claude/rules/_probe-c-size.md`. ✅ **AC1's GUARD IS BUILT** (`eb82199`) — 11 assertions in `plugin-claude-code/tests/test-aria-rules-digest.sh`: a positive control on the needle, a deterministic worst-case fixture proven to carry all six conditional blocks, a downward-only ratchet at **20,322** normalised codepoints, and the last-rule-title check on the minimal AND worst-case paths. Suite **213 passed / 0 failed, bare exit 0**. ⛔ **The FIRST version survived its own mutation:** it counted raw characters, and the payload interpolates the knowledge-folder path **3 times**, so the total tracked the temp-dir path length (21,074 at a 144-char path vs 20,942 at 100 — exactly 3× the difference); `wc -m` was no better, counting bytes under `LC_ALL=C`. The measure is now jq's literal string split, path- AND locale-independent. ⚑ **Four of seven mutation attempts were unfaithful** (a no-op insert, a `sed` that never matched, and twice truncating a variable after its value had been copied out) — every one caught by proving the condition was created, **none by re-reading**. ⛔ **NEW DEFECT FOUND, not fixed, Mike's call: `bin/pre-bash-write-check.sh`'s temp-path exemption tests whether the COMMAND STRING MENTIONS a temp path, not whether the MUTATION TARGET is one.** Proven three ways: `sed -i` on a tracked `.sh` **warns**; the identical edit in a command that also references a scratchpad path is **silent**; `cat >>` into a tracked `.sh` **warns**. ⚑ The irony is what makes it matter — **backup-to-scratchpad-then-mutate is the safe pattern this workspace's own discipline mandates**, so doing the careful thing silences the hook, and its measured 0.674% fire rate is therefore an **underestimate** (the corpus cannot have counted what the hook was blind to). It is a false NEGATIVE, so the KILL-not-loosen rule (which governs false positives) does not bind; the fix is narrowing the exemption to the resolved target. ⚠ Also: the harness's own bash-first directive rides along with **auto mode** (`steerOnly`) — same instruction block also serves bypass-permissions mode and a `bashFirst` flag — so under auto mode it actively pushes the shell edits that trip that hook. Commits `eb82199` (guard) + `f1fcc29` (spec). ⚠ **19 ahead of `origin/main`, NOT pushed.** ⚠ CODEMAP.md is **37 days** old against a 14-day threshold.* *Session 2026-08-26 (later still) — **`/auto`'s modifier surface carried two defects; both fixed in canonical, neither live.** ⛔ **F2 — three knobs documented in Step 5 were in no parser list.** `workflow`, `fanout=<pct>` and `agents=<N>` are described there as invocation overrides for the three fan-out stopgaps, and appeared in no modifier bullet, no `argument-hint` and no `description`. Under the skill's own ENDS scan an unrecognised token ends the modifier run, so typing one **dropped the opt-in AND put a stray word in the goal** — `/auto full workflow audit X` yielded goal *"workflow audit X"* with Workflow still hard-OFF. ⚑ It **failed safe** (tighter defaults held, nothing errored), which is exactly why it survived in shipped docs: a knob that silently keeps its default is indistinguishable from one you never reached for. Also corrected the axis count — the description said "one word per axis" then listed three plus two loose extras; there are **six** (authority · presence · duration · work-source · context-recovery · fan-out). **Ruled ENDS-only and uniform, NOT a second key=value-anywhere rule:** a general `<word>=<value>` scan would eat a legitimate goal like *"fix the assertion that checks count=20"*, which is the mis-parse the ENDS rule exists to prevent; `=`-bearing tokens are collision-free by shape and need no rule of their own. ⛔ **F4 — the Runtime Gate offered a handoff to a skill that exists in no port.** It named a Cowork counterpart of `/auto` four times and, on `y`, said it would invoke it via the `Skill` tool. Verified absent in `plugin-claude-cowork/skills` with a positive control, in source and in the installed tree. Cause: the section was doing two jobs — ADR-094's gate exists for the **24 colliding names**, where the point is offering the runtime-appropriate variant, and this skill is Code-only with no counterpart, so it is not in the collision set. **The dead redirect is what a colliding-name template produces when applied to a non-colliding name.** Rewritten as a Bash **capability precondition**: the check is unchanged, the stop branch now routes to the four Cowork gates that do exist (`prospect`, `retrospect`, `handoff`, `wrapup`), and the proceed branch gained the honesty instruction it lacked — never report a Bash-backed step as done when it did not run. `y`/`n` kept for family uniformity with the question polarised to *"Stop here?"*, so `n` still means *run it anyway*; phrasing it "proceed anyway?" would have inverted `n` for this skill alone. ⛔⛔ **A PRE-EXISTING ASSERTION WAS CERTIFYING THE DEFECT: `tests/repros/auto-modes.sh` assertion `I` required the skill to NAME the dead variant**, so it would have gone red for anyone who fixed the redirect. Found only because the green arm failed at 155/1. It came from the colliding-name template rather than a measurement; replaced (not deleted) with the fact that is true — the skill declares itself Code-only. ⚑ **This is the inverse of ordinary test rot: a vacuous assertion goes quietly green and protects nothing, while this one went actively green on a broken behaviour and would have BLOCKED the repair. Both are invisible until you fix the code — which is why the green arm is not a formality.** ⚑ Also self-caught: my own `FG5` emitted five failures for one defect (a per-gate loop plus a redundant summary covering 2 of 4); collapsed to one assertion naming every miss. **Gates:** Gate B measured before and after rather than assumed — **19,552 → 19,622 B of 19,968, headroom 346** (the `description` IS counted; `argument-hint` is not, `release.sh:78` stops at the next top-level key, so the hint edits were free). auto-modes **146 → 156**; two-sided via a scratch mirror tree running the edited suite against the committed pre-edit file — **151 passed / 5 failed**, each for its own named reason, GREEN 156/0. `FG3` passes in **both** arms and is labelled in-file as a non-regression guard against an over-broad deletion, **not landing evidence**. Full plugin suite 253/0, repro set 37 suites/0, all bare exit 0. Commits `d6fd0fa` (F2/F3) + `7ec3ca7` (F4), staged by exact path. ⚠ **NEITHER FIX IS LIVE** — measured in the installed plugin: 4 dead refs remain, `fanout=` absent from `argument-hint`, description still undercounts the axes. A surgical copy of `skills/auto/SKILL.md` makes them live; a full re-install also lands 42 other commits. ⚠ **NOT pushed** — 44 ahead of `origin/main`, 42 of them another arc's. ⚠ Ports: F2/F3 reach antigravity and cursor when their build scripts next run (`build.sh` copies canonical `skills/` and has no `auto` overlay; cursor recompiles via `port-skills-to-mdc.py`); codex is hand-sync; **F4 needs no propagation — those ports strip ADR-094 gates, censused 0**. ⚠ **A `/wrapup` conflict left unresolved rather than actioned: `session_state_tracked` is global-`true`, but this repo ignores `SESSION.md` at `.gitignore:17`, is public, and has a fatal Gate D on home paths.** The skill's true-branch would delete that ignore line and stage session state into a public artifact; not done, and `.gitignore` was concurrently dirty. This is the documented global-knob defect firing where the consequence is publication. ⚠ Unretrospected: `d6fd0fa~1..7ec3ca7`.*