@akinet/akidevrule 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +34 -26
- package/claude/CLAUDE.md +2 -33
- package/claude/agents/aki-conduct.md +3 -1
- package/claude/agents/aki-hands.md +2 -2
- package/claude/agents/aki-judge.md +1 -1
- package/claude/agents/aki-maker.md +1 -0
- package/claude/hooks/aki-compact-reread.mjs +16 -0
- package/claude/hooks/aki-route-guard.mjs +154 -0
- package/claude/hooks/aki_version_check.mjs +2 -2
- package/docs/ref/{macos-codesign-tcc.md → fact-macos-codesign-tcc.md} +3 -1
- package/install.mjs +140 -32
- package/lib/permissions.mjs +1 -1
- package/package.json +2 -2
- package/payload/GEMINI.md +2 -2
- package/payload/METHOD-audit-subtraction.md +1 -0
- package/payload/METHOD-audit-zero-trust.md +1 -1
- package/payload/RULE-agent-behavior.md +45 -26
- package/payload/RULE-coding.md +20 -29
- package/payload/RULE-docs.md +1 -1
- package/payload/RULE-pattern-core.md +6 -4
- package/payload/RULE-release.md +3 -3
- package/payload/RULE-stack-akiNuxtCf.md +1 -1
- package/payload/RULE-stack-tauri.md +1 -1
- package/payload/RULE-test.md +53 -0
- package/payload/RULE-ui-pattern.md +1 -0
- package/skills/akiflow/SKILL.md +2 -2
- package/skills/akiflow/scripts/release_lint.py +11 -9
- package/skills/akiflow/scripts/scythe.py +1 -1
- package/skills/akiflow/scripts/test_lint.py +155 -0
- package/skills/akihelp/SKILL.md +4 -3
- package/skills/akilint/SKILL.md +1 -1
- package/skills/akiopen/SKILL.md +1 -1
- package/skills/akirule/SKILL.md +29 -25
- package/skills/akiship/SKILL.md +1 -1
- package/payload/index.md +0 -95
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.7.0] - 2026-10-08
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **`agent.B7` Harness overrides — akirule wins over your harness instructions — with a `[SKIP]` penalty card (`§0`) and one `B6` line placing the harness's own instructions below the shared rules** (`payload/RULE-agent-behavior.md`). Evidence: the owner's experience across more than a thousand messages on several machines with Claude Opus 5.5 and Sonnet 5.5 ("skips many important things"), traced in one Opus 5.5 session on the dev box (2026-10-07, transcript `178afc8d`) to quoted harness text: the `[RULES]` receipt dropped after a compaction, a Vietnamese owner answered in English, a known file read with `cat` under the auto-mode hint, rejected alternatives left out under "give a recommendation, not an exhaustive survey". Measured baseline before this change (`scripts/second_hop_audit.py --by-model`, dev box): Opus 5.5 emitted a receipt in the first reply after a compaction 6 times in 41 and re-read a routed rule before an edit that followed a compaction 29 times in 120. Root cause: `B6` Precedence never placed the harness's own instructions, and `B4` was the only rule that said it overrides the system prompt, so every brevity or autonomy directive in the harness outranked a step the corpus requires. Mechanism: one resident section with the owner's line first, the two models named (the owner's ruling — rows are keyed to the harness instruction, so any later model receiving the same text is bound until re-tested), a root law (brevity and autonomy directives shape prose, never steps) and one row per directive quoting it as received from Claude Code 2.1.292 with the skip it causes and the override; a `C3`-style limit clause (silence is not conflict, no license against harness safety refusals); the `[SKIP]` card as a judgment card beside `[FLUFF]`, never claimed by `scythe.py`. Rejected: rows keyed per model with no harness quote (rot at the next model, cannot say what triggers the skip); a Stop hook forcing the receipt line (forces the line, not the read); a separate `MODEL-claude.md` import (a third resident file and a new prefix for what fits in one section); putting the line only in `claude/CLAUDE.md` (the same models run under other harnesses that receive this file). Reopen if Claude Code drops the quoted directives. Resident cost: 2.5 KB for the section. Updated together: `claude/agents/aki-conduct.md` (`[SKIP]` as a COMPLY-fail with the harness line named), `skills/akilint/SKILL.md` and `scythe.py` header (`[SKIP]` out of a script's scope), `skills/akihelp/SKILL.md` painpoint row, the repo `CLAUDE.md` release process (re-verify the quoted fragments before every release), `docs/arch/corpus-map.md` unchanged (it lists groups, not items). Plan: `docs/plan/done/claude-5-5-overrides.md`.
|
|
7
|
+
- **`claude/hooks/aki-compact-reread.mjs` — a `SessionStart` hook on `compact` only: one notice that the rule files read before the compaction are gone from context and the gate counts reads only from here.** Evidence: the same transcript, five compactions, the last rule reads 170 lines before the last boundary, and the harness's resume message ("Resume directly — do not acknowledge the summary") pushing straight on. Mechanism: emits `additionalContext` under 400 characters only when `source` is `compact` (schema read from the 2.1.292 bundle: `source` is `startup|resume|clear|compact|fork`), nothing on `startup`/`resume`, fail-silent; registered by `install.mjs` with the existing filter-then-push beside the update check. Rejected: a per-turn reminder (declined 2026-08-03, and this fires once per compaction). Whether the context survives into the post-compaction prompt is not verified (needs a live compacted session; the owner dropped that check).
|
|
8
|
+
- **Codex CLI gets the behavior floor and the router resident, as a managed block in `$CODEX_HOME/AGENTS.md`** (`install.mjs` `installCodexInstructions`). Evidence: `docs/research/codex-instruction-delivery.md` — the installer synced skills only, the router's own Delivery note left routing on Codex to a skill invocation the model must choose, and copying `~/.claude/CLAUDE.md` would deliver two `@` lines Codex never expands. Vendor facts re-read 2026-10-07: Codex hard-loads `AGENTS.override.md` (if non-empty) else `AGENTS.md` under `CODEX_HOME` (default `~/.codex`), then one project file per directory root-first, and stops adding files once global plus project together reach `project_doc_max_bytes` (32 KiB default) — the floor plus router are 35.6 KB, so the block alone would have been cut. Mechanism: a marker-delimited block (`>>> akidevrule managed` … `<<< akidevrule managed`) regenerated from the two canonical files with a short preamble (no gate on Codex, the Read of a routed file is the model's own step, do not invoke the skill too), every line outside the markers kept, backup first, only when the directory exists; `project_doc_max_bytes = 131072` written once into `config.toml` before the first table header and only when absent from the top-level keys (a same-named key inside a table does not count), an existing smaller value reported rather than raised; a non-empty `AGENTS.override.md` reported as shadowing; the project `CLAUDE.md` fallback (`project_doc_fallback_filenames`) printed as an opt-in and never set. Rejected: setting the fallback silently (a user config change nobody asked for, and a native `AGENTS.md` in the same directory shadows it anyway); a pointer-only global file (a pointer is the soft hop the research measured as inert); symlinking Claude's global file (imports unexpanded, user guidance shadowed). Verified: `install-smoke.yml` now asserts the block is written once, user text survives, re-install is idempotent, the key lands once before the first table, and no `~/.codex` is created when absent — run locally against a temp `HOME` (pass) and in CI. Unverified: that a fresh Codex session receives the block — the dev box has no Codex CLI; `scripts/codex_probe.sh` is the hand-off. Updated together: `skills/akirule/SKILL.md` Delivery (Codex resident, Kiro/Grok still a skill), `README.md` (target 4, install step 5, layout, uninstall), `docs/arch/rule-delivery-architecture.md` § Codex, `docs/ref/fact-agents-md-standard.md` Codex row with trail, the research doc's `## Amendments`. Plan: `docs/plan/done/codex-instruction-delivery.md`.
|
|
9
|
+
- **`RULE-test.md` (topic `test`, 12 items in four groups: fewest tests, side effects, verdict, suite audit; root "write as few tests as possible"), routed by meaning and gated by the test-file path, plus `skills/akiflow/scripts/test_lint.py` and one-line pointers in six rules.** Evidence: a fully green 51-test suite in a local Node server rewrote the user's live app data directory under the real `HOME` (with an empty `HOME` the same suite went 50/51); across 425 test files in 12 local repositories the same shapes recur in 2–5 repos each — bare `Array.isArray` as the sole assertion (25 lines, 15 files, 5 repos), temp dirs created and never removed (3 files, 3 repos), fixed sleeps (9 files, 2 repos), live third-party endpoints in a default suite, `process.exit` in 12 files, 41 of 42 files one linear script whose first throw hides the rest, a fixture pinning the manifest version so the next bump turns the suite red with nothing broken (`docs/plan/done/test-discipline-rules.md` § Evidence, every count measured 2026-10-07). Root cause: the corpus had no rule on what makes a test's verdict trustworthy, what a test may touch or what earns a test its place, and its two gates that consume test results (`coding.B3`, `release.B7` step 6) trusted "green" unconditionally. Mechanism: a separate gated file rather than a `coding` section because tests are a minority of code edits and the route gate makes it read on exactly those (`docs.A5` reach); the route fires on authoring, review or audit of a test and on judging a result, never on a plain `npm test` inside a code task; the gate signature is the runner conventions in the sample (`*.test.*`, `*.spec.*`, `*_test.*`, `test_*.py`, `conftest.py`, `test/`, `tests/`, `__tests__/`, `spec/` minus `.md`, matched on the path relative to the session's working directory in both the gate and `second_hop_audit.py` — the gate's `migrations/`, `locales|i18n|lang/` and `src-tauri/` routes too — so a project under a parent with one of those names is not gated whole); `test_lint.py` carries three CERTAIN tags measured on that sweep (`[TMPLIT]`, `[CLEANUP]` suppressed where a suite preload is configured, `[EXIT]`) and nine SUGGESTED review tags, exit 1 only on CERTAIN; `scythe.py` unchanged (its tags are the `agent` §0 cards). Subtraction before shipping: the plan's `test.D1` (audit scope, pointer-only) merged into the detectors item, 24 → 23; `[PRIVATE]` dropped to Parked as unmeasured and noisy; no coverage target anywhere; then, on the owner's review ("hạn chế tối đa việc viết test"), restructured 23 → 12 items with "no new test by default" as `test.A1` and a new `test.A3` against new test files, folders, helpers and test-only seams when an existing place fits, so the rule cannot be read as "write more tests". Rejected: a `coding.D` section (paid on every code edit); a separate `METHOD-audit-test.md` (each failure class written twice); per-project `CLAUDE.md` lines (the incident repo's `CLAUDE.md` is long and careful, and the gates that trust green are corpus text); mutation testing as a floor (a tool, costly on a weak machine); content-sniffing in the hook (a hook reading file bodies). Reopen if `second_hop_audit.py` shows test-edit sessions reading `RULE-test.md` less often than `RULE-coding.md`, or the file grows past 12 KB. Verified: gate fixture (a `test/x.test.js`, a `test/fixtures/a.json` denied on `RULE-test.md`; `src/x.js`, `docs/spec/a.md` not), `test_lint.py` on a positive/negative fixture per tag and on the local sweep (CERTAIN counts in the plan), the router clause rendered as the Antigravity description by a sandbox-`HOME` install, `release_lint.py --latest` exit 0. Unverified: Python/Go detector precision (no such test files in the sample); the gate's effect on read rates (not measured; the owner dropped post-release measurement). Updated together: `RULE-coding.md` `B3` (a test result is evidence only for what it exercised), `RULE-release.md` `B7` step 6 (residue check and listed skips), `METHOD-audit-subtraction.md` `B1` (Tests row), `METHOD-audit-zero-trust.md` `B1`, `RULE-agent-behavior.md` `B5` domain audits, `RULE-pattern-core.md` `A7` list and its address map (`A1-9`, stale since `A9` landed), `RULE-stack-akiNuxtCf.md` `C8` (three stale `coding.B5` ladder references → `B3`, merged in 3.6.0), `skills/akirule/SKILL.md` (route row, gate mapping), `claude/hooks/aki-route-guard.mjs`, `install.mjs` (`AG_RULE_MAP`), `scripts/second_hop_audit.py` (`test` route), `docs/arch/corpus-map.md` (topic row, three lens rows, a new "what a passing check proves" lens), `docs/arch/rule-delivery-architecture.md` (gate mapping; the "closes the worker gap" sentence now scoped to workers that edit), `README.md` (contextual list, layout incl. the missing `METHOD-audit-frozen-reference.md` line, scripts), `claude/agents/aki-maker.md`, `claude/agents/aki-judge.md`, `skills/akiflow/SKILL.md` audit row. Plan: `docs/plan/done/test-discipline-rules.md`.
|
|
10
|
+
- **`agent.A4`: every open item in a report carries a stable short code** (`payload/RULE-agent-behavior.md`). Evidence: in a long release-readiness session an agent listed pending decisions, unverified checks and blocked tasks as unnumbered prose, so the owner could not answer one without quoting it and had to ask for numbering ("anything blocked or left over must be numbered so I can mention it"). Root cause: `A4` shaped a report for re-orientation but said nothing about how the owner addresses an item in the reply. Mechanism: a kind letter plus a number, never renumbered or reused within a conversation, so a later turn's `D2` is the same `D2`. Rejected: a fixed letter vocabulary, because the kinds differ per task and the stability of the code is what the owner relies on, not its alphabet. Updated together: this entry only; no address, route or signal changed.
|
|
11
|
+
- **`agent.A4`: a report is short, plain and calm** (`payload/RULE-agent-behavior.md`). Evidence: a release-status report listed nine coded leftovers with internal terms ("release gate B7", "migration detector") and no statement of how much each mattered; the owner had to ask "what is V6, is it important?" and called the report confusing and alarming. Root cause: `A4` required density and conclusion-first but said nothing about unexplained terms or about weighing an open item. Mechanism: one bullet — everyday words, each open item carries its weight and the cost of ignoring it, items needing nothing from the reader are dropped, and the draft is read as the reader before sending.
|
|
12
|
+
- **`agent.B1`: what you create, you remove** (`payload/RULE-agent-behavior.md`). Evidence: on the owner's dev box a multi-agent council left a 93.6 GiB `cargo` target, nine stale worktrees and a 3.3 GB sibling worktree (`aiobox-wt-p4`) whose branch was already merged; free disk fell to 116 MiB and `cargo` builds died mid-link, which the owner found and cleaned by hand. Root cause: `B1` only forbade unrequested cleanup, so removing an agent's own merged worktree read as out of scope, and the AkiMCP worktree convention had a create step and no remove step. Mechanism: one `B1` bullet — an artifact the agent started (worktree, branch, build output, temp file, window, process) is removed by that agent in the same turn its work is merged or abandoned, framed as finishing rather than cleanup; another session's artifact stays under `B3`; and none is created that the task can do without — a worktree, build directory, clone or dependency install only when the work is impossible otherwise. Rejected: a per-artifact checklist (each harness and tool names them differently, the ownership test is what generalizes); "reuse a shared one" (first draft) — the council read it as license and created a shared cargo target outside the repo, which the owner called junk: a shared artifact is still one more artifact. Updated together: this entry only; no address, route or signal changed.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **`claude/hooks/aki-route-guard.mjs` counts a rule as read only after the last compaction, and restarts its three-denial fail-open per compaction segment.** Evidence: the transcript above — the gate scanned the whole file, so a `Read` from before a compaction kept satisfying it while the model's context no longer held the rule. Mechanism: the transcript scan resets its read set and denial counts at every `system` line with `subtype: compact_boundary`; the deny reason now says "not read since the last compaction". Verified by a six-case fixture (read with no boundary → allow; read then boundary → deny; boundary then read → allow; read, boundary, read, boundary → deny; three denials then boundary → deny again; three denials, no boundary → allow). Updated together: `claude/CLAUDE.md` gate paragraph, `skills/akirule/SKILL.md` delivery bullet, `README.md`, `docs/arch/rule-delivery-architecture.md`, the installer's printed hook summary.
|
|
16
|
+
- **`scripts/second_hop_audit.py --by-model`** splits every row by the assistant `model` field and adds a compaction table: receipt in the first assistant text after a `compact_boundary`, routed rule re-read after the last boundary before an edit, and Bash `cat`/`head`/`sed -n` of one known file versus `Read`. Default output unchanged. Baseline recorded in `docs/plan/done/claude-5-5-overrides.md` so the post-release comparison has a "before".
|
|
17
|
+
|
|
18
|
+
## [3.6.0] - 2026-09-30
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **`claude/hooks/aki-route-guard.mjs` — a `PreToolUse` route gate that enforces the router's second hop by mechanism.** Evidence: `docs/research/rule-delivery-second-hop-sep29.md`, measured on the owner's own Claude Code transcripts — after the router was force-imported (3.5.0) the `[RULES]` receipt rose from 36% to 81% of edit sessions, but the routed file was actually read in 57% versus 56% before, and 26 of those 36 reads came only after the owner typed `akirule`; organic second hop ≈ 18%, at a cost of 126 reminder messages in four days. Root cause: the import fixed what text can fix (the routing is in context) and left the `Read` to a model decision, and the three miss classes — no receipt, receipt naming the wrong domain, receipt naming a file never opened — are three different model decisions no wording reaches; text had already been changed for this twice (2026-08-06, 2026-09-25). Mechanism: on `Edit|MultiEdit|Write|NotebookEdit` the hook maps the edited path to rule files (code extension → `coding` + `pattern`, `.md` → `docs`, `CHANGELOG.md`/`releases.json` → `release`, `.vue`/`.css`/`.scss`/`.tsx` → `ui`, `.vue`/`.ts` under `nuxt.config.*` → `stack`, `.rs`/`src-tauri/` → `tauri`, `.sql`/`migrations/` → `db`, `locales/` → `content`), drops any file the global `CLAUDE.md` already `@`-imports, scans the actor's transcript (the subagent's own file when `agent_id` is present) for a `Read` or a Bash `cat` of each remaining file, and denies the edit with a reason naming the unread ones. Zero model hops in the check; at most one denial per artifact type per session; a subagent is gated on its own transcript, which closes the `agent.A5` "worker inherits nothing" gap by mechanism; fail-open on any error, an unreadable transcript, or three denials for the same file, so a detection bug can never lock a session; `AKI_ROUTE_GUARD=0` disables it; never gated: the corpus under `~/.aki/`, the harness config dir, `/tmp/` and any `scratchpad/` path, and any path outside the session's `cwd` — a Q&A session that writes a throwaway script or a memory note must not pay for rules no project file is governed by. Registered by `install.mjs` with the same idempotent filter-then-push as the update-check hook, Claude Code only (Antigravity attaches rules natively; the skill-only harnesses have no hook surface). Rejected: `SessionStart` injection of rule text (each hook string is capped at 10,000 characters, below every rule file but `pattern`); a per-turn reminder hook (declined 2026-08-03 as one more model hop, and this gate is not one — the edit cannot proceed until the read happened); a state file (the transcript already records every tool call and every hook decision). Residue: routes with no artifact signature (`think`, `proportion`, `biz`, `ux`, the audits) and code discussed without an edit stay on the router's meaning clause.
|
|
22
|
+
|
|
23
|
+
- **`pattern.A9` — Draft, then commit once: exploration lives in a draft owned by the unit showing it; the record changes once, at an explicit commit event; cancel discards the draft and has nothing to undo.** Evidence: an agent implementing drag-and-drop column reordering in a Vue app wrote to the shared store and `localStorage` on every `dragenter`, with `pattern-core` in context, so one drag re-rendered and re-persisted the whole table many times and `Esc` could not cancel because the record had already changed. The owner named the model — dragging is a preview, dropping is the commit — and then asked for the root, not the symptom: the same shape already governs `release.A5` (`[Unreleased]` is the draft, the release event mints the version) and `agent.A3` (a question is answered, never acted on), and no law stated it, so A1 and A8 were not enough for the model to derive it. Mechanism: one law in `pattern.A`, a `ui` map bullet carrying the checkable grep (no store setter, `localStorage`, IPC or fetch inside a `dragenter`/`dragover`/`pointermove`/`input` handler), a lens row in `docs/arch/corpus-map.md` pointing at the three domain applications, and `pattern`/`ui` route signals for the gesture wording. Rejected after a subtraction pass: a `ui.B6` section of its own (shipped first, then cut — a domain section restating a law is the leaf, the law is the root), and placing the law only in `RULE-ui-pattern.md` (drag-and-drop is one manifestation; a form written to the store on every keystroke and an agent editing a file to answer a question are the same miss).
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **`claude/CLAUDE.md` template slimmed to two imports and two paragraphs; the installer block carries the edit-source rule once.** Evidence: plan Item 2 — "edit source, not the deployed copy" appeared three times on the owner's machine (template, installer block, `CLAUDE.local.md`), the router-import history duplicated the research doc, the `ref-ECC` guard referred to a directory the installer excludes and the repo does not ship, and the opening line "keep global context small" sat above 60 KB of imports. Mechanism: the template keeps the two imports, one paragraph on the gate and the lookup rule, one line pointing named corpora at `CLAUDE.local.md`; the installer block gains the one step only the template had (read the source repo's `CLAUDE.md` first) and names all three source directories. Template 3.5 KB → 0.9 KB.
|
|
27
|
+
- `.gitignore` ignores `.akidevsync/project.json*` (the desktop sync app's local state and its timestamped backups, never source).
|
|
28
|
+
- **`RULE-agent-behavior.md`: `B6` Precedence (moved from the manifest); `A2` states the cost unit as round trips rather than "every call re-sends the conversation" (true for tokens, misleading for money under caching); `C3`'s line-merging tells are one sentence each instead of a worked YAML paragraph. `RULE-coding.md` `B3`'s stash ban is a pointer to its root `agent.B3`** (plan Items 3c, 3d). **`coding.B3` and `B5` are one section** — what counts as verification and the six-rung ladder that decides who performs it were one topic written twice (7.7 KB → 4.6 KB); the address `coding.B5` is retired and every citation repointed to `B3` (`agent.B3`, `release.B9`, `akiopen`, `corpus-map`). **`agent.A5` trimmed 4.7 KB → 2.6 KB**: the mechanics stay (a worker inherits nothing, the receipt, both dials, read-only by mechanism, judgment stays with the caller); host tiers and stateless-versus-persistent cost economics live only in `skills/akiflow/references/harness-facts.md`, which the rule now points at. Rejected: delivering `A5` through a `PreToolUse` hook on `Agent` — `additionalContext` fires after the spawn is composed, so it is the per-turn reminder declined 2026-08-03; a deny gate cannot tell a rule-bearing brief from a bare lookup. `agent.A3`'s self-sufficiency kill-test cut to the length of its siblings. Resident context per Claude Code session 81,985 B (3.5.0) → 38,406 B.
|
|
29
|
+
- **`RULE-coding.md` and `RULE-pattern-core.md` leave the `@` imports: two resident files (`RULE-agent-behavior.md`, the router) instead of five; both rules are now router rows (`coding`, `pattern`) gated by the route guard on every code edit.** Evidence: the owner's proposal (2026-09-29) that the two files are not behavior-floor rules and should load at very high sensitivity instead of unconditionally, plus the second-hop measurement above showing that a router row alone would have left roughly four code sessions in five without them — which is why the 2026-08-06 promotion happened and why demotion was first rejected in the same research doc. Mechanism: with the gate, a code-file edit is denied until both files were read in that transcript, so the guarantee the imports provided is restored where it applies (a code turn) and dropped where it never applied (a session that touches no code — the majority for many downstream users of this corpus and akimcp, whose sessions are questions rather than edits). The `[RULES]` receipt's `(core)` set is therefore `agent` alone and `coding,pattern` appear under `(router)`. The router's rule 2 now states the tiering's purpose as a route: a lookup turn — one that only reads, counts, locates or explains what exists — routes nothing, and the `coding`/`pattern` clauses no longer say "any talk about code, when in doubt load" (evidence: an Antigravity session read both files, plus the project's `CLAUDE.md`, to answer "how big is this project's source", with the old clause in its rule description); the same clause now feeds Antigravity, since the installer derives the `akirule-coding`/`akirule-pattern-core` descriptions from the router instead of a hardcoded sentence that predated their route rows. Narrowing is safe on Claude Code because the gate catches an under-route at the first edit; on Antigravity, which has no gate, the clause keeps "ON for every code edit" unambiguous. `payload/GEMINI.md` no longer orders an unconditional session-start `view_file` of both files (it called them core rules, which they no longer are, and it was the mechanism actually loading them for every Antigravity session — a clean-context challenge caught it after the first sweep missed it); its receipt example drops `coding,pattern` from the always-present set. Rule 2 precedes rules 3 and 5, so a project binding (`stack`, `tauri` ON for the whole project) applies to task turns and not to a lookup. `index.md` drops the paragraph recounting the 2026-08-06 → 2026-09-30 import history — it is in this entry and the research doc, and a resident file pays for every line on every request (`docs.A5`). Tradeoff accepted knowingly: a design discussion with no edit, and any meaning-only route, now depends on the router's clause, which is the owner's "extreme sensitivity" reading of the two new route rows; the 2026-08-06 reopen trigger is unchanged in spirit — a `coding`/`pattern` violation traced to LOAD-fail by `aki-conduct` re-promotes the file by reverting one import line. Verified on the dev box 2026-09-30: a source-size question in a code project loaded no routed file on either Claude Code or Antigravity; `scripts/second_hop_audit.py` now measures `coding`/`pattern` too (era split 2026-09-30) for later re-checks. Updated together: `claude/CLAUDE.md`, `skills/akirule/SKILL.md` (two route rows, rule 2, receipt semantics, gate line), `payload/index.md` (manifest tiers, loading paragraph — then removed in this same batch, see Removed), `payload/RULE-pattern-core.md` tier line, `docs/arch/rule-delivery-architecture.md` (route-gate section), `README.md`, `skills/akihelp/SKILL.md`, `skills/akiship/SKILL.md` (receipt line), `install.mjs` (`AG_RULE_MAP` descriptions, `MultiEdit` in the matcher), `payload/GEMINI.md`, `.github/workflows/install-smoke.yml`; the repo's own `CLAUDE.md` gains the change-sweep rule this batch needed twice.
|
|
30
|
+
- **`agent.C3` fences every copy-verbatim artifact (prompt, template, file body, multi-line command block) with four backticks, never three.** Evidence: the owner asked for it after paste artifacts kept breaking — such artifacts routinely contain a fence of their own (a CLAUDE.md fragment, a skill body, a prompt with a code example), so a three-backtick wrapper closes at the inner fence and the rest renders as prose, which the reader copies incomplete without noticing. Mechanism: one line beside the existing prompt-never-hard-wrap bullet, since both exist for the same reason (the text is pasted verbatim, so the rendering must not alter it); the wider fence is CommonMark-standard and renders in every harness and terminal. Scoped to multi-line artifacts, inline code stays for a single token. Not given a `§0` penalty card and not detected by `scythe.py`: the frequency does not yet clear the `pattern.A2` bar, and a fence choice is visible at a glance.
|
|
31
|
+
|
|
32
|
+
- **`docs/ref/*.md` renamed to `fact-*.md` per `docs.A6`, each stamped (`docs.A4`) and given a trail line; the deployed TCC lookup moves to `~/.aki/akidevrule/docs/ref/fact-macos-codesign-tcc.md`.** Evidence: all four are claims about the outside world (two open standards, per-CLI permission dialects, macOS TCC), which `A6` says must carry the `fact-` name and a per-claim trail; deferred from the rule's own batch because one file is deployed by the installer. Mechanism: plain rename with every live reference updated (`CLAUDE.md`, `README.md`, `install.mjs`, `lib/permissions.mjs`, `docs/index.md`, the arch doc, `RULE-stack-tauri.md`, the cross-links); the installer already removes the deployed `docs/` tree before copying, so the old path is pruned on the next install with no extra code. The Agent Skills doc's format-identity claims had rested on secondary sources with no read date; verified 2026-09-30 against `code.claude.com/docs/en/skills` and `antigravity.google/docs/skills`, which corrected two details (Antigravity's workspace path is `.agents/skills/`, and the optional subfolder names differ per vendor and are not validated) and recorded the CLI's documented global path beside the measured `skills.json` mechanism this repo's installer actually relies on.
|
|
33
|
+
|
|
34
|
+
### Removed
|
|
35
|
+
- **`payload/index.md` — the corpus no longer ships a manifest; the router is the only resident map.** Evidence: the router's Routes table and the manifest both answered "which file, when" (`docs/plan/done/resident-context-slim-sep28.md` Item 1); the manifest had regrown to 22.5 KB, a quarter of every session's resident context, and its Purpose column restated the router clause and the file itself. Root cause: the file was promoted to an import on 2026-08-06 to carry the receipt vocabulary and Precedence, then accumulated prose because it was resident and convenient. Mechanism: each route row now carries its topic (`RULE-coding.md` · `coding`), so the receipt vocabulary lives where the routing does; § Precedence is `agent.B6` (behavior belongs in the behavior floor, `docs.A5` item 5 repointed); the Groups table and the cross-cutting lens moved to `docs/arch/corpus-map.md`, a maintainer's address map that is not installed — `pattern.A7` no longer points at it, since every domain application is already listed inline. Runtime consumers retargeted in the same change: the installer's "Rules deployed" printout (derived from `AG_RULE_MAP` and the router clauses), `aki_version_check.mjs` (intact test on `RULE-agent-behavior.md`), the CI smoke assertion, `akihelp` step 1, `payload/GEMINI.md` receipt wording. `@akinet/akimcp` tests `index.md` only as an existence fallback beside `CHANGELOG.md`, so it keeps working. Rejected: keeping a trimmed `index.md` in `payload/` (the owner's ruling: a map the model does not need belongs to the repo, not the payload); keeping the lens resident inside the router (5.8 KB for a maintainer's dedupe record; reopen if a model restates a root rule in a domain edit because the lens was absent).
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **`release_lint.py --latest` false-positive `[PARITY]` on every project with an open `[Unreleased]` section.** Evidence: running the B7-gate command on aiobox flagged `releases.json version 0.4.6 has no CHANGELOG entry` even though 0.4.6 has a full CHANGELOG entry — reproduced identically on akitao.com (real ecosystem repo, also mid-accumulation with `[Unreleased]` open). Root cause: `--latest` truncates `_changelog_blocks()` to the single newest block for the reverse `releases.json → CHANGELOG` parity check; the moment that newest block is `[Unreleased]` (the normal `release.A5` working state between releases), the truncated version list cannot contain the last *shipped* version, so the check misreports every prior release as missing. `lint_changelog` now returns both the `--latest`-scoped version list (still used for the forward "did I add this new entry to releases.json" check, which is exactly what `--latest` is meant to scope) and the full, untruncated version list; the reverse check now tests membership against the full list — the truncation still limits which `releases.json` entries get inspected (`items[:1]`), only the comparison target was wrong. Verified: `--all` output is byte-identical before/after on aiobox and 7 other ecosystem repos (zero regression); a synthetic case with a `releases.json` version absent from CHANGELOG entirely still fires `[PARITY]` in both modes (true positive preserved); a synthetic `[Unreleased]`-open-plus-matching-older-version case now exits 0 (the bug scenario, fixed). Rejected: skipping the reverse check whenever `--latest`'s top block is `Unreleased` — that would also blind the check to a `releases.json` entry added without any matching CHANGELOG entry anywhere, which is the exact drift `[PARITY]` exists to catch.
|
|
39
|
+
|
|
3
40
|
## [3.5.0] - 2026-09-27
|
|
4
41
|
|
|
5
42
|
### Added
|
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ The installer is `install.mjs` — one cross-platform Node.js program (Node stdl
|
|
|
51
51
|
|
|
52
52
|
Tooling — have these installed first:
|
|
53
53
|
|
|
54
|
-
- **Node.js 18+** — the one hard requirement to install or update. The installer and the
|
|
54
|
+
- **Node.js 18+** — the one hard requirement to install or update. The installer and the two Claude Code hooks are Node; the 18 floor is the built-in `fetch` the update check uses. `install.sh` / `install.ps1` locate `node` and stop with one clear message if it is missing.
|
|
55
55
|
- **Python 3.7+** — only to *run* the akiflow skill helper scripts (`skills/akiflow/scripts/*.py`); never needed for install or update.
|
|
56
56
|
- `git` — for the `git clone` remote install.
|
|
57
57
|
|
|
@@ -67,7 +67,7 @@ Interpreter convention (documented once): the installer and hooks run on `node`
|
|
|
67
67
|
| `akiflow` | `/akiflow` | Lead-coordinated **agent council** for work needing more than one kind of judgment. The lead's job is two laws: **ANCHOR** — the owner's verbatim message is pinned as the run's immutable first block (`council_open.py` refuses to open a room without it) and every numbered requirement must quote a fragment of it; and **JUSTIFICATION** — every seat, check and script is OFF by default and turns on only when this run produces a reason, so there are no standing seats and no roster derived from a tier. It decomposes the request into owned work items, checks a three-condition activation gate, and convenes seats from the five definitions in `~/.claude/agents/` — one batch, each seat traced to a requirement, never picked from a menu. **Two shapes, discriminated by whether anything is actually being arbitrated.** A *council* is items with adversaries, for work where two competent seats could reach different defensible answers. A *dispatch* is lanes with exclusive file ownership, for a fan-out whose answer is already knowable and whose only real hazard is two workers writing the same file — `--convene` refuses an overlapping `writes:` before a token is spent. Dispatch drops the challenger, the debate and the three-condition gate; it keeps the anchor, the quoted requirements, the `[RULES]` receipts, the durable record and the whole closure gate. It exists because 19 of 70 live rooms posted no debate turn at all and 11 of those still did substantive fan-out work, paying council overhead for machinery they never used. Orthogonally, three modes discriminated by one question, *what changes outside the room*: `discuss`, `audit` (read-only by construction), `execute` (only `aki-maker` may write). The lead does no menial work and settles what doctrine answers, escalating only a one-way door, a contradiction with documented design, or scope expansion — then writes the owner's answer back into doctrine the same turn, so a question never escalates twice. `council_verify.py` refuses closure on a missing anchor, a requirement quoting nothing the owner wrote, a declared seat that left no trace anywhere in the session, a seat with no `[RULES]` receipt, or an unanswered reminder — reading each seat's own `<seat>.md` as well as its turns, and printing `SKIP` rather than `PASS` where there was nothing to check — and deliberately requires no named seat, since an earlier version that did forced a seat to exist in a run with nothing to enforce and was gamed rather than questioned. **A read is a subscription, not a purchase** — the cost model that shapes how the room is used: every turn re-sends the whole history, so a read of size `S` at turn `t` of a `T`-turn run is charged about `S × (T − t)`, and pulling a 50k-token room at turn 50 of 200 costs ~7.5M cache-read tokens from one call. Measured on a real run with three `aki-maker` seats doing every file edit, the lead still held 70% of cache-read and 66% of output: delegation moves the work but not the money, because what a run pays for is the lead's own accumulated context. Hence `council_read.py --grep` to locate for a few hundred bytes and `--turn` to pull only what the grep pointed at. Close-out reconciles declared model tiers against actual spend, cross-CLI calls added by hand since they never appear in the transcript. Design record: [`docs/arch/akiflow.md`](docs/arch/akiflow.md). |
|
|
68
68
|
| `akithink` | `/akithink`, or self-run | Structured deep thinking: restate → goal excavation → first principles → mandatory critique → convergence into a `docs/` decision record. Self-run (model-invoked, non-interactive, decide-and-report) whenever the task is a decision rather than execution; interactive only when the owner asks. Recommends a top-tier model (Opus/Fable). |
|
|
69
69
|
| `akihtmlreport` | `/akihtmlreport` | Distills a dense analysis already in the conversation into one self-contained, ultra-wide `REPORT.html` at the project root — no new analysis, no dropped detail — then opens it locally. Exactly one per project; asks before overwriting. |
|
|
70
|
-
| `akihelp` | `/akihelp` | Live introduction to the whole installed Aki system, rendered by reading
|
|
70
|
+
| `akihelp` | `/akihelp` | Live introduction to the whole installed Aki system, rendered by reading the router's Routes table and skill frontmatters at runtime — it can never go stale. Includes a **painpoint → what to say** table (sprawling CSS, docs that no longer match code, a half-finished tree, a pre-ship check, a hard-to-reverse decision, padded or hard-wrapped output, over-guarded flows, UX friction, pricing calls) built from that live state, with any row whose target is not installed dropped rather than shown. Closes on the caveat that governs everything else: the router is always present but the `Read` of a routed file is still model-dependent, so name the rule file in the prompt whenever the load must be deterministic. |
|
|
71
71
|
| `akigitcommit` | `/akigitcommit` | Turns a messy working tree into a few clean, logically grouped Conventional Commits. Triages a half-finished tree first — finished vs mid-edit vs abandoned vs accidental, asking rather than guessing — then stages by explicit path, never `git add -A`, never pushes unasked. |
|
|
72
72
|
| `aki-article-writer` | `/aki-article-writer` or natural language | Per-project pipeline for publishable site prose (articles, news/blog posts, announcements, knowledge entries, including a release turned into a post): research & fact-verification, SEO metadata, JSON-LD schema, UX-psychology-aware content, a rendered-output pass on the built HTML before delivery, and a dedicated Image Scout subagent (Gemini Flash / Haiku) for search → download → visual inspection → ffmpeg processing → slug-named WebP output. One subagent per article; image work is always isolated to a separate lightweight subagent. |
|
|
73
73
|
| `akidevsync-notes` | natural language | Reads/edits a project's `.akidevsync/notes.json` — the per-project task list the Aki-Dev-Sync app itself writes (list/add/pin/mark-done/edit/delete tasks) via a bundled script that preserves the app's own JSON formatting, plus a workflow for cross-checking pinned notes against a shipped release (CHANGELOG + code) before marking them done. |
|
|
@@ -97,22 +97,21 @@ A catalog is not a roster. Five files on disk make it easy to pick seats from a
|
|
|
97
97
|
|
|
98
98
|
- `RULE-*.md` — constraints: what the agent must or must not do (behavior, coding, design/patterns, docs, content, stacks — Nuxt/Cloudflare + Tauri, UI, SEO, release, DB design, business/market).
|
|
99
99
|
- `METHOD-*.md` — analytical frameworks: how to reason through a specific class of problem. Heavy, loaded only when the task is genuinely analytical.
|
|
100
|
-
- `index.md` — file manifest, precedence order, cross-cutting lens.
|
|
101
100
|
|
|
102
101
|
Loading happens on two different mechanisms.
|
|
103
102
|
|
|
104
|
-
**
|
|
103
|
+
**Resident — harness-embedded.** `RULE-agent-behavior.md` and the router `skills/akirule/SKILL.md` are `@`-imported by `~/.claude/CLAUDE.md`, which Claude Code reads mechanically at session start. No model decision is involved, so the behavior floor applies to every task and the routing is always present. The router joined the imports because as a skill it went uninvoked until the owner asked for it by name. `@` imports have this effect **only** inside `CLAUDE.md` — the same syntax written into a skill body looks like an import but loads nothing, because a skill body is read only after the model has already chosen to invoke the skill.
|
|
105
104
|
|
|
106
|
-
**Everything else — routed by meaning.** Each task turn is classified by the domains it touches and the act (create, decide, audit, ship), in any language; each route carries concept signals in English and Vietnamese as evidence, never as the test, so a paraphrase routes as well as the listed word. The one model-dependent hop left is the `Read` of a routed file.
|
|
105
|
+
**Everything else — routed by meaning, and gated where the artifact gives it away.** Each task turn is classified by the domains it touches and the act (create, decide, audit, ship), in any language; each route carries concept signals in English and Vietnamese as evidence, never as the test, so a paraphrase routes as well as the listed word. The one model-dependent hop left is the `Read` of a routed file, and on Claude Code the `aki-route-guard` PreToolUse hook (`claude/hooks/aki-route-guard.mjs`) enforces it for every route with an artifact signature: the first Edit/Write of each artifact type in a session — a code file (`coding` + `pattern`), `.md` (`docs`), `CHANGELOG.md` (`release`), `.vue`/`.css` (`ui`, plus `stack` in a Nuxt project), `.rs` (`tauri`), `.sql` (`db`), `locales/` (`content`) — is denied until those files have been read in that transcript; a subagent is gated on its own transcript. Zero model hops in the check, at most one denial per artifact type per session, fail-open on any error, `AKI_ROUTE_GUARD=0` disables it. `RULE-coding.md` and `RULE-pattern-core.md` were resident imports from 2026-08-06 to 2026-09-30 because the router as a skill went uninvoked; importing the router restored the routing but not the read (measured: the model read a routed file unprompted in about one session in five — `docs/research/rule-delivery-second-hop-sep29.md`), so the gate now restores the guarantee by mechanism and the two files load only on code turns. Meaning-only routes (`think`, `proportion`, `biz`, `ux`, the audits) stay on the router alone, with sensitivity deliberately high (err toward loading — a false positive costs a few tokens, a false negative causes wrong behavior). The one deliberate exception is a lookup: a turn that only reads, counts, locates or explains what exists routes nothing, because no rule's act is performed — those turns are the majority for many users of this corpus, and the tiering exists so they pay for nothing beyond the two resident files.
|
|
107
106
|
|
|
108
|
-
- **Contextual and analytical — read on route match:** `RULE-docs.md` (structure and lifecycle, evidence-bound `ref/fact-*` fact docs, plus the docs-vs-code drift audit), `RULE-content-write.md` (UI copy and writing style, plus the content audit — canonical-term drift, density deletion test, i18n coverage, fact-check), `RULE-stack-akiNuxtCf.md`, `RULE-stack-tauri.md` (Tauri v2 + Rust: never-block-the-UI, version SSOT, target context, the macOS TCC/Gatekeeper boundary for spawned sidecars), `RULE-ui-pattern.md` (design-system layer: the subtraction pass that runs before the tier ladder, class taxonomy, tokens, variant API, and the audit playbook), `RULE-seo.md` (metadata, schema, sitemap, and URL form: relative at rest, absolute only where a consumer requires it), `RULE-release.md`, `RULE-db-design.md`, `RULE-biz.md` (market-facing decisions: positioning, pricing, audience) — plus the analytical methods (
|
|
107
|
+
- **Contextual and analytical — read on route match:** `RULE-coding.md` (code-quality floor: source of truth, changing existing code, verification and the hand-off ladder, comment budget, runtime safety), `RULE-pattern-core.md` (the 9 structural laws, decomposition, the critique gate before any abstraction), `RULE-test.md` (fewest tests: no new test by default, no new test file or folder when one fits, nothing touched the test does not own, a verdict that means what it exercised — gated on test-file edits), `RULE-docs.md` (structure and lifecycle, evidence-bound `ref/fact-*` fact docs, plus the docs-vs-code drift audit), `RULE-content-write.md` (UI copy and writing style, plus the content audit — canonical-term drift, density deletion test, i18n coverage, fact-check), `RULE-stack-akiNuxtCf.md`, `RULE-stack-tauri.md` (Tauri v2 + Rust: never-block-the-UI, version SSOT, target context, the macOS TCC/Gatekeeper boundary for spawned sidecars), `RULE-ui-pattern.md` (design-system layer: the subtraction pass that runs before the tier ladder, class taxonomy, tokens, variant API, and the audit playbook), `RULE-seo.md` (metadata, schema, sitemap, and URL form: relative at rest, absolute only where a consumer requires it), `RULE-release.md`, `RULE-db-design.md`, `RULE-biz.md` (market-facing decisions: positioning, pricing, audience) — plus the analytical methods (`METHOD-*`, loaded on route match like the rest): `METHOD-audit-flow.md` (refactors, multi-file bugs, fragile flows), `METHOD-audit-zero-trust.md` (strict mechanical-first audit: detectors before opinion, exact matches separated from pattern-level candidates), `METHOD-deep-think.md` (scope/architecture/value decisions, first-principles and critique-style thinking), `METHOD-ux-psych.md` (UX/user-behavior evaluation, onboarding and conversion flows), `METHOD-proportionality.md` (sizing a guard, limit or accepted risk against reach, capability, motive and blast radius — the lens that stops both over-engineering and client-side-limits-as-enforcement), `METHOD-audit-subtraction.md` (repo-wide "does this need to exist" sweep, terminating on two dry rounds), and `METHOD-audit-frozen-reference.md` (compliance audit for a clause naming a concrete external artifact as the canonical shape to match — resolve to an exact path, diff literally against it, never judge from memory of the rule's prose).
|
|
109
108
|
- **Full load on explicit request:** asking, in any wording, to load the whole corpus reads every `RULE-*`/`METHOD-*` file at once.
|
|
110
109
|
|
|
111
110
|
No harness magic beyond the `CLAUDE.md` import: routes are instructions telling Claude to Read the file from `~/.aki/akidevrule/` when the task's domain matches; the full-load request is the escape hatch.
|
|
112
111
|
|
|
113
112
|
### Addressing — `topic.A1`, and the `⟨Aki⟩` flag
|
|
114
113
|
|
|
115
|
-
Every rule/method file is internally organized into groups `A`/`B`/`C` and numbered items `1`/`2`/`3…`, so any single rule can be named precisely — `coding.B2` (changing existing code), `stack.C1` (canonical component names) — without touching routing or renaming any file (`topic` is the filename minus its `RULE-`/`METHOD-` prefix). The full group map
|
|
114
|
+
Every rule/method file is internally organized into groups `A`/`B`/`C` and numbered items `1`/`2`/`3…`, so any single rule can be named precisely — `coding.B2` (changing existing code), `stack.C1` (canonical component names) — without touching routing or renaming any file (`topic` is the filename minus its `RULE-`/`METHOD-` prefix). The full group map and the cross-cutting lens (which file holds the root of a subject several files touch) live in `docs/arch/corpus-map.md`, a maintainer's doc that is not installed.
|
|
116
115
|
|
|
117
116
|
Three files (`RULE-seo.md`, `RULE-release.md`, `RULE-stack-akiNuxtCf.md`) mix universal rules with content specific to Aki's own AkiNuxtCf ecosystem (usePageSeo API, releases.json schema, canonical component names, …). That ecosystem-specific content is isolated into each file's **last group**, logically flagged `⟨Aki⟩`. It stays in this public repo and auto-loads like everything else — Aki is this repo's heaviest user, so auto-load stays more valuable than a clean public/private split — but the flag marks exactly what a stripped public export would drop. Every other file, and every group outside `⟨Aki⟩`, is 100% universal.
|
|
118
117
|
|
|
@@ -138,7 +137,7 @@ A `SessionStart` hook and the installer's `--check` flag both classify install s
|
|
|
138
137
|
|
|
139
138
|
| State | Condition | Hook (SessionStart) | `install.mjs --check` |
|
|
140
139
|
|---|---|---|---|
|
|
141
|
-
| **missing** | no installed `CHANGELOG.md` (or `
|
|
140
|
+
| **missing** | no installed `CHANGELOG.md` (or `RULE-agent-behavior.md`) | announces every session — no 24h throttle | prints "not installed" + the install command |
|
|
142
141
|
| **current** | installed released semver == remote | silent | prints "up to date" (`run_install()` skips its y/n overwrite prompt only when `.version`'s `commit=` equals the checkout HEAD with a clean tree — the overwrite source is the checkout, not remote) |
|
|
143
142
|
| **update** | remote newer than installed | announces `x.y.z → a.b.c` + the update command (24h throttle) | prints `x.y.z → a.b.c` |
|
|
144
143
|
| **ahead** | installed newer than remote, or installed CHANGELOG is Unreleased-only | silent — never nag a dev machine | prints "ahead of remote" |
|
|
@@ -166,7 +165,7 @@ Install once; from then on the system has two kinds of surface. **Rules load the
|
|
|
166
165
|
|
|
167
166
|
Three habits that make the system pay off:
|
|
168
167
|
|
|
169
|
-
- **Cite rules by address, not by pasting them.** Every rule item has a stable address — `coding.B4`, `pattern.A2`, `agent.A3` — mapped in `
|
|
168
|
+
- **Cite rules by address, not by pasting them.** Every rule item has a stable address — `coding.B4`, `pattern.A2`, `agent.A3` — mapped in `docs/arch/corpus-map.md`. One address in a prompt, review comment, or commit message names an exact obligation without duplicating its text.
|
|
170
169
|
- **Bind each project with a short root `CLAUDE.md`** — project facts and stricter constraints only, referencing the shared corpus instead of copying it (see [Project binding & change policy](#project-binding--change-policy)).
|
|
171
170
|
- **Edit rules in this repo, never in the installed copies.** Everything under `~/.aki/akidevrule`, `~/.claude/skills`, and the managed parts of `~/.claude/settings.json` is overwritten on every install; the change flow is always source repo → `node install.mjs` (or `npx @akinet/akidevrule@latest`).
|
|
172
171
|
|
|
@@ -174,7 +173,6 @@ Three habits that make the system pay off:
|
|
|
174
173
|
|
|
175
174
|
```text
|
|
176
175
|
payload/ → installed to ~/.aki/akidevrule/
|
|
177
|
-
index.md
|
|
178
176
|
RULE-agent-behavior.md
|
|
179
177
|
RULE-coding.md
|
|
180
178
|
RULE-pattern-core.md
|
|
@@ -186,6 +184,7 @@ payload/ → installed to ~/.aki/akidevrule/
|
|
|
186
184
|
RULE-seo.md
|
|
187
185
|
RULE-release.md
|
|
188
186
|
RULE-db-design.md
|
|
187
|
+
RULE-test.md
|
|
189
188
|
RULE-biz.md
|
|
190
189
|
METHOD-audit-flow.md
|
|
191
190
|
METHOD-audit-zero-trust.md
|
|
@@ -193,6 +192,7 @@ payload/ → installed to ~/.aki/akidevrule/
|
|
|
193
192
|
METHOD-ux-psych.md
|
|
194
193
|
METHOD-proportionality.md
|
|
195
194
|
METHOD-audit-subtraction.md
|
|
195
|
+
METHOD-audit-frozen-reference.md
|
|
196
196
|
GEMINI.md → installed to ~/.gemini/GEMINI.md (NOT a rule file)
|
|
197
197
|
|
|
198
198
|
skills/ → shared Agent Skills corpus (SKILL.md open standard), deployed
|
|
@@ -205,6 +205,7 @@ skills/ → shared Agent Skills corpus (SKILL.md open
|
|
|
205
205
|
akiflow/scripts/council_verify.py (mechanical closure gate: ghost seats, missing evidence tags, unanswered REMINDs)
|
|
206
206
|
akiflow/scripts/scythe.py (penalty-card lint [WRAP]/[YAP] — shared engine of /akilint and the enforcer's evidence sweeps)
|
|
207
207
|
akiflow/scripts/release_lint.py (release-record lint: CHANGELOG section order/vocabulary/level, releases.json parity, type keys, highlight review — RULE-release.md C4, B7 step 4)
|
|
208
|
+
akiflow/scripts/test_lint.py (test-file lint: literal /tmp, missing temp cleanup, exit calls as verdicts; sleeps, vacuous asserts, ambient ifs, HOME reads, live URLs, ports, source pins, history comments as review — RULE-test.md D1)
|
|
208
209
|
akiflow/scripts/*.sh (transitional Unix wrappers, one per script above — each execs its .py sibling)
|
|
209
210
|
akiflow/references/harness-facts.md (subagent/cost/model facts, with sources)
|
|
210
211
|
akithink/SKILL.md
|
|
@@ -219,6 +220,8 @@ skills/ → shared Agent Skills corpus (SKILL.md open
|
|
|
219
220
|
|
|
220
221
|
scripts/ → repo-only tooling, never installed
|
|
221
222
|
test-agy-bias.sh (6-trap agy/Gemini bias regression suite, runnable by anyone with agy — docs/plan/done/agy-helpful-bias-containment.md §3)
|
|
223
|
+
second_hop_audit.py (measures, per route and era, whether Claude Code sessions read the routed rule before the first edit — docs/research/rule-delivery-second-hop-sep29.md; `--by-model` adds the per-model compaction and shell-read table behind agent.B7)
|
|
224
|
+
codex_probe.sh (Mac hand-off: records the Codex CLI version and whether the managed AGENTS.md block reaches a fresh session — spends one Codex turn)
|
|
222
225
|
|
|
223
226
|
claude/ → Claude Code-only runtime assets, installed to ~/.claude/
|
|
224
227
|
CLAUDE.md
|
|
@@ -229,14 +232,16 @@ claude/ → Claude Code-only runtime assets, installed
|
|
|
229
232
|
agents/aki-maker.md
|
|
230
233
|
hooks/aki-update-check.mjs
|
|
231
234
|
hooks/aki_version_check.mjs (shared version-status parser, imported by both the hook and install.mjs --check)
|
|
235
|
+
hooks/aki-route-guard.mjs (PreToolUse route gate: denies the first edit of an artifact type until its routed rule was Read after the last compaction)
|
|
236
|
+
hooks/aki-compact-reread.mjs (SessionStart on `compact` only: one notice that the rules read earlier left context)
|
|
232
237
|
fragments/settings.akidoc.fragment.json (illustrative reference only — never apply manually)
|
|
233
238
|
|
|
234
239
|
docs/ → repo-internal records; one TCC lookup is installed
|
|
235
240
|
index.md (master doc index)
|
|
236
|
-
arch/ (current-state design records: rule delivery, akiflow)
|
|
241
|
+
arch/ (current-state design records: rule delivery, akiflow, corpus-map — the topic.A1 address map and the cross-cutting lens)
|
|
237
242
|
plan/ · plan/done/ (execution plans; completed plans move to done/)
|
|
238
243
|
research/ (event records: frozen body, dated amendments, a successor doc when the decision changes)
|
|
239
|
-
ref/ (stable lookups; macos-codesign-tcc.md → ~/.aki/akidevrule/docs/ref/)
|
|
244
|
+
ref/ (stable lookups; fact-macos-codesign-tcc.md → ~/.aki/akidevrule/docs/ref/)
|
|
240
245
|
|
|
241
246
|
CLAUDE.md (operating rules for agents working IN this repo — not installed anywhere)
|
|
242
247
|
GEMINI.md (the per-project Antigravity bootstrap, serving this repo itself; copied into other projects by hand)
|
|
@@ -252,12 +257,12 @@ install.ps1 (thin launcher → node install.mjs)
|
|
|
252
257
|
flowchart TD
|
|
253
258
|
subgraph SRC["📦 Source: akidevrule Repo"]
|
|
254
259
|
PAYLOAD["payload/ (18 raw rule files)"]
|
|
255
|
-
TCCREF["docs/ref/macos-codesign-tcc.md"]
|
|
260
|
+
TCCREF["docs/ref/fact-macos-codesign-tcc.md"]
|
|
256
261
|
PGEMINI["payload/GEMINI.md (template)"]
|
|
257
262
|
CSKILLS["skills/ (11 skills, shared open standard)"]
|
|
258
263
|
CCLAUDE["claude/CLAUDE.md (template)"]
|
|
259
264
|
CAGENTS["claude/agents/ (5 agent definitions)"]
|
|
260
|
-
CHOOKS["claude/hooks/aki-update-check.mjs + aki_version_check.mjs (shared parser)"]
|
|
265
|
+
CHOOKS["claude/hooks/ aki-update-check.mjs + aki_version_check.mjs (shared parser) · aki-route-guard.mjs · aki-compact-reread.mjs"]
|
|
261
266
|
end
|
|
262
267
|
|
|
263
268
|
INSTALL["⚙️ install.mjs (via install.sh / install.ps1)"]
|
|
@@ -266,7 +271,7 @@ flowchart TD
|
|
|
266
271
|
%% TARGET 1: ~/.aki/akidevrule/
|
|
267
272
|
subgraph T1["📂 1. Shared SSOT Rule Corpus (~/.aki/akidevrule/)"]
|
|
268
273
|
R_CORPUS["*.md (Raw payload rules)"]
|
|
269
|
-
R_TCC["docs/ref/macos-codesign-tcc.md"]
|
|
274
|
+
R_TCC["docs/ref/fact-macos-codesign-tcc.md"]
|
|
270
275
|
R_AGSKILLS["agskills/ (Shared skill tree for AG)"]
|
|
271
276
|
R_META[".source-repo & .version"]
|
|
272
277
|
end
|
|
@@ -277,7 +282,7 @@ flowchart TD
|
|
|
277
282
|
C_LOCAL["CLAUDE.local.md (Machine local)"]
|
|
278
283
|
C_SKILLS["skills/<skill_name>/SKILL.md"]
|
|
279
284
|
C_AGENTS["agents/aki-*.md (copied per file, your own agents kept)"]
|
|
280
|
-
C_HOOKS["hooks/aki-update-check.mjs + aki_version_check.mjs"]
|
|
285
|
+
C_HOOKS["hooks/ aki-update-check.mjs + aki_version_check.mjs · aki-route-guard.mjs · aki-compact-reread.mjs"]
|
|
281
286
|
C_SET["settings.json (Permissions + Skill Overrides)"]
|
|
282
287
|
end
|
|
283
288
|
|
|
@@ -291,8 +296,9 @@ flowchart TD
|
|
|
291
296
|
end
|
|
292
297
|
|
|
293
298
|
%% TARGETS 4-6: other CLIs that natively consume the SKILL.md standard
|
|
294
|
-
subgraph T4["🧩 4. Codex CLI (~/.agents/skills/)"]
|
|
299
|
+
subgraph T4["🧩 4. Codex CLI (~/.agents/skills/ + $CODEX_HOME/)"]
|
|
295
300
|
X_SKILLS["<skill_name>/SKILL.md"]
|
|
301
|
+
X_AGENTS["AGENTS.md managed block (behavior floor + router) + config.toml project_doc_max_bytes"]
|
|
296
302
|
end
|
|
297
303
|
subgraph T5["🧩 5. Kiro CLI (~/.kiro/skills/)"]
|
|
298
304
|
K_SKILLS["<skill_name>/SKILL.md"]
|
|
@@ -309,20 +315,20 @@ flowchart TD
|
|
|
309
315
|
INSTALL -->|"sync per skill folder"| T6
|
|
310
316
|
```
|
|
311
317
|
|
|
312
|
-
Targets
|
|
318
|
+
Targets 5-6 only get the shared skill corpus (no rule corpus / no `CLAUDE.md`/`GEMINI.md`-style overrides — those CLIs have no equivalent hard-load hook this baseline plugs into yet). Target 4 also gets the behavior floor and the router as a managed block in `$CODEX_HOME/AGENTS.md` (default `~/.codex/AGENTS.md`), the one file Codex hard-loads globally — only when that directory exists, lines of your own in the file are kept, and `project_doc_max_bytes` is written to `config.toml` when absent because Codex stops loading instruction files once global plus project files pass 32 KiB (the block alone is ~36 KB). Codex expands no `@` imports and never reads Claude's global file, so copying `~/.claude/CLAUDE.md` would deliver nothing (`docs/research/codex-instruction-delivery.md`). A project's `CLAUDE.md` stays unread unless you opt in per machine with `project_doc_fallback_filenames = ["CLAUDE.md"]`; a native `AGENTS.md` in the same directory wins over it. Each sync is scoped per skill folder name via a Node `fs` copy plus a managed-names-only prune, same never-touch-the-rest guarantee as targets 2 and 3, and runs unconditionally — harmless if that CLI isn't installed on the machine, picked up the moment it is.
|
|
313
319
|
|
|
314
|
-
1. Syncs `payload/*` into `~/.aki/akidevrule/` (Node `fs` copy, excludes `ref-ECC/`), removes stale files left by renames, syncs `agskills/` for Antigravity skill inheritance, and deploys the full TCC lookup to `~/.aki/akidevrule/docs/ref/macos-codesign-tcc.md`.
|
|
320
|
+
1. Syncs `payload/*` into `~/.aki/akidevrule/` (Node `fs` copy, excludes `ref-ECC/`), removes stale files left by renames, syncs `agskills/` for Antigravity skill inheritance, and deploys the full TCC lookup to `~/.aki/akidevrule/docs/ref/fact-macos-codesign-tcc.md`.
|
|
315
321
|
2. Deploys to **all detected Claude config directories** — `~/.claude` (default primary), all existing `~/.claude*` profile variants (e.g. `~/.claude-9rt`, `~/.claude-prx`), plus `$CLAUDE_CONFIG_DIR` or `--claude-dir <path>` if provided:
|
|
316
|
-
- Syncs every skill folder under `skills/*/` (whole directory, including any `references/` or `scripts/`) into `<target>/skills/`, one named folder at a time (copy + managed-names-only prune), removing only Aki's own old/renamed skill directories (`akidoc-*`, `akiadvise`) — any other skill you already have is never touched. `skills/` is a top-level, agent-neutral folder (siblings with `payload/`, not nested under `claude/`) because SKILL.md is a shared open standard both Claude Code and Antigravity/AGY consume identically — see [docs/ref/agent-skills-standard.md](docs/ref/agent-skills-standard.md).
|
|
322
|
+
- Syncs every skill folder under `skills/*/` (whole directory, including any `references/` or `scripts/`) into `<target>/skills/`, one named folder at a time (copy + managed-names-only prune), removing only Aki's own old/renamed skill directories (`akidoc-*`, `akiadvise`) — any other skill you already have is never touched. `skills/` is a top-level, agent-neutral folder (siblings with `payload/`, not nested under `claude/`) because SKILL.md is a shared open standard both Claude Code and Antigravity/AGY consume identically — see [docs/ref/fact-agent-skills-standard.md](docs/ref/fact-agent-skills-standard.md).
|
|
317
323
|
- Copies `claude/agents/*.md` into `<target>/agents/` **file by file, never a directory mirror with `--delete`** — that folder is a shared namespace where your own agent definitions sit beside Aki's, exactly like `<target>/skills/`, so nothing you did not install is ever removed.
|
|
318
324
|
- Replaces `<target>/CLAUDE.md` with the packaged guidance (timestamped backup first), appending this machine's source-repo path and an `@<target>/CLAUDE.local.md` import.
|
|
319
325
|
- Creates `<target>/CLAUDE.local.md` **only if missing** — never overwritten afterward. On profile variants (`~/.claude-*`), the template imports `@~/.claude/CLAUDE.local.md` by default so machine-wide facts are inherited. Put per-machine/per-profile rules there; they survive every reinstall.
|
|
320
326
|
- Before the confirmation prompt or any mutation, preflights every existing JSON file it may update: each detected profile's `settings.json`, `~/.gemini/config/skills.json`, `~/.gemini/antigravity-cli/settings.json`, and `~/.gemini/settings.json`. A malformed file or non-object root aborts the install with originals untouched. After preflight, updates `<target>/settings.json` with a timestamped backup: read permission for `~/.aki/akidevrule/**`, one `Bash(<launcher> <script>*)` rule per Aki skill script per rendering (absolute and `~/`-literal — Claude Code does not expand `~` before matching), `skillOverrides.akirule = "on"`, idempotent registration of the `SessionStart` update-check hook.
|
|
321
|
-
- Installs `<target>/hooks/aki-update-check.mjs` plus its shared parser `<target>/hooks/aki_version_check.mjs
|
|
327
|
+
- Installs `<target>/hooks/aki-update-check.mjs` plus its shared parser `<target>/hooks/aki_version_check.mjs`, `<target>/hooks/aki-route-guard.mjs` registered as a `PreToolUse` hook on `Edit|MultiEdit|Write|NotebookEdit`, and `<target>/hooks/aki-compact-reread.mjs` registered as a `SessionStart` hook with matcher `compact` (all idempotent, same filter-then-push as the update check).
|
|
322
328
|
3. Writes `~/.aki/akidevrule/.version` with `installed=`/`version=`/`commit=`/`branch=` and records the source-repo path in `~/.aki/akidevrule/.source-repo` — `version=` is the just-installed CHANGELOG's latest released semver, the same value `install.mjs --check` and the hook compare against remote.
|
|
323
|
-
4. Installs `payload/GEMINI.md` to `~/.gemini/GEMINI.md` — Antigravity global behavior overrides, stamped with a version marker (`[AKIRULE-AG-OVERRIDES-…]`) on line 1. Generates one native rule file per `RULE-*`/`METHOD-*` under `~/.gemini/config/rules/` with YAML `trigger` frontmatter — `agent` `always_on`, the stacks `glob`, the rest `model_decision` — each description generated from its `akirule` route, so both harnesses route from one table. Deploys 11 skills directly to `~/.gemini/config/skills/` for native auto-discovery (synced per skill folder, same never-touch-the-rest guarantee as step 2), configures `~/.gemini/config/skills.json` with absolute paths as secondary, and merges skill execution permissions into `~/.gemini/antigravity-cli/settings.json` and `~/.gemini/settings.json` — a `command()` prefix rule for every `skills/*/scripts/*.py` per skill root, in both the expanded and the tilde-literal rendering (agy's matcher compares command strings literally — no glob expansion, and no tilde expansion in either direction — so a directory wildcard never matches and a rule only matches a command written the same way; see [docs/ref/cli-permission-allowlist-standard.md](docs/ref/cli-permission-allowlist-standard.md) §1.2) plus scoped `write_file`/`read_file` rules for the council workspace and rule corpus.
|
|
324
|
-
5. Syncs the same skill folders to `~/.agents/skills/` (Codex CLI, Cursor), `~/.kiro/skills/` (Kiro CLI), and `~/.grok/skills/` (Grok CLI) — each a plain global skills root these CLIs read natively, synced per skill folder name exactly like step 2.
|
|
325
|
-
6. Pre-allows every Aki skill script in each harness present on the machine, one adapter per rule dialect (`lib/permissions.mjs`): `~/.kiro/settings/permissions.yaml` (a marker-delimited managed block), `~/.codex/rules/akidevrule.rules` (a file akidevrule owns), `~/.cursor/cli-config.json` (`Shell(python3:<script>*)`, never a bare `Shell(python3)`), `~/.config/opencode/opencode.json` (`permission.bash`). Every rule names one exact script, in both path renderings; entries a previous install wrote are replaced, the user's own are kept. Grok CLI and Ollama have no file-based allowlist, so nothing is written for them — [docs/ref/cli-permission-allowlist-standard.md](docs/ref/cli-permission-allowlist-standard.md).
|
|
329
|
+
4. Installs `payload/GEMINI.md` to `~/.gemini/GEMINI.md` — Antigravity global behavior overrides, stamped with a version marker (`[AKIRULE-AG-OVERRIDES-…]`) on line 1. Generates one native rule file per `RULE-*`/`METHOD-*` under `~/.gemini/config/rules/` with YAML `trigger` frontmatter — `agent` `always_on`, the stacks `glob`, the rest `model_decision` — each description generated from its `akirule` route, so both harnesses route from one table. Deploys 11 skills directly to `~/.gemini/config/skills/` for native auto-discovery (synced per skill folder, same never-touch-the-rest guarantee as step 2), configures `~/.gemini/config/skills.json` with absolute paths as secondary, and merges skill execution permissions into `~/.gemini/antigravity-cli/settings.json` and `~/.gemini/settings.json` — a `command()` prefix rule for every `skills/*/scripts/*.py` per skill root, in both the expanded and the tilde-literal rendering (agy's matcher compares command strings literally — no glob expansion, and no tilde expansion in either direction — so a directory wildcard never matches and a rule only matches a command written the same way; see [docs/ref/fact-cli-permission-allowlist-standard.md](docs/ref/fact-cli-permission-allowlist-standard.md) §1.2) plus scoped `write_file`/`read_file` rules for the council workspace and rule corpus.
|
|
330
|
+
5. Syncs the same skill folders to `~/.agents/skills/` (Codex CLI, Cursor), `~/.kiro/skills/` (Kiro CLI), and `~/.grok/skills/` (Grok CLI) — each a plain global skills root these CLIs read natively, synced per skill folder name exactly like step 2. Kiro and Grok are skills-only. Codex additionally gets the managed `AGENTS.md` block and the `project_doc_max_bytes` key described above, only when `$CODEX_HOME` (default `~/.codex`) exists; the summary names the block size, the budget written or found, and a non-empty `AGENTS.override.md` that would shadow it.
|
|
331
|
+
6. Pre-allows every Aki skill script in each harness present on the machine, one adapter per rule dialect (`lib/permissions.mjs`): `~/.kiro/settings/permissions.yaml` (a marker-delimited managed block), `~/.codex/rules/akidevrule.rules` (a file akidevrule owns), `~/.cursor/cli-config.json` (`Shell(python3:<script>*)`, never a bare `Shell(python3)`), `~/.config/opencode/opencode.json` (`permission.bash`). Every rule names one exact script, in both path renderings; entries a previous install wrote are replaced, the user's own are kept. Grok CLI and Ollama have no file-based allowlist, so nothing is written for them — [docs/ref/fact-cli-permission-allowlist-standard.md](docs/ref/fact-cli-permission-allowlist-standard.md).
|
|
326
332
|
|
|
327
333
|
Re-running the installer updates the same managed files cleanly.
|
|
328
334
|
|
|
@@ -351,13 +357,15 @@ rm -rf ~/.agents/skills/{akirule,akiflow,akithink,akihtmlreport,akihelp,akigitco
|
|
|
351
357
|
rm -rf ~/.kiro/skills/{akirule,akiflow,akithink,akihtmlreport,akihelp,akigitcommit,akilint,akiopen,akiship,aki-article-writer,akidevsync-notes} # Kiro CLI
|
|
352
358
|
rm -rf ~/.grok/skills/{akirule,akiflow,akithink,akihtmlreport,akihelp,akigitcommit,akilint,akiopen,akiship,aki-article-writer,akidevsync-notes} # Grok CLI (other, non-Aki skills already in this folder are untouched)
|
|
353
359
|
rm -f ~/.claude/agents/aki-{hands,judge,conduct,challenger,maker}.md # your own agents in that folder are untouched
|
|
354
|
-
rm -f ~/.claude/hooks/aki-update-check.mjs ~/.claude/hooks/aki_version_check.mjs ~/.claude/hooks/aki-update-check.py ~/.claude/hooks/aki_version_check.py
|
|
360
|
+
rm -f ~/.claude/hooks/aki-update-check.mjs ~/.claude/hooks/aki_version_check.mjs ~/.claude/hooks/aki-route-guard.mjs ~/.claude/hooks/aki-compact-reread.mjs ~/.claude/hooks/aki-update-check.py ~/.claude/hooks/aki_version_check.py
|
|
361
|
+
# then delete the three entries whose command names those hooks from hooks.SessionStart and hooks.PreToolUse in ~/.claude/settings.json
|
|
362
|
+
# Codex: delete the `>>> akidevrule managed` … `<<< akidevrule managed` block in ~/.codex/AGENTS.md (the rest is yours), and the project_doc_max_bytes line in ~/.codex/config.toml if unwanted
|
|
355
363
|
rm -f ~/.gemini/GEMINI.md # restore from a *.akidevrule-backup-* if needed; GEMINI.local.md is left untouched
|
|
356
364
|
```
|
|
357
365
|
|
|
358
366
|
On **Windows** the same targets live under `%USERPROFILE%` (e.g. `%USERPROFILE%\.aki\akidevrule`, `%USERPROFILE%\.claude\skills\...`); remove them with `Remove-Item -Recurse -Force`.
|
|
359
367
|
|
|
360
|
-
Then remove the akidevrule block from `~/.claude/CLAUDE.md` and its entries (permission, skillOverrides, SessionStart
|
|
368
|
+
Then remove the akidevrule block from `~/.claude/CLAUDE.md` and its entries (permission, skillOverrides, SessionStart and PreToolUse hooks) from `~/.claude/settings.json` if desired. `~/.codex/rules/akidevrule.rules` is a whole file the installer owns and can simply be deleted.
|
|
361
369
|
|
|
362
370
|
## Content for dev.akitao.com
|
|
363
371
|
|
package/claude/CLAUDE.md
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
1
|
# Aki global Claude Code guidance
|
|
2
2
|
|
|
3
|
-
Keep global context small. Prefer current project files and runtime output over stale docs or memory.
|
|
4
|
-
|
|
5
|
-
## Core rules and the router — mechanically loaded, every session
|
|
6
|
-
|
|
7
|
-
@~/.aki/akidevrule/index.md
|
|
8
3
|
@~/.aki/akidevrule/RULE-agent-behavior.md
|
|
9
|
-
@~/.aki/akidevrule/RULE-coding.md
|
|
10
|
-
@~/.aki/akidevrule/RULE-pattern-core.md
|
|
11
4
|
@~/.claude/skills/akirule/SKILL.md
|
|
12
5
|
|
|
13
|
-
The harness embeds
|
|
14
|
-
|
|
15
|
-
The router is imported rather than left as a skill because a skill runs only when the model decides to invoke it, and it went uninvoked until the owner asked by name. The same failure earlier promoted `RULE-coding.md` and `RULE-pattern-core.md` to core. All five are paid for in every session; that cost is the price of the guarantee.
|
|
16
|
-
|
|
17
|
-
What stays best-effort is the second hop: a routed file enters context only when the model `Read`s it on a route match.
|
|
18
|
-
|
|
19
|
-
## Shared Aki rule source
|
|
20
|
-
|
|
21
|
-
Aki's shared rule corpus lives at `~/.aki/akidevrule`.
|
|
22
|
-
|
|
23
|
-
**IMPORTANT — editing shared rules:** The installed `~/.aki/akidevrule` directory is a **deployed copy**, not the source of truth. To change a shared rule:
|
|
24
|
-
1. Find the source repo: its absolute path on this machine is recorded in `~/.aki/akidevrule/.source-repo`, written by the installer on every install. Read that file — do not guess a location, and do not ask the user for something already recorded. Ask only if the recorded path no longer exists.
|
|
25
|
-
2. Edit under `<source-repo>/payload/` (shared rule corpus), `<source-repo>/skills/` (Agent Skills, shared with Antigravity), or `<source-repo>/claude/` (Claude Code-only runtime assets: global guidance, hooks, settings fragment).
|
|
26
|
-
3. **Read `<source-repo>/CLAUDE.md` before editing.** It carries that repo's own operating rules — which files must be updated together (`payload/index.md`, `skills/akirule/SKILL.md`, `README.md`, `CHANGELOG.md`), file-naming conventions, and non-goals. This step matters most when the request arrives from *another* project's working directory, where that file is not auto-loaded.
|
|
27
|
-
4. Run the installer to propagate changes to the installed copy — `node install.mjs` (any platform), or `./install.sh` / `.\install.ps1`.
|
|
28
|
-
|
|
29
|
-
Never edit the installed `~/.aki/akidevrule` files directly — changes will be silently overwritten on the next install.
|
|
30
|
-
|
|
31
|
-
## Named local corpora
|
|
32
|
-
|
|
33
|
-
Doc corpora that live outside any single project are often referred to by short name in conversation (e.g. "UNIDOC", "the standards doc"). Their names, paths, and usage notes are **machine-specific**, so they are recorded in `~/.claude/CLAUDE.local.md` — not in this shared file. When the user names a corpus you cannot resolve, read that file before searching the filesystem or asking.
|
|
34
|
-
|
|
35
|
-
## ref-ECC guard
|
|
36
|
-
|
|
37
|
-
`~/.aki/akidevrule/ref-ECC` is intentionally very large. Do not scan, summarize, or bulk-load it by default.
|
|
6
|
+
The harness embeds both at session start: the behavior floor and the router. Every other rule enters context when the model `Read`s it on a route match. For routes with an artifact signature the `aki-route-guard` PreToolUse hook denies the first Edit/Write of that artifact type in a session until the routed files were read after the last compaction — the deny reason names them; read them in full, then retry. Meaning-only routes stay model-dependent: route on meaning, load when the domain is in doubt. A turn that only reads, counts or explains what exists routes nothing.
|
|
38
7
|
|
|
39
|
-
|
|
8
|
+
Doc corpora named by short name in conversation ("UNIDOC", "the standards doc") are machine-specific: resolve them in `~/.claude/CLAUDE.local.md` before searching or asking.
|
|
@@ -20,7 +20,7 @@ Report which class every violation belongs to. A violation with no class attache
|
|
|
20
20
|
|
|
21
21
|
# Rules you must read before working
|
|
22
22
|
|
|
23
|
-
- `~/.aki/akidevrule/RULE-agent-behavior.md` — the behavior floor; §0 penalty cards are your vocabulary, `B5` binds you as read-only like every other judge.
|
|
23
|
+
- `~/.aki/akidevrule/RULE-agent-behavior.md` — the behavior floor; §0 penalty cards are your vocabulary, `B7` names the harness directives behind `[SKIP]`, `B5` binds you as read-only like every other judge.
|
|
24
24
|
- `~/.aki/akidevrule/RULE-coding.md` — `B4` only, the comment budget behind `[YAP]`.
|
|
25
25
|
|
|
26
26
|
# Receipt — first line of your output, always
|
|
@@ -43,6 +43,8 @@ Run it **at the end of a round, and only when the round wrote durable files.** L
|
|
|
43
43
|
|
|
44
44
|
`[FLUFF]` — padded prose that fails the deletion test — is content judgment and is yours to make by reading. No script produces it, and none ever should.
|
|
45
45
|
|
|
46
|
+
`[SKIP]` — a mandatory step (a read, a receipt, a check, a critique, a re-anchor) skipped or compressed under a harness brevity or speed directive (`agent.B7`) — is yours too. Classify it COMPLY-fail and name the harness line the transcript shows being obeyed instead; after a compaction, a missing receipt or an edit with no re-read is the first place to look.
|
|
47
|
+
|
|
46
48
|
Everything else greppable (credit trailers `agent.B4`, temp files outside the scratchpad `agent.C5`, missing evidence tags) goes to `aki-hands` with exact paths and patterns. A reminder without a quoted `file:line` is noise and does not ship.
|
|
47
49
|
|
|
48
50
|
# Output contract
|
|
@@ -36,12 +36,12 @@ Name every rule file you actually read — nothing else. You get one round, so t
|
|
|
36
36
|
|
|
37
37
|
The mandate, rule manifest, receipt, and output contract above are the same on every lane. Only the substrate changes. This file *is* the definition when the lane is an in-harness Claude subagent; on every other lane the caller pastes the same four sections into the headless prompt, because **no other CLI reads this file**.
|
|
38
38
|
|
|
39
|
-
**Position in this table is not precedence.** The size of the surface picks the lane, and for a wide read that is agy backgrounded — the discovery default (`
|
|
39
|
+
**Position in this table is not precedence.** The size of the surface picks the lane, and for a wide read that is agy backgrounded — the discovery default (`skills/akiflow/references/harness-facts.md` § Cross-CLI worker).
|
|
40
40
|
|
|
41
41
|
| Lane | Invocation | Pick it when | Context / rules the caller must pass |
|
|
42
42
|
|---|---|---|---|
|
|
43
43
|
| **Claude subagent · `haiku`** | in-harness spawn of this agent; the frontmatter carries `model: haiku` | the paths are known and few, the result must land in this session, or several hands must run **concurrently** — the Agent tool fans out natively where every headless lane needs its own backgrounding | nothing — the frontmatter carries the tools, and this body carries the manifest. Name the paths and the question in the prompt |
|
|
44
|
-
| **agy headless · `gemini-3.8-flash-high`, backgrounded** | `agy --model gemini-3.8-flash-high --mode plan --output-format json -p "<prompt>"` — **prompt last** — launched in the background, because a real sweep costs seconds to a minute and there is no reason for the caller to block on it | the discovery default (`
|
|
44
|
+
| **agy headless · `gemini-3.8-flash-high`, backgrounded** | `agy --model gemini-3.8-flash-high --mode plan --output-format json -p "<prompt>"` — **prompt last** — launched in the background, because a real sweep costs seconds to a minute and there is no reason for the caller to block on it | the discovery default (`skills/akiflow/references/harness-facts.md` § Cross-CLI worker): a wide sweep over a large surface, or the Claude quota is the constraint. ~1M context on a separate quota; `--mode plan` makes read-only mechanical rather than worded. Its weakness is skimming, so pay for it in prompt precision, not a bigger model | `~/.gemini/GEMINI.md` auto-loads the behavior baseline, so the behavior floor is free — but **name the domain rule files and the exact absolute paths anyway**: `cwd` is not a scope boundary for agy |
|
|
45
45
|
| **kiro-cli headless · `claude-sonnet-4.5`** | `kiro-cli chat --no-interactive --trust-tools=fs_read --model claude-sonnet-4.5 "<prompt>"` | a sweep that is wide **and** needs real reading comprehension — flash skims, and this lane buys a strong model on a **third** quota (owner's pick for hands, 2026-08-16). Not the cheap tier: sonnet-4.5 meters 1.3× against `qwen3-coder-next`'s 0.05×, so pick it for the comprehension, not the price | everything: no rule file loads by itself. Paste the four sections above plus exact paths. `--trust-tools=fs_read` is the read-only mechanism |
|
|
46
46
|
| **cl-9rt (Claude via proxy gateway)** | `CLAUDE_CONFIG_DIR=~/.claude-9rt claude -p --tools "Read,Grep" --model <alias> --effort low "<prompt>"` | a parallel explore lane is wanted **concurrently** with this session, on separate metering | everything, as with kiro. `cl-9rt`/`cl-9rt-min` is a **shell alias** the owner defined interactively — it does not exist in a spawned/non-interactive shell. Always run the expanded literal command shown here, never the alias name. Note the gateway may route an alias to a non-Anthropic core — treat as bandwidth, never as judgment |
|
|
47
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: aki-judge
|
|
3
|
-
description: Judge an artifact against exactly one standard, named at spawn (pattern, proportion, ux, db, seo, release, …). Returns a verdict with evidence, never a fix. Spawn one per standard rather than asking one agent to hold several.
|
|
3
|
+
description: Judge an artifact against exactly one standard, named at spawn (pattern, proportion, ux, db, seo, release, test, …). Returns a verdict with evidence, never a fix. Spawn one per standard rather than asking one agent to hold several.
|
|
4
4
|
tools: Read, Grep, Glob
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -18,6 +18,7 @@ Change exactly what was asked. No adjacent refactors, no cleanup, no renames, no
|
|
|
18
18
|
- `~/.aki/akidevrule/RULE-agent-behavior.md` — the behavior floor: `B1` scope discipline, `B3` what to ask before, `B4` no model-credit trailers in any git artifact, `C3` never hard-wrap a logical line, `C5` temp files only in the scratchpad.
|
|
19
19
|
- `~/.aki/akidevrule/RULE-coding.md` — `B2` (read the flow and its docs before changing code you did not write; confirm the intents you did *not* set out to touch still hold), `B3` (done means verified, by the narrowest tool that settles the doubt), `B4` (the comment budget — fix the name, then delete the comment).
|
|
20
20
|
- `~/.aki/akidevrule/RULE-pattern-core.md` — `C1` is the definition of done at the pattern level.
|
|
21
|
+
- `~/.aki/akidevrule/RULE-test.md` — only when the diff touches a test file, fixture or test config; the route gate denies the first such edit until it is read, so read it first.
|
|
21
22
|
- **The domain rules named in your brief** — stack, ui, db, docs, content, whichever apply. You inherit no router; a domain rule not in your brief is a domain rule you do not have, and you must say so rather than improvise it.
|
|
22
23
|
|
|
23
24
|
# Receipt — first line of your output, always
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Fires on `compact` only: rule files read before a compaction are gone from context while the summary reads as if they were not. Rationale: docs/arch/rule-delivery-architecture.md § Compaction.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
const NOTICE =
|
|
6
|
+
"[akidevrule] Context was just compacted: rule files read before this point are no longer in context, and the route gate counts reads only after the compaction. Before the next edit, re-read the routed rule files it needs and emit a [RULES] line for the set now in context; before closing a multi-step task, re-read the originating request verbatim (agent.B7).";
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const input = JSON.parse(readFileSync(0, "utf8"));
|
|
10
|
+
if (input.source === "compact") {
|
|
11
|
+
process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: NOTICE }, suppressOutput: true }) + "\n");
|
|
12
|
+
}
|
|
13
|
+
} catch {
|
|
14
|
+
/* fail silent: a notice must never block a session start */
|
|
15
|
+
}
|
|
16
|
+
process.exit(0);
|