@akinet/akidevrule 3.0.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 +835 -0
- package/LICENSE +21 -0
- package/README.md +356 -0
- package/claude/CLAUDE.md +40 -0
- package/claude/agents/aki-challenger.md +38 -0
- package/claude/agents/aki-conduct.md +54 -0
- package/claude/agents/aki-hands.md +59 -0
- package/claude/agents/aki-judge.md +37 -0
- package/claude/agents/aki-maker.md +36 -0
- package/claude/fragments/settings.akidoc.fragment.json +15 -0
- package/claude/hooks/aki-update-check.mjs +160 -0
- package/claude/hooks/aki_version_check.mjs +83 -0
- package/docs/ref/macos-codesign-tcc.md +59 -0
- package/install.mjs +1067 -0
- package/install.ps1 +11 -0
- package/install.sh +12 -0
- package/package.json +52 -0
- package/payload/GEMINI.md +147 -0
- package/payload/METHOD-audit-flow.md +147 -0
- package/payload/METHOD-audit-subtraction.md +67 -0
- package/payload/METHOD-audit-zero-trust.md +49 -0
- package/payload/METHOD-deep-think.md +172 -0
- package/payload/METHOD-proportionality.md +62 -0
- package/payload/METHOD-ux-psych.md +60 -0
- package/payload/RULE-agent-behavior.md +138 -0
- package/payload/RULE-biz.md +51 -0
- package/payload/RULE-coding.md +130 -0
- package/payload/RULE-content-write.md +54 -0
- package/payload/RULE-db-design.md +26 -0
- package/payload/RULE-docs.md +144 -0
- package/payload/RULE-pattern-core.md +80 -0
- package/payload/RULE-release.md +215 -0
- package/payload/RULE-seo.md +173 -0
- package/payload/RULE-stack-akiNuxtCf.md +179 -0
- package/payload/RULE-stack-tauri.md +59 -0
- package/payload/RULE-ui-pattern.md +167 -0
- package/payload/index.md +91 -0
- package/skills/aki-article-writer/SKILL.md +50 -0
- package/skills/aki-article-writer/references/article-workflow.md +377 -0
- package/skills/akidevsync-notes/SKILL.md +48 -0
- package/skills/akidevsync-notes/scripts/notes_cli.py +212 -0
- package/skills/akiflow/SKILL.md +221 -0
- package/skills/akiflow/references/harness-facts.md +215 -0
- package/skills/akiflow/scripts/council-cost.sh +4 -0
- package/skills/akiflow/scripts/council-open.sh +4 -0
- package/skills/akiflow/scripts/council-read.sh +4 -0
- package/skills/akiflow/scripts/council-verify.sh +4 -0
- package/skills/akiflow/scripts/council_cost.py +149 -0
- package/skills/akiflow/scripts/council_open.py +323 -0
- package/skills/akiflow/scripts/council_read.py +148 -0
- package/skills/akiflow/scripts/council_verify.py +315 -0
- package/skills/akiflow/scripts/scythe.py +307 -0
- package/skills/akiflow/scripts/scythe.sh +4 -0
- package/skills/akigitcommit/SKILL.md +85 -0
- package/skills/akihelp/SKILL.md +47 -0
- package/skills/akihtmlreport/SKILL.md +59 -0
- package/skills/akilint/SKILL.md +29 -0
- package/skills/akirule/SKILL.md +155 -0
- package/skills/akiship/SKILL.md +55 -0
- package/skills/akithink/SKILL.md +59 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Core Coding Rules
|
|
2
|
+
|
|
3
|
+
<!-- Address map: coding.A1-3 · coding.B1-4 · coding.C1-5 -->
|
|
4
|
+
|
|
5
|
+
## A. Philosophy & source of truth
|
|
6
|
+
|
|
7
|
+
### A1. Language
|
|
8
|
+
- Code and comments: English only
|
|
9
|
+
- Commit messages: English, imperative style
|
|
10
|
+
|
|
11
|
+
### A2. Philosophy
|
|
12
|
+
- Single-maintainer friendly — about who maintains, not how many use; never an excuse to cut UX
|
|
13
|
+
- MVP-first
|
|
14
|
+
- DRY, but no abstraction for its own sake
|
|
15
|
+
- YAGNI
|
|
16
|
+
- Default to simple, direct solutions
|
|
17
|
+
|
|
18
|
+
### A3. Source of truth
|
|
19
|
+
Priority order:
|
|
20
|
+
1. Local source code, type definitions, runtime output, and build output
|
|
21
|
+
2. Official documentation
|
|
22
|
+
3. Live observed results
|
|
23
|
+
|
|
24
|
+
Project docs and memory are useful context, not final truth.
|
|
25
|
+
|
|
26
|
+
## B. Quality & changing code
|
|
27
|
+
|
|
28
|
+
### B1. Code quality
|
|
29
|
+
- Naming: `pattern.A7` is the root rule — not restated here
|
|
30
|
+
- Prefer one clear responsibility per function/module
|
|
31
|
+
- Modularize only when it improves clarity, reuse, or testability
|
|
32
|
+
- Prefer existing code and patterns over re-implementation
|
|
33
|
+
|
|
34
|
+
### B2. Changing existing code
|
|
35
|
+
A principle with the procedure that guarantees it — apply to any edit of code you did not just write:
|
|
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
|
+
- **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
|
+
|
|
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
|
+
- **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.
|
|
43
|
+
- **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.
|
|
44
|
+
- **Running the app is not a default verification step — but not running it does not let you claim "Done".** Starting a dev server, making live network calls, or driving a full build/headless screenshot is **user-triggered**, not self-authorized (cost and side effects are the user's call). 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.
|
|
45
|
+
- **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.
|
|
46
|
+
- **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).
|
|
47
|
+
|
|
48
|
+
### B4. Self-documenting code — comments are a last resort
|
|
49
|
+
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).
|
|
50
|
+
- Naming and shape come first: a comment that explains *what* a block does is a failed name or a failed extraction — fix the name/structure (`pattern.A7`, `pattern.A3`), then delete the comment. Clean flow plus role-named functions and variables need no narration.
|
|
51
|
+
- A comment may state only what the code cannot say: a non-obvious constraint, an external contract, a genuine why. Never narrate the next line, restate the signature, or record change history.
|
|
52
|
+
- Deletion test, per comment: if removing it loses nothing a reader needs beyond what the code already says, remove it. Default is silence — comment density is a smell, not a virtue.
|
|
53
|
+
- 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.
|
|
54
|
+
- 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).
|
|
55
|
+
|
|
56
|
+
### B5. Handing a check to the human is the last rung of a ladder, never the default
|
|
57
|
+
|
|
58
|
+
`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.
|
|
59
|
+
|
|
60
|
+
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".
|
|
61
|
+
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.*
|
|
62
|
+
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.
|
|
63
|
+
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.
|
|
64
|
+
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.
|
|
65
|
+
6. **Hand off** — only what survives all five.
|
|
66
|
+
|
|
67
|
+
Rules for whatever residue reaches rung 6:
|
|
68
|
+
- **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.
|
|
69
|
+
- **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.
|
|
70
|
+
- **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.
|
|
71
|
+
- **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.
|
|
72
|
+
- 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.
|
|
73
|
+
|
|
74
|
+
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.
|
|
75
|
+
|
|
76
|
+
## C. Runtime safety
|
|
77
|
+
|
|
78
|
+
### C1. Error handling
|
|
79
|
+
- Validate at system boundaries: user input, external APIs, filesystem, network, persistence
|
|
80
|
+
- Do not add defensive guards for impossible internal states — and size the ones that do guard a reachable state against who can actually reach it (`METHOD-proportionality.md`), instead of adding protection by reflex
|
|
81
|
+
- Fail loudly in development when it helps reveal broken assumptions
|
|
82
|
+
- Keep production failures safe and user-appropriate
|
|
83
|
+
- **Never fabricate mock/fixture data as a runtime fallback for a missing dependency** (DB, API, service binding). Throw/return a real error instead. If a local dev environment genuinely lacks that dependency, fix the environment itself (real local instance, proper binding/proxy) — don't paper over it with fake data. Verify the dependency is actually unavailable by reading how the runtime/framework wires it in dev before assuming a fallback is needed at all.
|
|
84
|
+
|
|
85
|
+
### C2. Result pattern for external calls
|
|
86
|
+
When calling external APIs, Firebase, or any fallible I/O at a system boundary, return a Result type instead of throwing:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
type Result<T> = { ok: true; data: T } | { ok: false; error: string }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- The function that owns the boundary (composable, service module) does the try/catch once and returns Result
|
|
93
|
+
- Callers check `.ok` before using `.data` — no try/catch spread across UI or business logic
|
|
94
|
+
- TypeScript narrows the type correctly after the `.ok` check — no `data!` assertions needed
|
|
95
|
+
- For batch calls: each item returns its own Result; one failure does not crash the batch
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
// ✅ boundary function — catches once
|
|
99
|
+
async function fetchUser(uid: string): Promise<Result<User>> {
|
|
100
|
+
try {
|
|
101
|
+
const doc = await getDoc(ref('users', uid))
|
|
102
|
+
return { ok: true, data: doc.data() as User }
|
|
103
|
+
} catch (e: any) {
|
|
104
|
+
return { ok: false, error: e.code ?? 'unknown' }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ✅ caller — no try/catch needed
|
|
109
|
+
const result = await fetchUser(uid)
|
|
110
|
+
if (!result.ok) return showError(result.error)
|
|
111
|
+
doSomethingWith(result.data) // TypeScript knows this is User
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### C3. Performance
|
|
115
|
+
- Minimize query/call count and CPU cost **incrementally, everywhere** — not just identified hot paths
|
|
116
|
+
- Prefer flat, non-correlated queries over nested CTEs or per-row correlated subqueries; push merge/aggregation logic to plain application code when data volume makes that cheap and clearer
|
|
117
|
+
- Before shipping a nested/correlated query, ask: could two flat queries + an application-layer merge replace this more simply and just as fast?
|
|
118
|
+
|
|
119
|
+
### C4. Security
|
|
120
|
+
- Sanitize external input
|
|
121
|
+
- Never expose secrets in client code
|
|
122
|
+
- Avoid command injection, XSS, SQL injection, unsafe redirects, and token leakage
|
|
123
|
+
- Treat generated files, external data, and user-provided content as untrusted until validated
|
|
124
|
+
|
|
125
|
+
### C5. Unicode / UTF-8 safety
|
|
126
|
+
A string and its byte representation are different things; nearly every Unicode bug comes from conflating them. Applies to every runtime, and bites hardest where there is no Node `Buffer` to hide it (e.g. Cloudflare Workers).
|
|
127
|
+
- **base64 / JWT / cookie payloads:** `atob()`/`btoa()` are Latin1-only, not UTF-8 codecs — `JSON.parse(atob(jwt))` silently mojibakes non-ASCII text (accented names, emoji) and `btoa()` throws on codepoints > U+00FF. Decode via `new TextDecoder().decode(bytes)`, encode via `new TextEncoder().encode(str)` before base64.
|
|
128
|
+
- **Compare / store / dedupe / keys:** normalize first with `str.normalize('NFC')`. The same visible text (e.g. "Nguyễn") can be two different byte sequences, so an un-normalized equality check, unique key, or dedupe treats identical-looking values as different.
|
|
129
|
+
- **Length limits & sizes:** measure bytes, not `str.length` (which counts UTF-16 units) — use `new TextEncoder().encode(str).length` for body size, storage/field limits, and `Content-Length`.
|
|
130
|
+
- **Truncating text:** never slice by index into the middle of a character — `slice`/`substring` split accented characters and emoji into `�`. Iterate codepoints (`[...str]`) when cutting previews or slugs.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Core Content Rules
|
|
2
|
+
|
|
3
|
+
<!-- Address map: content.A1-3 · content.B1-3 · content.C1-2 -->
|
|
4
|
+
|
|
5
|
+
## A. Content principles
|
|
6
|
+
|
|
7
|
+
### A1. Scope
|
|
8
|
+
These rules apply to all product content: interface text, meta titles/descriptions, FAQ answers, JSON-LD text fields, article copy, and empty states. All of these are "content" — the channel (visible UI, SERP snippet, schema bot) does not change the authoring principles.
|
|
9
|
+
|
|
10
|
+
### A2. Interface text
|
|
11
|
+
- Use the current UI language
|
|
12
|
+
- Small local strings may stay inline
|
|
13
|
+
- Shared or repeated strings should use i18n keys. Exception: Text content that is exactly the same in both EN/VI should be directly hardcoded in the UI.
|
|
14
|
+
|
|
15
|
+
### A3. Semantic stability
|
|
16
|
+
- Use one canonical term for one concept across the product
|
|
17
|
+
- Avoid synonyms for the same action unless the context truly differs
|
|
18
|
+
- Keep labels stable so users, translators, tests, and LLMs can map concepts reliably
|
|
19
|
+
|
|
20
|
+
## B. Style & patterns
|
|
21
|
+
|
|
22
|
+
### B1. Interface text patterns
|
|
23
|
+
- Action buttons should usually start with verbs
|
|
24
|
+
- Field labels and setting names should usually be noun-based
|
|
25
|
+
- Error messages should state the problem first, then the next action if needed
|
|
26
|
+
- Empty states should explain what is missing and what the user can do next
|
|
27
|
+
|
|
28
|
+
### B2. Writing style — density is enforced, not preferred
|
|
29
|
+
- Prefer clear, concrete wording
|
|
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.
|
|
32
|
+
- Avoid filler and vague marketing language unless the project explicitly wants it
|
|
33
|
+
- Keep headings short and literal
|
|
34
|
+
- Punctuation: Strictly limit the use of em dash (—) and en dash (–)
|
|
35
|
+
|
|
36
|
+
### B3. Human + LLM readability
|
|
37
|
+
- Prefer explicit nouns over clever wording
|
|
38
|
+
- Use stable labels for repeated concepts
|
|
39
|
+
- Avoid unnecessary abbreviations in user-facing text
|
|
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
|
+
|
|
43
|
+
## C. Separation
|
|
44
|
+
|
|
45
|
+
### C1. Separation
|
|
46
|
+
- Do not mix chat wording into product content
|
|
47
|
+
- Do not let temporary task context leak into permanent copy
|
|
48
|
+
|
|
49
|
+
### C2. Content audit
|
|
50
|
+
Read-only (`agent.B5`). Three sweeps, each anchored to the rule it checks:
|
|
51
|
+
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
|
+
2. **Density** (B2) — deletion test per shipped sentence; preamble, restatement, and reassurance in product copy are findings.
|
|
53
|
+
3. **i18n coverage** (A2) — hardcoded user-facing strings that should be keys (excluding the EN=VI exception).
|
|
54
|
+
Classify severity per `docs.C4` (wrong / stale / incomplete / cosmetic); findings spanning domains route into the `docs.C2` research+plan pair.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Database Design Rules
|
|
2
|
+
|
|
3
|
+
<!-- Address map: db.A1-4 · db.B1 -->
|
|
4
|
+
|
|
5
|
+
**Tier: Contextual** — load when designing a schema, writing a migration, or refactoring a database layer. Do not load by default on every task.
|
|
6
|
+
|
|
7
|
+
## A. Data principles
|
|
8
|
+
|
|
9
|
+
### A1. Immutability & Event Sourcing
|
|
10
|
+
For business domains with transactions or mutable-looking state (wallets/credits, transaction history, audit logs): never mutate state directly — only append action records (append-only log). Current balance/state is a materialized view derived by replaying/summing the log. On error, replay the log instead of patching state by hand.
|
|
11
|
+
|
|
12
|
+
Exempt: read-only, display-only, or purely static data — this pattern is for domains that track change over time, not for content that doesn't have meaningful history.
|
|
13
|
+
|
|
14
|
+
### A2. First Normal Form (atomicity)
|
|
15
|
+
A column holds one atomic value. Do not stuff a JSON blob into a column as a "black box" — it breaks indexing and costs CPU/RAM to parse on every read. JSON in a column is acceptable only for data that is genuinely unstructured and never queried/filtered by its internal content.
|
|
16
|
+
|
|
17
|
+
### A3. Bounded Context (DDD)
|
|
18
|
+
Split databases/tables along independent business boundaries. Different modules/domains link to each other only through a stable ID — never reach into another domain's internal data directly.
|
|
19
|
+
|
|
20
|
+
### A4. Flat queries, merge in the application layer
|
|
21
|
+
Prefer flat, non-correlated queries over nested CTEs or per-row correlated subqueries; push merge/aggregation logic into plain application code when data volume makes that cheap and clearer. Apply this everywhere, not just to already-identified hot paths — see RULE-coding.md (Performance section) for the general principle.
|
|
22
|
+
|
|
23
|
+
## B. Unicode
|
|
24
|
+
|
|
25
|
+
### B1. The DB is not your Unicode safety net
|
|
26
|
+
SQLite/D1 stores UTF-8 natively and has no `utf8` vs `utf8mb4` trap, so it is easy to assume "D1 → no Unicode bugs". False: the DB faithfully stores whatever bytes it is handed, including already-corrupt ones. Text corruption (mojibake, un-normalized duplicates) happens one layer up, in the application code that decodes/compares the string before the `INSERT` — fix it there, per RULE-coding.md (Unicode / UTF-8 safety), not in the schema. The one schema-level Unicode concern is on MySQL/MariaDB: use `utf8mb4`, never the 3-byte `utf8`, or emoji and some CJK truncate.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Core Docs Rules
|
|
2
|
+
|
|
3
|
+
<!-- Address map: docs.A1-4 · docs.B1-3 · docs.C1-4 -->
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
Docs should be readable for both humans and LLMs.
|
|
7
|
+
|
|
8
|
+
## A. Index & Structure
|
|
9
|
+
|
|
10
|
+
### A1. Index
|
|
11
|
+
- `docs/index.md` is the master index
|
|
12
|
+
- Update it when docs or code changes affect discoverability
|
|
13
|
+
- Index entries should be short and descriptive
|
|
14
|
+
|
|
15
|
+
### A2. Topic folders
|
|
16
|
+
Use these short, stable topic folders:
|
|
17
|
+
|
|
18
|
+
- `docs/biz/` — business backbone: identity, USP, positioning, monetization (MANDATORY for any project with a business dimension)
|
|
19
|
+
- `docs/feat/` — features, systems, behaviors
|
|
20
|
+
- `docs/arch/` — architecture, structure, technical design
|
|
21
|
+
- `docs/plan/` — plans and execution notes
|
|
22
|
+
- `docs/ref/` — stable references, setup notes, lookup docs
|
|
23
|
+
- `docs/research/` — exploratory, comparative, or time-bound findings
|
|
24
|
+
|
|
25
|
+
Do not create new top-level doc topics unless the existing set clearly fails.
|
|
26
|
+
|
|
27
|
+
`biz/`, `feat/`, and `arch/` hold only current/target state — never accumulate history or superseded reasoning (`research/` is where that lives, see B2). Threshold: a rationale that fits in one sentence may stay inline (e.g. `(chose D1 over Postgres — serverless-native, no extra infra)`); a rationale that needs its own strategy, comparison, or verification to be trustworthy belongs in `research/` instead, with the doc here holding only the conclusion and a link.
|
|
28
|
+
|
|
29
|
+
Filenames across all `docs/*` never lead with a date — the content-identifying name comes first: concise, precise, and unique to that file's own content (short preferred). Dates live in the doc's own header stamp (A4), not the filename. A compact date suffix (abbreviated month + day, no year, no separator — e.g. `jun24`, `jul27`) may be appended at the very end as a lightweight, optional disambiguator (existing example: `docs/plan/done/improve-jun24.md`) — separate from the domain-specific supersede-chain naming already defined for `plan/` (B1, version-increment) and `research/` (B2, ADR-style numeric suffix).
|
|
30
|
+
|
|
31
|
+
### A3. Business backbone — `docs/biz/`
|
|
32
|
+
- For any project with a business dimension, `docs/biz/` is REQUIRED and is the spine.
|
|
33
|
+
- All `arch/`, `feat/`, and `plan/` docs that touch product direction or money must reference it.
|
|
34
|
+
- When code intent and a `biz/` doc disagree, the `biz/` doc wins — reconcile or escalate.
|
|
35
|
+
|
|
36
|
+
### A4. Anchor stamp — `updated <time> <version>` on every `arch|biz|feat` doc
|
|
37
|
+
|
|
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
|
+
|
|
40
|
+
**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
|
+
```markdown
|
|
43
|
+
# Rule delivery architecture
|
|
44
|
+
|
|
45
|
+
> updated 2026-08-12 · v2.1.0
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**`<time>`** is `YYYY-MM-DD`, the date of this edit. **`<version>`** is the project version the doc's content was confirmed against — the last **released** version at edit time, read from `CHANGELOG.md` (`release.A`), never an `[Unreleased]` buffer and never a number invented for the doc. A project with no version scheme stamps the short commit hash instead.
|
|
49
|
+
|
|
50
|
+
**Every content update rewrites the stamp, in the same edit.** A stamp older than the change under it is worse than no stamp: it certifies as verified something nobody checked. Pure-cosmetic edits (typo, link fix, reflow) leave it alone — the stamp records when the *content* was last true, not when bytes last moved.
|
|
51
|
+
|
|
52
|
+
The stamp is what makes drift mechanically visible: a `docs/arch/` file stamped three releases back is a drift-audit lead (C3) before anyone reads a line of it.
|
|
53
|
+
|
|
54
|
+
## B. Lifecycle & Sync
|
|
55
|
+
|
|
56
|
+
### B1. Plan lifecycle & Filename Rules
|
|
57
|
+
- Active plans live in `docs/plan/` (or `plan/`)
|
|
58
|
+
- Completed plans move to `docs/plan/done/`
|
|
59
|
+
- Use `done`, not `archived`, for completed plans
|
|
60
|
+
- **Filenames**: see A2 for the repo-wide no-leading-date rule and the optional compact date suffix. Plan docs additionally use version-increment naming when execution can't wait for the plan (e.g. `v2-feature-name.md` or `v1.1-update.md`).
|
|
61
|
+
- **Prioritize Creating Plans (`docs/plan/`)**: Always prioritize creating a plan document in `docs/plan/` (or `plan/`) for any code/architectural changes.
|
|
62
|
+
|
|
63
|
+
### B2. Research doc structure (`docs/research/`)
|
|
64
|
+
|
|
65
|
+
A research doc is an **event record** — the reasoning as it stood when written (the current-state vs. history split is defined in A2). Its body is frozen: never rewrite a claim, a number, or a verification status in place, because the record of what was believed is the doc's whole value. What may change after writing, by class:
|
|
66
|
+
- **Cosmetic** (typo, broken link, a path after a rename) — edit in place, no marker.
|
|
67
|
+
- **Erratum on a claim** — a fact turned out wrong, a number was re-measured, an unverified claim was later verified or contradicted, but the **Decision** field still stands: append a dated entry to a closing `## Amendments` section (`- 2026-08-02 · § R9: verified on kiro-cli 2.16.0; the row above was written unverified`), naming the section it corrects and stating only the corrected fact (no story of finding it — `agent.C2`), and add `Status: amended <date>` under the H1 so a reader is warned before reaching the stale claim. The original text stays.
|
|
68
|
+
- **Decision changes** — applying the correction would alter the Decision field: create a **new** research doc and add `Status: superseded by <path>` at the top of the old one. Name the chain with a sequential numeric suffix, ADR-style: `db-engine-choice.md` → `db-engine-choice-2.md` → `db-engine-choice-3.md`, each `superseded by` pointing only at its immediate successor so the chain can be walked backward.
|
|
69
|
+
- **Decision-field links and cross-references** — an Action link to where the result landed, a new cross-ref: edit in place; those fields describe where the event's consequences live, not the event.
|
|
70
|
+
|
|
71
|
+
The discriminator is mechanical: read the Decision field; if the correction would change it, successor doc, otherwise amendment. Anything outside research that links to a chain (`arch/feat/biz`) points at the latest number and gets updated each time the chain grows — that edit is allowed because those docs hold current state, not history.
|
|
72
|
+
|
|
73
|
+
Required fields, in order:
|
|
74
|
+
1. **Start time** — when the research began
|
|
75
|
+
2. **Initial purpose** — the question/goal, plus the context/constraints at the time (needed later to judge whether the research still holds)
|
|
76
|
+
3. **Strategy** — the approach taken
|
|
77
|
+
4. **Checklist** — the steps executed
|
|
78
|
+
5. **Result** — the finding/conclusion itself, plus:
|
|
79
|
+
- **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.
|
|
80
|
+
- **Corroborating links** — links to the evidence/cases the result rests on or conflicts with (not just a verified/unverified flag)
|
|
81
|
+
6. **Decision** — the resolution reached, one of:
|
|
82
|
+
- **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.
|
|
83
|
+
- **No action** — state why explicitly, so it reads as a deliberate stop, not an abandoned doc
|
|
84
|
+
- **Follow-up research** — link to the new research doc opened by this result
|
|
85
|
+
- **Rejected/closed** — an option eliminated with no replacement; no link needed
|
|
86
|
+
- **Cross-references** — list any other existing docs affected by this decision, beyond the artifact(s) it materialized into
|
|
87
|
+
|
|
88
|
+
### B3. Documentation behavior
|
|
89
|
+
- Docs are dense by default (domain application of `agent.A4`): conclusion first, then structure (tables/bullets), prose last, deletion test per sentence — narrative filler and restatement make a doc worse for both humans and LLMs. Length follows content: never pad to look thorough, never cut load-bearing detail to look short.
|
|
90
|
+
- Keep docs synchronized with code. Code does not auto-generate docs unless complex/requested; when editing code derived from `feat|arch` docs, proactively sync the doc or comment the reference path.
|
|
91
|
+
- Comments should not restate what a doc already explains in detail — when the rationale/behavior is complex, or a doc already covers it precisely, comment a reference to that doc (its specific section/heading, not just the whole file, when only part of it applies) instead of duplicating the explanation inline. Keeps the doc as the single source of truth and stops the comment from silently drifting out of sync with it.
|
|
92
|
+
- Prefer one clear canonical doc over multiple overlapping docs
|
|
93
|
+
- Use Markdown
|
|
94
|
+
- Prefer Mermaid when the subject is complex enough that plain text is harder to follow — flows, architecture, state transitions, or pipelines
|
|
95
|
+
- README should stay focused on setup and entry-level usage unless the project explicitly wants more
|
|
96
|
+
|
|
97
|
+
## C. Drift audit
|
|
98
|
+
|
|
99
|
+
B3 is a **process** rule — sync the docs while the code changes. This group is the **verification** rule — check afterwards whether that sync actually held. Every discipline decays, and a topology that mandates plan lifecycles, supersede chains, and a master index needs a way to prove it was followed. Sibling audits own their own domains and must not be restated here: `release.B` (version/CHANGELOG state), `ui.C` (class and token drift), `METHOD-audit-flow.md` (flow and state drift). This group owns **docs-vs-reality** only.
|
|
100
|
+
|
|
101
|
+
### C1. When it runs — and when it does not
|
|
102
|
+
|
|
103
|
+
The discriminator is not how big the audit is. It is whether the baseline is stable and whether the findings outlive the session.
|
|
104
|
+
|
|
105
|
+
- **Runs here** — the tree is clean and the last release is published: the "open the repo after a release, audit before starting the next version" moment. The baseline is stable, so a recorded snapshot stays true.
|
|
106
|
+
- **Not here, unstable baseline** — a long half-finished working tree (some committed, some not, some mid-edit). That needs triage of the tree state, not a docs snapshot, and belongs to the commit workflow (`/akigitcommit` step 0). A "state of the tree today" record is false tomorrow and would fill the `research/` chain with expired findings.
|
|
107
|
+
- **Not here, pre-ship gate** — work finished but not yet pushed, deployed, or released. That is a pass/fail gate whose findings must be *fixed* before shipping rather than filed for posterity: `release.B7`.
|
|
108
|
+
- **Below threshold** — a spot-check of one doc, or anything answerable inline, produces no doc at all. Two docs per question is the failure mode this threshold exists to prevent. The bar for the C2 output is a fan-out across two or more domains, or findings that cannot all be fixed in the current session.
|
|
109
|
+
|
|
110
|
+
### C2. Output contract — a research doc paired with a plan doc
|
|
111
|
+
|
|
112
|
+
An audit that qualifies under C1 produces **both**, never only one:
|
|
113
|
+
|
|
114
|
+
1. **The finding record** — a `docs/research/` doc on the B2 schema, which already fits an audit exactly. *Start time* = when the audit ran · *Initial purpose* = the scope audited plus the version/commit it ran against, since that context is what lets a later reader judge whether the findings still hold · *Strategy* = which domains and lenses · *Checklist* = the steps executed · *Result + Verification* = the findings, with anything only checkable at runtime marked "unverified" per `coding.B3` · *Decision → Action* = a link to the plan doc below.
|
|
115
|
+
2. **The execution doc** — a `docs/plan/` doc per B1 that sequences the fixes and links back to the research doc.
|
|
116
|
+
|
|
117
|
+
What makes the pair trustworthy:
|
|
118
|
+
- **Name by what was audited — never version-first or date-first** (A2): `audit-ui-jul27.md`, `audit-docs-drift-jul27.md`. The version audited belongs in the *Initial purpose* field, not the filename: a version in the name reads ambiguously against B2's supersede-chain suffix (`audit-ui-2.md` is the second audit; `audit-1.4.2.md` would look like one).
|
|
119
|
+
- **Re-auditing later opens a new doc in the chain** (B2) and never edits the old audit's body. An audit is an event record, not a living document.
|
|
120
|
+
- **A finding deliberately left unscheduled must be recorded as B2's "No action" with its reason.** Silence makes a deliberate deferral indistinguishable from an oversight, and low-severity findings are exactly what a plan doc otherwise swallows.
|
|
121
|
+
|
|
122
|
+
### C3. What to compare
|
|
123
|
+
|
|
124
|
+
Walk the topology, checking each doc against what is actually true now:
|
|
125
|
+
- `docs/index.md` — every entry resolves, and nothing that exists is missing from it (A1)
|
|
126
|
+
- `docs/plan/` — an active plan whose work already shipped belongs in `done/` (B1); an active plan nobody is executing is either dead or unstarted and must be labeled as one, not left ambiguous
|
|
127
|
+
- `docs/arch/` — module boundaries, data shapes, and diagrams still match the actual tree
|
|
128
|
+
- `docs/feat/` — the described behavior still matches what the code does
|
|
129
|
+
- `docs/biz/` — where code intent contradicts it, A3 decides: the `biz/` doc wins until it is explicitly changed
|
|
130
|
+
- `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)
|
|
131
|
+
- `docs/ref/` — commands, paths, and setup steps still run
|
|
132
|
+
- Doc references inside code comments (B3) still point at a heading that exists
|
|
133
|
+
- **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
|
|
134
|
+
|
|
135
|
+
### C4. Severity — drift is not one thing
|
|
136
|
+
|
|
137
|
+
- **Wrong** — the doc states something a reader would act on and be harmed by: a stale command that destroys data, an architecture diagram that routes work to the wrong module. Fix before anything else; a wrong doc is worse than no doc.
|
|
138
|
+
- **Stale** — accurate when written, since superseded. Goes into the plan doc.
|
|
139
|
+
- **Incomplete** — nothing false, something missing.
|
|
140
|
+
- **Cosmetic** — index ordering, a broken relative link.
|
|
141
|
+
|
|
142
|
+
Report the count per level. Never compress "wrong" and "cosmetic" into one number — an audit that reports "14 drift issues" hides whether the docs are currently dangerous.
|
|
143
|
+
|
|
144
|
+
Audits are read-only by construction: `agent.B5`.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Pattern Core — Universal Architecture Pattern Rules
|
|
2
|
+
|
|
3
|
+
<!-- Address map: pattern.A1-8 · pattern.B1-3 · pattern.C1 -->
|
|
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.
|
|
6
|
+
|
|
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
|
+
|
|
9
|
+
## Relationship to existing rules — read, do not duplicate
|
|
10
|
+
|
|
11
|
+
- **`RULE-coding.md`** owns baseline DRY, YAGNI, "no abstraction for its own sake", one-responsibility functions, Result pattern, error handling, security. This file assumes all of it and adds the *when-and-how-to-abstract / how-to-decompose* layer.
|
|
12
|
+
- **`METHOD-audit-flow.md`** owns flow-integrity thinking. When you keep adding guards/checks around the same path, defer to it — this file only points there.
|
|
13
|
+
- **`METHOD-deep-think.md`** owns first-principles and the mandatory critique pass. Run its critique mini-pass before introducing any new abstraction.
|
|
14
|
+
- **`RULE-db-design.md`** owns bounded-context and normalization for data. Law 6 below is the same boundary principle generalized to code modules.
|
|
15
|
+
|
|
16
|
+
## Scope note
|
|
17
|
+
|
|
18
|
+
These are constraints on **structure and reuse**, not style. Reach for this file whenever a task involves designing a module, extracting shared code, refactoring, hunting duplication, or deciding how to split responsibilities — regardless of language or framework.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## A. The 8 laws — checkable, stack-agnostic
|
|
23
|
+
|
|
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
|
+
|
|
26
|
+
**A2 — Evidence-based abstraction (Rule of Three).** Do not abstract on the first or second occurrence. Extract a shared function / module / type only when the same shape repeats **≥3 times across ≥2 unrelated call sites**. Premature abstraction is a violation: it adds an indirection layer with no proven need, and is harder to read and change than the duplication it replaced.
|
|
27
|
+
- *Risk-weighted exception:* business logic with real cost of error (auth, money, permissions, data integrity) extracts on the **2nd** occurrence. A logic bug there is worse than a little duplication.
|
|
28
|
+
|
|
29
|
+
**A3 — Single Responsibility, the "and" test.** A unit (function, module, class, service) does one thing. If describing its job requires the word "and" — "parses input **and** writes to DB **and** formats output" — split it. The name should reveal the single responsibility.
|
|
30
|
+
|
|
31
|
+
**A4 — Open for extension, closed for modification.** Add behavior through parameters, injected handlers/strategies, or new implementations of a stable interface — not by editing a working unit for one new case. A function that grows one more boolean flag per caller is the smell that this law is being broken.
|
|
32
|
+
|
|
33
|
+
**A5 — Composition over duplication.** Prefer combining small units — helper functions, modules, data-driven iteration — over copy-pasting a near-identical block "for speed." The **second** paste is a mandatory STOP: plan the shared shape before a third exists (Law 2).
|
|
34
|
+
|
|
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
|
+
|
|
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.
|
|
39
|
+
|
|
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. Full method: `METHOD-audit-flow.md`.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## B. Decomposition & the forest pass
|
|
45
|
+
|
|
46
|
+
### B1. Module decomposition — how to split
|
|
47
|
+
- Split by **responsibility/domain**, not by technical layer alone and not by file size.
|
|
48
|
+
- A module must be describable in one sentence without "and" (Law 3).
|
|
49
|
+
- Prefer many small, single-purpose modules with clear names over a few god-modules — but only once Rule of Three (Law 2) justifies each extraction. Do not pre-split speculative modules (YAGNI).
|
|
50
|
+
- Keep dependencies pointing inward toward stable abstractions; push volatile details (providers, SDKs, frameworks) to the edges behind a boundary (Law 6; see also `RULE-coding.md` Result pattern and `RULE-ui-pattern.md` / `RULE-stack-akiNuxtCf.md` composable boundary).
|
|
51
|
+
|
|
52
|
+
### B2. The "forest" pass — before you patch
|
|
53
|
+
Before adding a feature or fixing a bug in unfamiliar code, do a quick whole-flow scan instead of a local patch. This is the direct antidote to "seeing the leaf, missing the forest":
|
|
54
|
+
|
|
55
|
+
1. **Flow** — what is the end-to-end path this change touches, start to end? (`METHOD-audit-flow.md`)
|
|
56
|
+
2. **Reuse** — does this problem already have a solution elsewhere in the codebase? Reuse before reimplementing (`RULE-coding.md`: "prefer existing code and patterns").
|
|
57
|
+
3. **Third instance** — is this the third occurrence of a shape? If so, extract now (Law 2).
|
|
58
|
+
4. **Symptom vs shape** — am I patching a symptom? If three patches cluster at one transition, stop and reshape the flow (Law 8) rather than adding a fourth.
|
|
59
|
+
|
|
60
|
+
### B3. Before introducing any new abstraction — critique gate
|
|
61
|
+
No new shared layer, base module, or generalization ships without a quick `METHOD-deep-think.md` critique mini-pass:
|
|
62
|
+
- **Subtract before you share** — must the duplicated thing exist at all? Packaging repetition is the second-best outcome; deleting it, or moving it somewhere it happens once by construction, is the first. Every bullet below silently assumes the code has to exist, so ask this one before them or the cheapest answer is never reached (`think.B4`).
|
|
63
|
+
- **Steelman NOT abstracting** — is keeping the duplication actually cheaper here?
|
|
64
|
+
- **Attack the abstraction** — one concrete way it could be the wrong shape, and how you'd know.
|
|
65
|
+
- **Smaller first** — is the first version smaller than the imagined final one?
|
|
66
|
+
|
|
67
|
+
## C. Closure
|
|
68
|
+
|
|
69
|
+
### C1. Definition of done — pattern level
|
|
70
|
+
A change is pattern-complete when all hold:
|
|
71
|
+
- No value/rule is duplicated (Law 1).
|
|
72
|
+
- Every new unit passes the "and" test (Law 3).
|
|
73
|
+
- No abstraction was added without ≥3 evidence — or ≥2 for risk logic (Law 2).
|
|
74
|
+
- No new repeated guard was added where the flow could be reshaped (Law 8).
|
|
75
|
+
- Every new name is role-based, not value-based (Law 7).
|
|
76
|
+
- Module boundaries stayed narrow — no reaching into another module's internals (Law 6).
|
|
77
|
+
|
|
78
|
+
## One-line reminder
|
|
79
|
+
|
|
80
|
+
Do not abstract, split, or guard until you are sure the shape itself is justified — and never let a local patch outrank the whole flow.
|