Immutable. This exact content is served forever at /api/v1/blob/f2f235f3ed930c4b.
# 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 **self-corrects**: invoked from the wrong runtime (Bash-availability is the fingerprint), it announces the mismatch in one line and redirects to the correct variant with the original arguments, without asking. ⛔ **As of v2.51.0 it does NOT ask, and there is no opt-out** — superseding ADR-094 §Part 2's `y`/`n` question and §Part 3's auto-mode exception, which existed only because the gate was a question. ⚠ A gate whose counterpart does NOT exist must never auto-redirect — it keeps a capability-precondition shape instead, since a redirect is only honest when a target exists. 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-28 — plugin-claude-code **v2.51.0** (**SHIPPED + PUSHED + GH-RELEASED + LIVE-VERIFIED**; `origin/main`=`e9e0353`, `ls-remote` SHA match + ancestor check; `/releases/latest` = v2.51.0, 6 assets, 5 links 200 with a 404 control, published zip byte-identical at 581,713 B and content-checked — `wrapup` redirects, zero `y`/`n`, and excluded `recap` correctly has NO redirect): **runtime gates now SELF-CORRECT instead of asking, and bare `/skillname` belongs to Code.** ⛔ **The `n` branch is GONE — there is no way to force the mismatched variant**, deliberately (the Cowork variant inside Code skips the memory + plans paths *because* it assumes no shell, so it is strictly worse). ⛔ **Bare-form priority is enforced by DESCRIPTION CONTENT, not by any harness rule** — Code descriptions carry the bare triggers, Cowork's carry only `/aria-cowork:x`; 22 of 24 already complied, `cowork/interview` did not. ⚠ **`aria-setup` and `daily-audit` lack the namespaced-only marker and are CORRECT** — deliberately distinct names, no collision; do not 'fix' them. ⛔ **SEVEN Code gates are EXCLUDED and must never auto-redirect** (`audit`, `audit-rules`, `audit-style`, `audit-usage`, `auto`, `recap`, `roadmap`) — no counterpart exists, and **a redirect gate is only honest when a redirect target exists**; `[RG2]` guards it. ⭐ **THE FIND: three Code gates asserted "No Cowork variant ships yet" while cowork ships ALL THREE** (`foundational-review`, `interview`, `readiness-audit`) — so a Cowork user was offered a DEGRADED Code run instead of the correct variant sitting right there. The v2.49.0 defect inverted; guarded by `[RG4]`. ⚑ **Zero tests touched any of the 57 gates before this release** — `tests/test-runtime-gates.sh` is the first, derives its in-scope set from **counterpart existence** rather than a hardcoded list, and all 4 families are mutation-verified (each reds its NAMED control, restores byte-identical). ⚠ **ADR-094 amended in place: §Part 1 stands; §Part 2's question and §Part 3's auto-mode exception are SUPERSEDED.** ⚠ **Two independent test trees** — plugin **293/0**, hook-repro **38 suites / 484 assertions**, both bare exit 0; naming which is required. Gate B unchanged, 449 B headroom.* *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`.*