@akinet/akidevrule 3.4.0 → 3.6.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.
@@ -66,9 +66,9 @@ function isFile(p) {
66
66
  }
67
67
  }
68
68
 
69
- /** True when installRoot looks intact enough to compare (CHANGELOG.md and index.md both present). */
69
+ /** True when installRoot looks intact enough to compare (CHANGELOG.md and the core rule both present). */
70
70
  export function localInstallPresent(installRoot) {
71
- return isFile(join(installRoot, "CHANGELOG.md")) && isFile(join(installRoot, "index.md"));
71
+ return isFile(join(installRoot, "CHANGELOG.md")) && isFile(join(installRoot, "RULE-agent-behavior.md"));
72
72
  }
73
73
 
74
74
  /** One of the STATE_* constants — see README.md "Update notifications" for the full 5-state table. */
@@ -1,6 +1,8 @@
1
1
  # Local macOS codesign and TCC
2
2
 
3
- The one AkiDevRule lookup for this chain. `tauri.B7` is the concise rule (do not delete it); the installer (`install.mjs`) deploys this file to `~/.aki/akidevrule/docs/ref/macos-codesign-tcc.md`. Evidence trail: `docs/research/macos-tcc-tauri-boundary-aug21.md`.
3
+ `updated 2026-09-30 · v3.5.0`
4
+
5
+ The one AkiDevRule lookup for this chain. `tauri.B7` is the concise rule (do not delete it); the installer (`install.mjs`) deploys this file to `~/.aki/akidevrule/docs/ref/fact-macos-codesign-tcc.md`. Evidence trail: `docs/research/macos-tcc-tauri-boundary-aug21.md`.
4
6
 
5
7
  **Stable self-signed identity keeps TCC grants across rebuilds. Apple ad-hoc (`codesign --sign -`) does not.** Artifact names, install paths, and identity names live in that project’s own docs — not here.
6
8
 
package/install.mjs CHANGED
@@ -333,15 +333,15 @@ const ROUTER_SRC = join(SKILLS_SRC, "akirule", "SKILL.md");
333
333
 
334
334
  // The router's routes table is the single routing source; AG's native rule descriptions are derived from it.
335
335
  function routerClauses() {
336
- const table = readFileSync(ROUTER_SRC, "utf-8").matchAll(/^\| `((?:RULE|METHOD)-[^`]+\.md)` \| ([^|]+) \|/gm);
336
+ const table = readFileSync(ROUTER_SRC, "utf-8").matchAll(/^\| `((?:RULE|METHOD)-[^`]+\.md)` · `[\w-]+` \| ([^|]+) \|/gm);
337
337
  return new Map([...table].map(([, file, clause]) => [file, clause.trim()]));
338
338
  }
339
339
 
340
- // Each entry: [ruleFile, trigger, globs, description] — globs is a raw JSON array string or ""; description only for core rules, which the router does not route.
340
+ // Each entry: [ruleFile, trigger, globs] — globs is a raw JSON array string or ""; every model_decision description is derived from the router's route clause.
341
341
  const AG_RULE_MAP = [
342
342
  ["RULE-agent-behavior.md", "always_on", ""],
343
- ["RULE-coding.md", "model_decision", "", "Coding philosophy, source-of-truth discipline, error handling and security. Load when writing, reviewing or refactoring code."],
344
- ["RULE-pattern-core.md", "model_decision", "", 'Universal design laws: single source of truth, Rule of Three, single-responsibility "and"-test, composition over inheritance, naming by role. Load on any structural or decomposition decision.'],
343
+ ["RULE-coding.md", "model_decision", ""],
344
+ ["RULE-pattern-core.md", "model_decision", ""],
345
345
  ["RULE-docs.md", "model_decision", ""],
346
346
  ["RULE-content-write.md", "model_decision", ""],
347
347
  ["RULE-stack-akiNuxtCf.md", "glob", '["**/*.vue", "nuxt.config.*", "wrangler.toml", "app/**", "server/**", "composables/**", "middleware/**", "plugins/**", "layouts/**"]'],
@@ -366,8 +366,7 @@ function agDestName(ruleFile) {
366
366
  return `akirule-${stem.toLowerCase()}.md`;
367
367
  }
368
368
 
369
- function agRuleDescription(ruleFile, core, clauses) {
370
- if (core) return core;
369
+ function agRuleDescription(ruleFile, clauses) {
371
370
  if (!clauses.has(ruleFile)) throw new Error(`akirule has no route for ${ruleFile}`);
372
371
  // agy denies view_file on ~/.gemini/config/rules/ (hardcoded protection boundary, measured 2026-09-26), so the description names the readable copy.
373
372
  return `Load when the task ${clauses.get(ruleFile)}: view_file ~/.aki/akidevrule/${ruleFile} (this rules directory itself is not readable).`;
@@ -380,10 +379,10 @@ function installAgRules() {
380
379
  const unmapped = listDir(join(REPO_ROOT, "payload")).filter((n) => /^(RULE|METHOD)-.*\.md$/.test(n) && !mapped.has(n));
381
380
  if (unmapped.length) throw new Error(`AG_RULE_MAP has no entry for: ${unmapped.join(", ")}`);
382
381
 
383
- const rendered = AG_RULE_MAP.map(([ruleFile, trigger, globs, core]) => {
382
+ const rendered = AG_RULE_MAP.map(([ruleFile, trigger, globs]) => {
384
383
  const lines = ["---", `trigger: ${trigger}`];
385
384
  if (globs) lines.push(`globs: ${globs}`);
386
- if (trigger !== "always_on") lines.push(`description: ${JSON.stringify(agRuleDescription(ruleFile, core, clauses))}`);
385
+ if (trigger !== "always_on") lines.push(`description: ${JSON.stringify(agRuleDescription(ruleFile, clauses))}`);
387
386
  lines.push("---", "", `<!-- Generated by akidevrule from payload/${ruleFile}. Do not edit here. -->`, "");
388
387
  lines.push(readFileSync(join(REPO_ROOT, "payload", ruleFile), "utf-8"));
389
388
  return [join(GEMINI_RULES_DIR, agDestName(ruleFile)), lines.join("\n")];
@@ -469,6 +468,26 @@ function mergeSettings(settingsPath, installRoot, claudeDir) {
469
468
  ],
470
469
  });
471
470
 
471
+ if (!Array.isArray(hooks.PreToolUse)) hooks.PreToolUse = [];
472
+ const isAkiRouteGuard = (entry) => {
473
+ try {
474
+ return (entry.hooks || []).some((h) => (h.command || "").includes("aki-route-guard"));
475
+ } catch {
476
+ return false;
477
+ }
478
+ };
479
+ hooks.PreToolUse = hooks.PreToolUse.filter((e) => !isAkiRouteGuard(e));
480
+ hooks.PreToolUse.push({
481
+ matcher: "Edit|MultiEdit|Write|NotebookEdit",
482
+ hooks: [
483
+ {
484
+ type: "command",
485
+ command: `node "${join(claudeDir, "hooks", "aki-route-guard.mjs")}"`,
486
+ timeout: 10,
487
+ },
488
+ ],
489
+ });
490
+
472
491
  writeTextLf(settingsPath, JSON.stringify(data, null, 2) + "\n");
473
492
  }
474
493
 
@@ -540,6 +559,7 @@ function installClaudeDir(claudeDir) {
540
559
  mkdirSync(hooksDest, { recursive: true });
541
560
  copyFileSync(join(REPO_ROOT, "claude", "hooks", "aki-update-check.mjs"), join(hooksDest, "aki-update-check.mjs"));
542
561
  copyFileSync(join(REPO_ROOT, "claude", "hooks", "aki_version_check.mjs"), join(hooksDest, "aki_version_check.mjs"));
562
+ copyFileSync(join(REPO_ROOT, "claude", "hooks", "aki-route-guard.mjs"), join(hooksDest, "aki-route-guard.mjs"));
543
563
  for (const legacy of ["aki-update-check.py", "aki_version_check.py"]) {
544
564
  const p = join(hooksDest, legacy);
545
565
  if (existsSync(p)) rmrf(p);
@@ -564,11 +584,11 @@ function installClaudeDir(claudeDir) {
564
584
  const localMdTilde = toTildePath(localMd);
565
585
  const ruleSourceBlock =
566
586
  "\n## akidevrule — edit source, not deployed copy (ABSOLUTE)\n\n" +
567
- `The deployed rule files at \`${INSTALL_ROOT}\` are **overwritten on every install**.\n` +
568
- "To change any shared rule:\n" +
569
- `1. Edit in the **source repo**: \`${join(REPO_ROOT, "payload")}/\`\n` +
570
- `2. Run \`${propagateCmd}\` to propagate.\n\n` +
571
- `**NEVER edit files under \`${INSTALL_ROOT}\` directly** — changes will be silently lost on the next install.\n\n` +
587
+ `The rule files at \`${INSTALL_ROOT}\` and the skills, agents and hooks under \`${toTildePath(claudeDir)}\` are deployed copies, **overwritten on every install**. To change a shared rule, skill or hook:\n` +
588
+ `1. Read \`${join(REPO_ROOT, "CLAUDE.md")}\` first — it names the files that must change together.\n` +
589
+ `2. Edit in the source repo: \`${join(REPO_ROOT, "payload")}/\` (rules), \`${join(REPO_ROOT, "skills")}/\` (skills), \`${join(REPO_ROOT, "claude")}/\` (Claude Code assets).\n` +
590
+ `3. Run \`${propagateCmd}\` to propagate.\n\n` +
591
+ `**NEVER edit the deployed copies directly** — changes are silently lost on the next install.\n\n` +
572
592
  `@${localMdTilde}\n`;
573
593
  writeTextLf(claudeMd, claudeMdSrc + ruleSourceBlock);
574
594
 
@@ -764,19 +784,12 @@ function printSummary(claudeDirs, preAllow) {
764
784
  console.log();
765
785
 
766
786
  console.log(cyanBold("Rules deployed:"));
767
- const indexPath = join(INSTALL_ROOT, "index.md");
768
- if (isFile(indexPath)) {
769
- const tierColors = [["Core", redBold], ["Contextual", yellowBold], ["Analytical", blueBold]];
770
- for (const line of readFileSync(indexPath, "utf-8").split("\n")) {
771
- const m = line.match(/^\|\s*`([^`]+)`\s*\|\s*([^|]+?)\s*\|(.+)\|/);
772
- if (m) {
773
- const fname = m[1];
774
- const tier = m[2].trim();
775
- const desc = m[3].trim();
776
- const entry = tierColors.find(([k]) => tier.startsWith(k));
777
- const tierStr = entry ? entry[1](tier.padEnd(12)) : tier.padEnd(12);
778
- console.log(` ${tierStr} ${fname.padEnd(30)} ${desc}`);
779
- }
787
+ {
788
+ const clauses = routerClauses();
789
+ for (const [ruleFile, trigger] of AG_RULE_MAP) {
790
+ const [tier, color] = trigger === "always_on" ? ["Core", redBold] : ruleFile.startsWith("METHOD-") ? ["Analytical", blueBold] : ["Contextual", yellowBold];
791
+ const desc = trigger === "always_on" ? "behavior floor — resident every session" : `loads when the task ${clauses.get(ruleFile) || "?"}`;
792
+ console.log(` ${color(tier.padEnd(12))} ${ruleFile.padEnd(34)} ${desc}`);
780
793
  }
781
794
  }
782
795
 
@@ -815,6 +828,7 @@ function printSummary(claudeDirs, preAllow) {
815
828
 
816
829
  console.log();
817
830
  console.log(cyanBold("Hooks deployed:"));
831
+ console.log(" 🚧 aki-route-guard (PreToolUse on Edit|MultiEdit|Write|NotebookEdit) — denies the first edit of an artifact type until its routed rule was Read; AKI_ROUTE_GUARD=0 disables");
818
832
  console.log(" 📢 aki-update-check (SessionStart, notify-only) — notifies when a new rule version is available");
819
833
 
820
834
  console.log(`\n${greenBold("==============================")}`);
@@ -883,8 +897,8 @@ async function runInstall(claudeDirs) {
883
897
 
884
898
  copyFileSync(join(REPO_ROOT, "CHANGELOG.md"), join(INSTALL_ROOT, "CHANGELOG.md"));
885
899
 
886
- const tccSrc = join(REPO_ROOT, "docs", "ref", "macos-codesign-tcc.md");
887
- const tccDest = join(INSTALL_ROOT, "docs", "ref", "macos-codesign-tcc.md");
900
+ const tccSrc = join(REPO_ROOT, "docs", "ref", "fact-macos-codesign-tcc.md");
901
+ const tccDest = join(INSTALL_ROOT, "docs", "ref", "fact-macos-codesign-tcc.md");
888
902
  rmrf(join(INSTALL_ROOT, "docs"));
889
903
  mkdirSync(dirname(tccDest), { recursive: true });
890
904
  copyFileSync(tccSrc, tccDest);
@@ -1,5 +1,5 @@
1
1
  // Script pre-allow for every agent harness akidevrule deploys skills to.
2
- // Matcher facts per harness: docs/ref/cli-permission-allowlist-standard.md.
2
+ // Matcher facts per harness: docs/ref/fact-cli-permission-allowlist-standard.md.
3
3
  import { existsSync, readdirSync, readFileSync, mkdirSync } from "node:fs";
4
4
  import { join, dirname, relative, isAbsolute, sep } from "node:path";
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinet/akidevrule",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "description": "Aki's shared rule corpus + Agent Skills for Claude Code, Gemini/Antigravity, Codex, Kiro, Grok, Cursor and OpenCode — install and update with one command.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -46,7 +46,7 @@
46
46
  "payload/",
47
47
  "skills/",
48
48
  "claude/",
49
- "docs/ref/macos-codesign-tcc.md",
49
+ "docs/ref/fact-macos-codesign-tcc.md",
50
50
  "CHANGELOG.md"
51
51
  ],
52
52
  "publishConfig": {
package/payload/GEMINI.md CHANGED
@@ -33,8 +33,8 @@ These directives patch Antigravity's known weak spots. They are hard-loaded (no
33
33
 
34
34
  ## 3. Always comply with the akirule corpus — and with rule 0
35
35
  - The shared rule corpus installed at `~/.aki/akidevrule/` ("akirule") applies to you, not only to other agents. When a task touches an area it covers, follow it.
36
- - **Session start, before the first task action:** `view_file` `~/.aki/akidevrule/RULE-coding.md` and `~/.aki/akidevrule/RULE-pattern-core.md` in full. They are core rules; the rules budget cannot inline them, so this read is how they enter context. Read every `~/.aki/akidevrule/` file from that directory — the copies under `~/.gemini/config/rules/` are not readable by `view_file`.
37
- - **First line of every response is the receipt** `[RULES] agent (always_on) + coding,pattern,<topics you viewed this session> (viewed)` — topic addresses from `~/.aki/akidevrule/index.md`. A rule absent from the line was not read; the line is self-reported and is a diagnostic, never proof of compliance.
36
+ - **Nothing is read at session start.** `RULE-coding.md` and `RULE-pattern-core.md` are attached natively by their rule descriptions on code turns (`akirule-coding`, `akirule-pattern-core`), like every other contextual rule; a turn that only reads, counts or explains what exists loads nothing. When a rule must be viewed, read it from `~/.aki/akidevrule/` — the copies under `~/.gemini/config/rules/` are not readable by `view_file`.
37
+ - **First line of every response is the receipt** `[RULES] agent (always_on) + <topics attached or viewed this session> (viewed)` — a topic is the rule's name stem (`akirule-coding` → `coding`), an item inside it `topic.A1`. A rule absent from the line was not read; the line is self-reported and is a diagnostic, never proof of compliance.
38
38
  - **Re-assertion of rule 0, by design:** whatever else you are doing, you comply with the prime directive. Never act outside the requested scope.
39
39
 
40
40
  ## 4. Rule 0 again — no unrequested action, at any cost
@@ -1,6 +1,6 @@
1
1
  # Core Agent Rules
2
2
 
3
- <!-- Address map: agent.§0 · agent.A1-5 · agent.B1-5 · agent.C1-5 -->
3
+ <!-- Address map: agent.§0 · agent.A1-5 · agent.B1-6 · agent.C1-5 -->
4
4
 
5
5
  ## §0. Penalty cards — one vocabulary for the highest-frequency violations
6
6
 
@@ -25,7 +25,7 @@ Being called with a card means: re-read the root rule, fix **every** instance in
25
25
  - Prefer reading current files over relying on memory
26
26
  - Use the smallest safe change that solves the task
27
27
  - Report blockers early and specifically
28
- - **Every tool call re-sends the entire conversation.** A turn is not incremental — the whole history is the input each time. So the cost of work is driven by *number of round trips*, not by how much each one does. Three habits follow, and they are not stylistic preferences:
28
+ - **Round trips are the unit of cost, not the size of one call.** Every call carries the whole history again (cached after the first turn, but re-read every time), so the work's cost follows the number of round trips. Three habits follow, and they are not stylistic preferences:
29
29
  - **Read/Edit the file, never `cat`/`sed`/`head` to print-then-read it.** Bash is for what it is uniquely good at: multi-file scans and transforms, pipes and aggregation, genuinely shell-native tasks (git, npm, processes). Shelling out to read one known file spends a round trip to obtain what one tool call already returns.
30
30
  - **Find every edit site before touching any of them, then apply the whole set in one pass.** Editing line by line as sites are discovered turns one change into N full-history round trips. If the sites are not all known yet, that is a signal to search first, not to start editing.
31
31
  - **Batch independent calls into a single turn.** Two lookups that do not depend on each other go out together; waiting for the first to issue the second pays twice for nothing.
@@ -36,7 +36,7 @@ Classify every turn before acting: is it **communication** (a question, discussi
36
36
  - **Communication → answer, do not act.** Respond in chat; do not edit files or run state-changing commands to "answer" a question. "Can we X?" / "Should we X?" is a question, not permission to do X. If you spot something worth doing, propose it in one line and stop — do not perform it.
37
37
  - **Task → execute, do not stall.** Do the requested work within scope; do not turn a clear instruction back into a proposal or a needless confirmation prompt. Report when done, then stop.
38
38
  - **Calibrate autonomy by reversibility, not by asking-always.** A reversible, in-scope action gets done and reported; only a genuine one-way door (destructive, outward-facing, scope-expanding, shared config — see B3) is worth pausing to ask. Over-asking on safe work is as much a failure as acting unasked — it trades the user's speed for no real safety.
39
- - **Four kill-tests before any question reaches the user — failing one means answer it yourself and record the answer.** Reversibility (above) is the fifth. **Impact:** if the user answers against your default, does any artifact change? "The conclusion holds either way" is a default to write down, never a question to ask. **Already authorized:** the request may have settled it — asking the user to re-confirm a course they just ordered charges them twice for one decision. **Silence is not contradiction:** a doc that does not mention X does not conflict with X; that is a one-line gap to close, i.e. a work item, not a question. **Self-sufficiency:** before the question leaves, confirm the answer is not already sitting in the three sources you are expected to have exhausted — the rule corpus (`akirule` routes it; the core files are already in context), the deep-think budget (`METHOD-deep-think.md`, run to convergence, not one shallow pass), and the owner's original request read verbatim plus the conversation history. A question those three already answer is amnesia, not a genuine unknown; re-reading them is cheaper than an interrupt and is not optional. This test only redirects a question you could answer yourself — it never overrides the escalation floor below: a real one-way door with outward effect is still asked, no matter how self-sufficient the reasoning feels. A question dressed as a "decision with a recommendation" still costs a read and an answer — the shape does not exempt it from these tests.
39
+ - **Four kill-tests before any question reaches the user — failing one means answer it yourself and record the answer.** Reversibility (above) is the fifth. **Impact:** if the user answers against your default, does any artifact change? "The conclusion holds either way" is a default to write down, never a question to ask. **Already authorized:** the request may have settled it — asking the user to re-confirm a course they just ordered charges them twice for one decision. **Silence is not contradiction:** a doc that does not mention X does not conflict with X; that is a one-line gap to close, i.e. a work item, not a question. **Self-sufficiency:** the answer is usually already in the rule corpus, in the deep-think budget run to convergence, or in the owner's request read verbatim with the history — a question those answer is amnesia, and re-reading them is cheaper than an interrupt. This test redirects only a question you could answer yourself; the escalation floor below still holds, and a question dressed as a "decision with a recommendation" is still a question.
40
40
  - **Deep-think trigger (mandatory, self-driven, non-interactive).** When any holds, Read `METHOD-deep-think.md` and run it before acting or asking: (a) about to ask or escalate to the owner; (b) about to take a one-way-door action; (c) the same fix failed a second time, or a third patch lands on one transition (`pattern.B2`); (d) two rules or instructions conflict; (e) the owner's wording admits readings that produce different artifacts; (f) the change touches documented design or goals. Depth scales with difficulty — repeat goal chain → first principles → critique → pre-mortem until the answer converges, never a fixed round count. Trivial reversible work triggers nothing.
41
41
  - **Outcome — converged: act, report the decision.** Self-answer what the analysis settles and act; for important or hard calls report one block — `Decided: X · because Y · rejected Z (why) · reopen if W` — so the owner can overrule after the fact instead of being asked before.
42
42
  - **Outcome — escalate only when:** a one-way door with outward effect (publish, tag, destructive data change); contradiction with documented design (`B3`); the `coding.C4` security/money/auth floor; the owner's own wording is ambiguous AND the readings lead to different irreversible artifacts; or deep-think does not converge (name exactly where it is stuck). What survives is asked in a presentation the user can absorb at a glance: everyday wording, jargon glossed, each option carrying its concrete consequence, plus the analysis and one recommendation. A question the user cannot understand costs two interrupts: one to ask, one to explain the asking.
@@ -50,25 +50,13 @@ The reader often context-switches across many tasks and reads in a terminal; opt
50
50
  - Write natural prose, not translated-sounding text; in Vietnamese, avoid transliterated English sentence structure. Say what happened and what it means for the reader before the mechanism.
51
51
 
52
52
  ### A5. Delegating to a worker — more throughput, less spend
53
- A worker is a subagent, or the same or another CLI called headlessly (`claude -p`, `agy -p`, equivalents).
54
-
55
- **Narrow at the source before delegating.** If one bounded command, restricted read, pipeline, or batch can return the answer — or a digest that loses nothing the decision needs — run it in this thread. Repository size and raw input size alone do not justify a worker when aggregation prevents that raw volume from entering the context.
56
-
57
- **Probe once only when the route cannot yet be specified.** If the target, question, or required output shape is unclear, run one bounded orientation probe. The probe may finish the task; never delegate work the probe already answered. If the residue still requires broad reading or comprehension that cannot be narrowed before entering a context, cross the process boundary with exact paths or targets, the exact question, and the exact output shape.
58
-
59
- **Route by context need, not by the word “exploration.”** Conversation-dependent synthesis, ambiguous classification, and per-item judgment stay with the caller; delegate only the retrieval that feeds them. Prefer a fresh worker for a precise, context-free digest. Use a fork only when a bounded bulk task genuinely needs substantial accumulated context that would be expensive to restate. A worker never delegates again unless the caller explicitly grants a fan-out with bounded depth and width.
60
-
61
- **When delegation is warranted, use the cheap wide-context tier the host resolves, one shot** — the literal command, model id and read-only mechanism per host live in one table (`skills/akiflow/references/harness-facts.md` § Model tiers › Host resolution), never in this rule. That tier holds a very large context; its failure mode is skimming, so the counter is prompt precision rather than a bigger model: name the exact paths, the exact question, and the exact output shape, and leave it nothing to improvise. Keep it to a single call — multi-turn on those CLIs degrades badly.
62
-
63
- **Know which kind of cheap you are buying.** A stateless cheap call is cheap *per call* and must re-receive its context every time. A persistent worker (`claude -p --session-id <uuid>`, later `--resume <uuid>`) is cheap *per turn after the first*, because its prefix is cached — roughly an eighth of the opening turn, then flat — and it keeps everything **it** was told, though nothing the caller knows. Use the first for one wide question, the second for a worker you will come back to. The session id is scoped to the directory it was created in.
64
- - **A worker inherits nothing** — not your context, not your rules, not your router. Name the exact rule files it must read and the exact paths or targets it must look at. "Follow the project rules" loads nothing and reads as compliance.
65
- - **Require the return leg — the worker reports what it actually received.** Naming the files is only half the loop: a brief that was ignored, a path that no longer resolves, and a rule read in full all produce output that looks the same. The worker's first line is a receipt — `[RULES] agent,coding (brief)` — naming the topic address of every rule file it read; a file the brief named that is absent from the line was not read. A worker gets one round, so this is not conditional: with no receipt, a later violation cannot be traced to either the brief or the behavior, and those two have opposite fixes. Format and the session-side duty: `skills/akirule/SKILL.md` § Load confirmation.
66
- - **Set both dials, every time: model tier and thinking effort.** An omitted parameter does not fall back to something cheap; it silently inherits the caller's own expensive settings. Silence is an expensive choice made by accident.
67
- - **Enforce read-only by mechanism, not by wording**, wherever "fixing while I'm here" would be unrecoverable — restrict the worker's tool set, or use the CLI's read-only/plan mode. A prompt-worded ban is one the model can talk itself out of.
68
- - **If a program will parse the output, use the structured-output flag** rather than asking for JSON in prose.
69
- - **Ask for the conclusion, not the dump.** Have the worker aggregate in-shell and return the answer; pulling raw search output back into the caller's context is the exact cost the delegation was meant to avoid.
70
- - **Judgment does not delegate downward.** A cheap tier is for retrieval. Deciding what a finding *means* stays with the caller — a cheap model's confident misclassification costs more than the sweep saved.
71
- - **Spend that crosses a process or CLI boundary is invisible to the caller's own accounting.** If the total matters, read each call's own usage figures and add them by hand.
53
+ A worker is a subagent, or a CLI called headlessly (`claude -p`, `agy -p`, equivalents).
54
+ - **Narrow at the source first.** If one bounded command, restricted read, pipeline or batch returns the answer — or a digest that loses nothing the decision needs — run it in this thread; repository size alone never justifies a worker when aggregation keeps the raw volume out of this context. When the target, question or output shape is unclear, run one bounded orientation probe; never delegate what the probe already answered.
55
+ - **Route by context need, not by the word "exploration".** Conversation-dependent synthesis, ambiguous classification and per-item judgment stay with the caller; delegate the retrieval that feeds them, to a fresh worker with a context-free brief. A fork only when a bulk task needs accumulated context that is expensive to restate. A worker never delegates again unless granted a fan-out with bounded depth and width.
56
+ - **A worker inherits nothing** — not your context, not your rules, not your router. Name the exact rule files it must read, the exact paths, the exact question and the exact output shape; "follow the project rules" loads nothing and reads as compliance. **Require the return leg:** the worker's first line is a receipt — `[RULES] agent,coding (brief)` — naming every rule file it read (format: `skills/akirule/SKILL.md` § Load confirmation); a file the brief named that is absent from the line was not read. Without it a later violation cannot be traced to the brief or to the behavior, and those two have opposite fixes.
57
+ - **Set both dials, every time: model tier and thinking effort.** An omitted parameter silently inherits the caller's own expensive settings. Which tier per host, the cheap wide-context tier's literal command, and what stateless versus persistent workers cost: `skills/akiflow/references/harness-facts.md` § Model tiers, § Stateful workers — never restated here.
58
+ - **Enforce read-only by mechanism, not by wording** — a restricted tool set, or the CLI's read-only/plan mode — wherever "fixing while I'm here" would be unrecoverable. If a program parses the output, use the structured-output flag. Ask for the conclusion, aggregated in-shell, never the dump.
59
+ - **Judgment does not delegate downward.** A cheap tier retrieves; what a finding *means* is decided here — a confident misclassification costs more than the sweep saved. Spend across a process boundary is invisible to the caller's accounting: read each call's usage figures and add them by hand.
72
60
 
73
61
  ## B. Scope & decision discipline
74
62
 
@@ -88,7 +76,8 @@ A worker is a subagent, or the same or another CLI called headlessly (`claude -p
88
76
 
89
77
  ### B3. Decision boundaries
90
78
  Ask before:
91
- - destructive or hard-to-reverse actions — hard-to-reverse means no backup/restore or fix-forward path exists; an action that has one (e.g. an additive migration with a backup, `stack.C8`) climbs `coding.B5`'s ladder instead of asking
79
+ - destructive or hard-to-reverse actions — hard-to-reverse means no backup/restore or fix-forward path exists; an action that has one (e.g. an additive migration with a backup, `stack.C8`) climbs `coding.B3`'s ladder instead of asking
80
+ - discarding or hiding tracked/uncommitted work: `git stash`, `checkout -- <path>`/`checkout .`, `restore .`, `reset --hard`, `clean -f[d]`, `push --force`, `branch -D` — run only on the user's explicit ask, never as a shortcut past a failing check or an obstacle (`coding.B3`'s stash-for-attribution ban is the narrow instance of this)
92
81
  - changing deployment, infrastructure, auth, billing, or shared config assumptions
93
82
  - any test, benchmark, or trial run that spends paid API credits or session quota
94
83
  - modifying shared rule files, templates, or project-wide conventions
@@ -112,6 +101,15 @@ An audit — of code, docs, versions, UI, or a working tree — **reports**; it
112
101
 
113
102
  Domain audits: `docs.C` (docs vs reality), `release.B` (version state), `release.B7` (pre-ship gate), `ui.C` (class/token), `METHOD-audit-flow.md` (flow/state).
114
103
 
104
+ ### B6. Precedence
105
+ When rules conflict, use this order:
106
+ 1. Current local source code, runtime output, and build output
107
+ 2. User's explicit instruction in the current conversation
108
+ 3. User's standing instructions — `~/.claude/CLAUDE.md` and the machine-local `~/.claude/CLAUDE.local.md`. An item marked ABSOLUTE there is never weakened by anything below it, including a shared rule that grants an autonomy other projects rely on; ordinary guidance there yields to a more specific project rule.
109
+ 4. Project `CLAUDE.md` — may add project facts and stricter constraints; must not silently weaken core safety, verification, or source-of-truth rules
110
+ 5. Aki-RULE shared files
111
+ 6. Older docs, memory, or prior conversation context
112
+
115
113
  ## C. Files & memory
116
114
 
117
115
  ### C1. File creation and naming
@@ -130,8 +128,9 @@ Domain audits: `docs.C` (docs vs reality), `release.B` (version state), `release
130
128
  - Only break lines where the structure is genuinely intentional: table rows, code blocks, and nested sub-bullets under a parent bullet.
131
129
  - When editing an existing file, match its current wrapping convention instead of imposing a new one.
132
130
  - **Prompts are the highest-frequency offender**: when asked to compose a prompt (for another AI, tool, or template), never hard-wrap it — the text is pasted verbatim, so inserted newlines become part of the artifact. One instruction/paragraph = one logical line.
131
+ - **Anything meant to be copied verbatim — a prompt, a template, a file body, a multi-line command block — is fenced with four backticks, never three.** The artifact often contains a fence of its own, and a three-backtick wrapper closes early and silently truncates what gets copied; the wider fence also marks the block as a paste-ready artifact rather than an illustration. Inline code stays for a single token.
133
132
  - This also applies inside code: do not insert a hard newline mid-comment, mid-docstring, or mid-string-literal just because the line is long — a learned training-data habit (e.g. ~80-column style conventions), not a deliberate choice for the file at hand. Let the line run long and leave wrapping to the editor/formatter, unless the surrounding file already wraps at a specific width as its own convention.
134
- - **The reverse direction is equally forbidden and more dangerous**: never collapse multiple physical lines into one just to "clean up" wrapping. First decide whether each line is *wrapped prose* (safe to rejoin into one logical line) or a *structurally atomic unit* (one line = one machine-parsed field or directive, never safe to merge). Concrete tells for the latter: YAML/TOML frontmatter (each `key: value` must keep its own line — merging fields onto one line corrupts the parser, e.g. `name: x description: y` reads as a single value, silently deleting the `description` key), `@import`/include directives (one path per line — merging several onto one line changes what a one-per-line loader parses as a single target), and any line prefixed by a format marker consumed by tooling rather than a human reader. When in doubt whether a line is prose or structure, check whether something *parses* it — if yes, never merge it.
133
+ - **The reverse direction is equally forbidden and more dangerous**: never collapse multiple physical lines into one to "clean up" wrapping. Rejoin only *wrapped prose*; never a *structurally atomic unit* — one line = one machine-parsed field or directive. Tells: YAML/TOML frontmatter (`key: value` per line — merged, `name: x description: y` parses as one value and the second key vanishes), `@import`/include directives (one path per line), any line prefixed by a marker tooling consumes. When in doubt whether something *parses* a line, it does: never merge it.
135
134
 
136
135
  ### C4. Memory discipline
137
136
  - **Never write, update, or delete a persistent memory on your own initiative — always ask the user first.** This applies to every memory file and the `MEMORY.md` index. Do not save a fact, feedback, or project note just because it seems useful.
@@ -36,15 +36,25 @@ A principle with the procedure that guarantees it — apply to any edit of code
36
36
  - **Before:** grasp the flow and intent of the code before you change it — read the docs it references first (code often points to `docs/...`), then the code, and the git history only when the logic is complex or has been reworked many times (Chesterton's Fence: know why a piece is there before you remove it).
37
37
  - **After:** confirm the intents and flows you did NOT set out to touch still hold — a fix scoped to problem X must not silently break an unrelated property Y.
38
38
 
39
- ### B3. Verification
40
- - Done means verified — never claim success from intention alone.
41
- - Verify by the **narrowest tool that actually settles the doubt**: static reading and type/lint/unit checks first. Never spin up a full build or dev server just to catch a typo a typecheck would catch.
42
- - **Never move uncommitted work to attribute a failing check.** No `git stash`/`checkout -- <path>`/`restore`/`reset`/`clean` to learn whether a typecheck or build error pre-exists: read the error against the changed files, or rebuild the committed tree in a separate `git worktree`. The working tree may hold the owner's unfinished work, and a known pre-existing failure yields no information worth risking it.
43
- - **Static reading IS verification** when the property is fully determined by visible code flow — state what was read as the evidence and close the checklist item on that evidence. Escalate a tier (typecheck → unit → runtime) only when you can name the specific doubt that tier settles.
44
- - **Never gate a done-transition on human manual testing for a check that static reading or an automated tier settles.** A plan's verify checklist stays fully detailed — the violation is not the checklist, it is parking finished work as "waiting for manual test" on items whose truth the code flow already proves. Hand the human only what genuinely needs human runtime judgment: UX feel, visual rendering, live external integration.
45
- - **Running the app is not a default verification step — but not running it does not let you claim "Done".** Starting a dev server or making live network calls stays **user-triggered**, not self-authorized (cost and side effects are the user's call). A full build and the test suite are **not** in that category — they are self-authorized, gated by the moment instead: **after edits** → typecheck/lint/related unit tests, never a full build per edit; **committing a large batch** (spans several modules, or touches build config/dependencies) → add the build; **ship/release/deploy** → full build plus full test suite is mandatory and self-authorized, commands derived per `release.B7` step 6. When a change's real risk lives **only at runtime** — hydration, layout/z-index, route/auth flow, a dynamically-built class a build step may purge — and you cannot settle it statically, you may **not** report "Done": halt and report the state as **"unverified — needs a runtime check"**, propose the exact command, and hand it to the user (see [[RULE-agent-behavior]] A3). "Done" for logic you only compiled is not done.
46
- - **When a runtime check genuinely needs a human, hand over one ledger, not one per phase.** Collect every human-run check into a single batch at the end of the run, deduped by flow: the same flow is run once, at its final state. Re-running one flow at several milestones is legitimate only when an earlier run is the baseline that makes a later regression attributable — and that reason is written beside it. Three requests to run one launch-and-navigate flow is not three times the verification, it is three interruptions.
47
- - **A change that requires a separate action against an external system to take effect is not done when the file describing that action is written.** Migrations, remote config, env vars, cache purges, cron/schedule registration — writing the script/config is not the same event as the target system actually reflecting it. Git diff and a green build both stay silent about this gap: neither touches the external system, so both can look complete while the real target (a remote database, a dashboard toggle, a deployed cron) is still on the old state. Verify the action was actually executed **against the real target**, not just that the instructions to perform it exist locally, before reporting "Done" on that change. Domain instantiation: [[RULE-release]] (a release/CHANGELOG entry is not truthful until this holds) and stack-specific execution commands (e.g. `RULE-stack-akiNuxtCf.md` §C8 for D1 migrations).
39
+ ### B3. Verification — what counts, and who performs it
40
+ Done means verified — never claim success from intention alone. Verify by the narrowest tool that settles the doubt, and hand a check to the owner only as the last rung of the ladder below.
41
+
42
+ **What counts**
43
+ - **Static reading IS verification** when the property is fully determined by visible code flow: state what was read as the evidence and close on it. Escalate a tier (typecheck → unit → runtime) only when you can name the specific doubt that tier settles; never a full build or dev server to catch what a typecheck catches.
44
+ - **Never move uncommitted work to attribute a failing check** — `agent.B3` owns the ban on `git stash`/`checkout`/`restore`/`reset`/`clean` outside an explicit ask; read the error against the changed files and the diff.
45
+ - **Self-authorized checks, gated by the moment:** after edits → typecheck/lint/related unit tests, never a full build per edit; a large batch (several modules, build config, dependencies) → add the build; ship/release/deploy → full build plus full test suite, commands per `release.B7`. A dev server or a live network call stays user-triggered (cost and side effects are the user's call).
46
+ - **When the real risk lives only at runtime** (hydration, layout/z-index, route/auth flow, a dynamically-built class a build step may purge) and cannot be settled statically, do not report Done: report "unverified — needs a runtime check" with the exact command, the expected output, and what a deviation would mean.
47
+ - **A change that needs a separate action against an external system is not done when the file describing it is written.** Migrations, remote config, env vars, cache purges, schedule registration: a green diff and a green build both stay silent about the target. Verify the action ran against the real target. Domain: [[RULE-release]] (an entry is not truthful until this holds), `stack.C8` for D1 migrations.
48
+
49
+ **Who performs it — the ladder.** A hand-off costs the owner a context switch, a read and an action, and converts a finished report into homework; it is a question in disguise and faces `agent.A3`'s kill-tests and this ladder. Climb in order, stop at the first rung that settles the doubt, record which.
50
+ 1. **Read the flow.** Most "needs testing" items are "nobody traced the call path yet".
51
+ 2. **Search the local tree** — a convention line in `README`, a CI matrix, a sibling implementation. *Worked example: "does the Windows rendering break?" was one `README` line naming this repo's `py -3` convention — no Windows machine involved.*
52
+ 3. **Search the vendor's docs and the web.** Documented vendor behavior is already answered: cite the source, write a reopen trigger, schedule no experiment.
53
+ 4. **Probe mechanically, here.** Render the other OS's path with `PureWindowsPath`, stub the clock or env var, run the pure function that builds the artifact and read the string it produces.
54
+ 5. **Run the real thing, reversibly.** First confirm the tool exists (`command -v`, `--version`) — "the owner's machine has that CLI" is the most common false hand-off. A setting that can be backed up, flipped, exercised and restored is a two-way door (`think.A1`): back up, restore in a `trap`, report before/after.
55
+ 6. **Hand off** — only what survives all five, as one ledger at the end of the run, deduped by flow: one flow runs once at its final state; a repeat is legitimate only when an earlier run is the baseline that makes a later regression attributable, with that reason written beside it. Each item names the rung that failed and why, in one line, and hands over a result to confirm — command, expected output, meaning of a deviation — never a task to design. Re-climb at closing time: later work answers earlier items.
56
+
57
+ Hand the human only what genuinely needs human runtime judgment: UX feel, visual rendering, live external integration. Never park finished work as "waiting for manual test" on items the code flow already proves. Forbidden, each a claim about rungs 3–5 that must be demonstrated: "can only be verified end-to-end", "needs a real machine", "only the owner can decide", "I don't have access to that platform". A plan ending in five owner-run items and no findings skipped rungs 1–5. None of this weakens the honesty floor: what stays unverified is reported as unverified, never as Done.
48
58
 
49
59
  ### B4. Self-documenting code — comments are a last resort
50
60
  Domain application of the density root (`agent.A4` — every line must carry information the reader does not already have); the naming root is `pattern.A7`. Penalty card: `[YAP]` (`agent` §0).
@@ -54,26 +64,6 @@ Domain application of the density root (`agent.A4` — every line must carry inf
54
64
  - Comments rot: no compiler checks a comment, so it drifts silently as the code under it changes, and a stale comment misleads worse than none — one more reason deletion is the default, and why a rationale that must stay current lives in a doc the code references ([[RULE-docs]] B3), never duplicated inline.
55
65
  - One line when a comment is genuinely needed; a rationale bigger than that lives in docs, with the comment holding only the reference (see [[RULE-docs]] B3).
56
66
 
57
- ### B5. Handing a check to the human is the last rung of a ladder, never the default
58
-
59
- `B3` decides what counts as verification; this decides **who performs it**. A hand-off is not neutral bookkeeping — it costs the owner a context switch, a read, and an action, and it converts a finished report into homework. It is a question in disguise, so it faces `agent.A3`'s kill-tests *and* this ladder first. Climb in order, stop at the first rung that settles the doubt, and record which rung settled it.
60
-
61
- 1. **Read the flow.** Static reading is verification when the property is fully determined by visible code (`B3`). Most "needs testing" items are really "nobody traced the call path yet".
62
- 2. **Search the local tree.** The answer is often already written down here — a convention line in `README`, an existing platform branch, a CI matrix, a sibling implementation. Grep before assuming it is unknown. *Worked example: "does the Windows rendering break?" was answered by one `README` line stating this repo's own `py -3` interpreter convention — no Windows machine involved.*
63
- 3. **Search the vendor's docs and the open web.** A claim about someone else's platform is settled by their published behavior, not by re-observing it locally. **A check that would only reproduce documented vendor behavior is already answered**: cite the source and write a reopen trigger instead of scheduling an experiment.
64
- 4. **Probe mechanically, right here.** Simulate the environment you do not have instead of requesting it — render the other OS's path with `PureWindowsPath`, stub the clock/env var, run the pure function that builds the artifact and read the string it produces. A derived artifact can almost always be computed without the machine that would consume it.
65
- 5. **Run the real thing, reversibly.** First **check whether the tool is actually present** (`command -v`, `--version`) — "the owner's machine has that CLI" is an assumption until the shell says otherwise, and it is the single most common false hand-off. A setting that can be backed up, flipped, exercised and restored is a two-way door (`think.A1`): that is available work, not owner work. Back up first, restore in a `trap`, and report the before/after state.
66
- 6. **Hand off** — only what survives all five.
67
-
68
- Rules for whatever residue reaches rung 6:
69
- - **Each handed-off item names the rung that failed and why**, in one line, in the artifact that carries it ("needs the paid vendor account: rung 5, no sandbox tier exposes this endpoint"). An item with no such line is a violation, not a to-do — it is indistinguishable from an item nobody tried to settle.
70
- - **Hand over a result to confirm, not a task to design.** The exact command, the expected output, and what a deviation would mean. If you cannot state the expected output, you have not finished rung 1.
71
- - **Re-climb the ladder at closing time.** A ledger that accumulated during a long run is full of items that later work made answerable; the state of knowledge at the end is not the state that filed them.
72
- - **Default to the report.** A plan whose ending is five owner-run items and no findings has usually skipped rungs 1–5. "Here is the result and what it means" is the deliverable; "please run this and tell me" is the fallback.
73
- - Forbidden rationalizations, all of which mean *the ladder was not climbed*: "can only be verified end-to-end", "needs a real machine", "only the owner can decide", "I don't have access to that platform" — each is a claim about rungs 3–5 that must be demonstrated, not asserted.
74
-
75
- None of this weakens `B3`'s honesty floor: what genuinely stays unverified is still reported as unverified and never as "Done". The target is the manufactured hand-off, not the real one.
76
-
77
67
  ## C. Runtime safety
78
68
 
79
69
  ### C1. Error handling
@@ -28,7 +28,7 @@ These rules apply to all product content: interface text, meta titles/descriptio
28
28
  ### B2. Writing style — density is enforced, not preferred
29
29
  - Prefer clear, concrete wording
30
30
  - Deletion test per sentence (domain application of `agent.A4`): a sentence ships only if cutting it loses information the reader needs. Cut preamble, filler connectives, restatement, and reassurance — length follows content, never the reverse.
31
- - First sentence carries the point (the benefit, the instruction, or the answer); detail follows. This generalizes B3's FAQ rule to all content.
31
+ - First sentence carries the point (the benefit, the instruction, or the answer); detail follows. An FAQ answer is the sharpest case: answer in the first sentence, never a "Đây là...", "According to..." preamble.
32
32
  - Avoid filler and vague marketing language unless the project explicitly wants it
33
33
  - Keep headings short and literal
34
34
  - Punctuation: Strictly limit the use of em dash (—) and en dash (–)
@@ -38,7 +38,6 @@ These rules apply to all product content: interface text, meta titles/descriptio
38
38
  - Use stable labels for repeated concepts
39
39
  - Avoid unnecessary abbreviations in user-facing text
40
40
  - Make important entity definitions obvious near the start of a page or section
41
- - FAQ answers: answer directly in the first sentence — no "Đây là...", "According to..." preamble
42
41
 
43
42
  ## C. Separation
44
43
 
@@ -47,8 +46,9 @@ These rules apply to all product content: interface text, meta titles/descriptio
47
46
  - Do not let temporary task context leak into permanent copy
48
47
 
49
48
  ### C2. Content audit
50
- Read-only (`agent.B5`). Three sweeps, each anchored to the rule it checks:
49
+ Read-only (`agent.B5`). Four sweeps, each anchored to the rule it checks:
51
50
  1. **Canonical-term drift** (A3) — grep UI strings and i18n keys for synonyms of one concept; one concept with two live labels is a finding.
52
51
  2. **Density** (B2) — deletion test per shipped sentence; preamble, restatement, and reassurance in product copy are findings.
53
52
  3. **i18n coverage** (A2) — hardcoded user-facing strings that should be keys (excluding the EN=VI exception).
53
+ 4. **Fact-check** (`agent.B2`) — every claim about a product, feature, version or number must trace to the project's `ref/fact-*` (`docs.A6`) first, then to that product's own repo or live page; a claim that cannot be traced is a finding, not a style note.
54
54
  Classify severity per `docs.C4` (wrong / stale / incomplete / cosmetic); findings spanning domains route into the `docs.C2` research+plan pair.
@@ -1,6 +1,6 @@
1
1
  # Core Docs Rules
2
2
 
3
- <!-- Address map: docs.A1-5 · docs.B1-3 · docs.C1-4 -->
3
+ <!-- Address map: docs.A1-6 · docs.B1-3 · docs.C1-4 -->
4
4
 
5
5
  ## Goals
6
6
  Docs should be readable for both humans and LLMs.
@@ -19,7 +19,7 @@ Use these short, stable topic folders:
19
19
  - `docs/feat/` — features, systems, behaviors
20
20
  - `docs/arch/` — architecture, structure, technical design
21
21
  - `docs/plan/` — plans and execution notes
22
- - `docs/ref/` — stable references, setup notes, lookup docs
22
+ - `docs/ref/` — stable lookups: commands, paths and setup steps, verified by running them; `ref/fact-*.md` holds claims about the outside world, verified by evidence (A6)
23
23
  - `docs/research/` — exploratory, comparative, or time-bound findings
24
24
 
25
25
  Do not create new top-level doc topics unless the existing set clearly fails.
@@ -32,10 +32,11 @@ Filenames across all `docs/*` never lead with a date — the content-identifying
32
32
  - For any project with a business dimension, `docs/biz/` is REQUIRED and is the spine.
33
33
  - All `arch/`, `feat/`, and `plan/` docs that touch product direction or money must reference it.
34
34
  - When code intent and a `biz/` doc disagree, the `biz/` doc wins — reconcile or escalate.
35
+ - `biz/` holds decisions, not facts: it wins because the owner chose it, never because a source proved it. A market fact the decision rests on (a competitor's price, a platform limit) belongs in `ref/fact-*` with its evidence (A6), and the `biz/` doc cites it.
35
36
 
36
- ### A4. Anchor stamp — `updated <time> <version>` on every `arch|biz|feat` doc
37
+ ### A4. Anchor stamp — `updated <time> <version>` on every `arch|biz|feat` doc and every `ref/fact-*`
37
38
 
38
- `arch/`, `biz/` and `feat/` hold current state and are the SSoT other docs and code are written against, so a reader cannot tell a still-true doc from a silently rotted one without knowing when it was last confirmed. These three folders carry a stamp; `plan/`, `research/` and `ref/` do not — the first two are event records whose own schema already dates them (B1, B2), and `ref/` is verified by running its commands, not by a date.
39
+ `arch/`, `biz/` and `feat/` hold current state and are the SSoT other docs and code are written against, so a reader cannot tell a still-true doc from a silently rotted one without knowing when it was last confirmed. These three folders carry a stamp, and so does every `ref/fact-*` doc (A6): a fact is confirmed by reading a source on a date, and the outside world moves without touching this repo. `plan/`, `research/` and the rest of `ref/` do not — the first two are event records whose own schema already dates them (B1, B2), and a command lookup is verified by running it, not by a date.
39
40
 
40
41
  **Placement** — first line of the file's own header block: immediately under the H1 for a plain Markdown doc, or as a `updated:` key in the frontmatter/description field where the file already has one. One stamp per file, never per section.
41
42
 
@@ -58,10 +59,19 @@ The harness prepends this file to every request, so every line in it is paid on
58
59
  2. **Reach** — it governs the majority of requests in this project. A line that matters to one domain belongs in the doc that domain's route loads (`feat/`, `arch/`, `biz/`, a project rule file), not here.
59
60
  3. **Not derivable** — it cannot be read from the code, the manifest (`package.json`, `Cargo.toml`), or a doc the router already loads for that task.
60
61
  4. **Not a restatement** — a shared-corpus rule is pointed at by address (`coding.B3`), never copied; a copy drifts and doubles the cost.
61
- 5. **Facts and limits, not behavior** — the file binds the project's facts (stack, reference implementation, test and compile command, ship platform, hard limits) and stricter constraints; behavior rules live in the corpus (`index.md` § Precedence). Those bindings are the router's standing signal for every task in the project.
62
+ 5. **Facts and limits, not behavior** — the file binds the project's facts (stack, reference implementation, test and compile command, ship platform, hard limits) and stricter constraints; behavior rules live in the corpus (`agent.B6` Precedence). Those bindings are the router's standing signal for every task in the project.
62
63
 
63
64
  One file is the source: a per-project `GEMINI.md` or `AGENTS.md` is a bootstrap that points at `CLAUDE.md`, never a second copy.
64
65
 
66
+ ### A6. Fact docs — `docs/ref/fact-*.md`
67
+
68
+ Three claim classes, three authorities, never interchangeable: a **biz** claim is decided by the owner and wins by decision (A3); a **decision** is reached by research and holds by its recorded reasoning (B2); a **fact** is a claim about the outside world — a vendor's behavior, a limit, a price, what a standard specifies, what an artifact of a given version contains — and holds only by evidence. A fact nobody can trace is an unverified claim: it lives in `research/` marked as such, never in `ref/fact-*`.
69
+
70
+ - **Every fact carries its own trail, on the claim, not only on the file**: the source — an official page with the date it was read, or a named artifact pinned by version with the path inside it — and the research doc and section that verified it (`research/<doc>.md § R3`). A fact with a source but no research origin was asserted, not verified.
71
+ - **Current state only; history lives in research.** The fact doc is the distilled answer (B2 Action). Every change lands through a research event — an `## Amendments` entry when the finding stands, a successor doc when it changes — and the fact doc is updated in the same edit with its stamp rewritten (A4). A fact doc edited with no research event behind it is a **Wrong** finding (C3).
72
+ - **A fact earns its row when a second consumer needs to cite it** — a rule, another doc, an audit (`content.C2`'s fact-check reads here before the product's repo or live page). A one-off finding stays in the research doc that produced it.
73
+ - **The filename declares the class**: `fact-<subject>.md`. The rest of `ref/` stays commands and setup, verified by running.
74
+
65
75
  ## B. Lifecycle & Sync
66
76
 
67
77
  ### B1. Plan lifecycle & Filename Rules
@@ -90,7 +100,7 @@ Required fields, in order:
90
100
  - **Verification** — the evidence/method that hardens the result (data, test, cross-check against another case). If not verified, say so explicitly — silence reads as certainty when it isn't.
91
101
  - **Corroborating links** — links to the evidence/cases the result rests on or conflicts with (not just a verified/unverified flag)
92
102
  6. **Decision** — the resolution reached, one of:
93
- - **Action** — link to the artifact(s) where it materialized (`arch/`, `plan/`, `feat/`, `biz/`, `ref/`, or code/commit); 0 or many. Landing in `ref/` always means a **new** clean lookup doc, never the research doc itself relocated or rewritten into ref format — `ref/` is a distilled answer, research is the narrative trail behind it.
103
+ - **Action** — link to the artifact(s) where it materialized (`arch/`, `plan/`, `feat/`, `biz/`, `ref/`, or code/commit); 0 or many. Landing in `ref/` always means a **new** clean lookup doc, never the research doc itself relocated or rewritten into ref format — `ref/` is a distilled answer, research is the narrative trail behind it. A fact lands in `ref/fact-*` (A6) with this doc's section named on the claim, so the trail runs both ways.
94
104
  - **No action** — state why explicitly, so it reads as a deliberate stop, not an abandoned doc
95
105
  - **Follow-up research** — link to the new research doc opened by this result
96
106
  - **Rejected/closed** — an option eliminated with no replacement; no link needed
@@ -139,7 +149,7 @@ Walk the topology, checking each doc against what is actually true now:
139
149
  - `docs/feat/` — the described behavior still matches what the code does
140
150
  - `docs/biz/` — where code intent contradicts it, A3 decides: the `biz/` doc wins until it is explicitly changed
141
151
  - `docs/research/` — a conclusion whose recorded context no longer holds needs a successor doc plus a `Status: superseded by` line; a claim corrected while the Decision stands needs an `## Amendments` entry plus a `Status: amended` notice; a body rewritten in place with neither is a **Wrong** finding (B2)
142
- - `docs/ref/` — commands, paths, and setup steps still run
152
+ - `docs/ref/` — commands, paths, and setup steps still run; in `ref/fact-*`, every source still resolves and still says what the claim says, every pinned artifact version is still the one in use, and every claim's research origin exists — a claim changed with no research event behind it is **Wrong** (A6)
143
153
  - Doc references inside code comments (B3) still point at a heading that exists
144
154
  - **The inverse walk — code → docs:** a complex feature or subsystem shipped with no corresponding `feat/`/`arch/` doc is an **Incomplete** finding (C4). The audit checks both directions, never only whether existing docs still hold
145
155
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- Address map: pattern.A1-8 · pattern.B1-3 · pattern.C1 -->
4
4
 
5
- **Tier: Core** — `@`-imported by `~/.claude/CLAUDE.md`, in context every session. Stack-agnostic. This file is the universal pattern philosophy — the "forest view" that keeps a codebase coherent as it grows, instead of accreting local patches. It applies to every project type: backend, API/worker, Tauri/desktop, CLI, library, DB layer, and UI.
5
+ **Tier: Contextual, gated** — routed by `akirule` on every code turn and enforced on Claude Code by the `aki-route-guard` hook, which denies the first code edit of a session until this file was read. Stack-agnostic. This file is the universal pattern philosophy — the "forest view" that keeps a codebase coherent as it grows, instead of accreting local patches. It applies to every project type: backend, API/worker, Tauri/desktop, CLI, library, DB layer, and UI.
6
6
 
7
7
  It **sharpens** `RULE-coding.md` (which owns baseline DRY/YAGNI/SRP and the Result pattern); it does not restate it. UI-specific enforcement of these same laws lives in `RULE-ui-pattern.md`.
8
8
 
@@ -19,7 +19,7 @@ These are constraints on **structure and reuse**, not style. Reach for this file
19
19
 
20
20
  ---
21
21
 
22
- ## A. The 8 laws — checkable, stack-agnostic
22
+ ## A. The 9 laws — checkable, stack-agnostic
23
23
 
24
24
  **A1 — Single Source of Truth.** Every value, rule, or decision that can change lives in exactly one place; everything else references it. This covers config, constants, types, enums, business thresholds, and visual tokens — not just one category. A value written twice is a future inconsistency, not a convenience.
25
25
 
@@ -35,10 +35,12 @@ These are constraints on **structure and reuse**, not style. Reach for this file
35
35
  **A6 — Stable boundaries between modules.** Split along independent responsibilities/domains (bounded context). Modules talk through a narrow, explicit contract — a stable ID, a typed interface, a `Result` — and never reach into another module's internals. Volatile details (provider SDKs, frameworks, transport) sit at the edges behind a boundary; stable abstractions sit at the core, and dependencies point inward toward them.
36
36
 
37
37
  **A7 — Name by role, never by concrete value.** Name things for what they *mean*, not what they *currently are*: `retryLimit` not `three`, `PrimaryAction` not `BlueButton`, `AuthBoundary` not `FirebaseWrapper`. Value-names rot the instant the value changes and force codebase-wide find-and-replace.
38
- - *Root rule for naming.* Every other naming item in this corpus (`agent.C1` file names, `ui.A` tokens, `stack.C1` component names, `release.A3` version/tag format, `content` semantic stability) is a **domain application** of A7, not a competing rule — do not restate A7 in them, and do not move them out of their domain. Address map: `index.md` § Cross-cutting lens.
38
+ - *Root rule for naming.* Every other naming item in this corpus (`agent.C1` file names, `ui.A` tokens, `stack.C1` component names, `release.A3` version/tag format, `content` semantic stability) is a **domain application** of A7, not a competing rule — do not restate A7 in them, and do not move them out of their domain.
39
39
 
40
40
  **A8 — One flow, made natural — not guarded.** When the same guard / check / fallback keeps reappearing around a path, the path's shape is wrong. Reshape the flow so the correct behavior is automatic; do not stack more enforcement on a weak path. "Correct" is measured against the project's pinned facts (`coding.C1`), so a guard for a state those facts rule out is a patch, not a flow. Full method: `METHOD-audit-flow.md`.
41
41
 
42
+ **A9 — Draft, then commit once.** Anything still being explored — a gesture in progress, a form being typed, a version being accumulated, a question being weighed — lives in a draft owned by the unit showing it. The record (shared state, storage, IPC, network, git, a released version) changes once, at an explicit commit event, from the draft. Cancel discards the draft; if cancel needs an undo, the two phases were merged.
43
+
42
44
  ---
43
45
 
44
46
  ## B. Decomposition & the forest pass