@akinet/akidevrule 3.7.0 → 3.9.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 +50 -0
- package/README.md +61 -20
- package/claude/CLAUDE.md +1 -1
- package/claude/agents/aki-hands.md +1 -1
- package/claude/agents/aki-maker.md +2 -2
- package/claude/fragments/settings.akidoc.fragment.json +5 -0
- package/claude/hooks/aki-route-guard.mjs +94 -43
- package/install.mjs +247 -61
- package/package.json +1 -1
- package/payload/GEMINI.md +7 -7
- package/payload/RULE-agent-behavior.md +24 -23
- package/payload/RULE-coding.md +8 -6
- package/payload/RULE-docs.md +1 -0
- package/payload/RULE-release.md +6 -5
- package/payload/RULE-stack-akiNuxtCf.md +3 -2
- package/payload/RULE-stack-tauri.md +11 -1
- package/payload/RULE-test.md +1 -1
- package/payload/RULE-ui-pattern.md +9 -2
- package/payload/route-map.json +14 -0
- package/skills/akiflow/SKILL.md +4 -2
- package/skills/akiflow/references/harness-facts.md +26 -5
- package/skills/akiflow/scripts/plan_lint.py +123 -0
- package/skills/akiflow/scripts/scythe.py +12 -10
- package/skills/akiflow/scripts/ship_gate.py +65 -0
- package/skills/akiflow/scripts/{test_lint.py → suite_lint.py} +18 -5
- package/skills/akigitcommit/SKILL.md +1 -1
- package/skills/akihelp/SKILL.md +3 -2
- package/skills/akilint/SKILL.md +1 -1
- package/skills/akirule/SKILL.md +6 -5
- package/skills/akiship/SKILL.md +7 -7
- package/skills/akithink/SKILL.md +2 -2
- package/skills/noyap/SKILL.md +44 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# plan_lint.py — mechanical checks that a project's plans and doc index agree with what shipped (RULE-docs.md B1, C3; RULE-release.md B7 step 5).
|
|
3
|
+
# Usage: plan_lint.py <project-dir> [...]
|
|
4
|
+
# Output: [TAG] path:line | short label Exit: 0 clean · 1 any verdict tag · 2 usage error. Same grammar as scythe.py and release_lint.py.
|
|
5
|
+
# Verdict tags: [DONE] an active plan in docs/plan/ whose every checkbox is ticked, so it belongs in docs/plan/done/ · [OPEN] a plan in docs/plan/done/ that still has an unticked box · [LINK] a docs/index.md link to a file that does not exist · [UNTRACKED] a docs/index.md link to a file git does not track, so a commit would ship the index without it.
|
|
6
|
+
# Review tag (never changes the exit code): [CLAIM] the newest CHANGELOG block cites a plan that still has unticked boxes — confirm the entry claims only the ticked items.
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
import subprocess
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
_BOX = re.compile(r'^\s*[-*+]\s+\[([ xX])\]')
|
|
16
|
+
_LINK = re.compile(r'\]\(([^)#\s]+\.md)(?:#[^)]*)?\)')
|
|
17
|
+
_PLAN_REF = re.compile(r'(?:docs/)?plan/((?!done/)[\w./-]+\.md)')
|
|
18
|
+
_VERSION = re.compile(r'^##\s+\[')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _boxes(path: Path) -> list[tuple[int, bool]]:
|
|
22
|
+
out: list[tuple[int, bool]] = []
|
|
23
|
+
fence = False
|
|
24
|
+
for n, raw in enumerate(path.read_text(encoding='utf-8', errors='replace').splitlines(), 1):
|
|
25
|
+
if raw.lstrip().startswith(('```', '~~~')):
|
|
26
|
+
fence = not fence
|
|
27
|
+
continue
|
|
28
|
+
m = None if fence else _BOX.match(raw)
|
|
29
|
+
if m:
|
|
30
|
+
out.append((n, m.group(1) != ' '))
|
|
31
|
+
return out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _tracked(root: Path) -> set[str] | None:
|
|
35
|
+
r = subprocess.run(['git', '-C', str(root), 'ls-files', '-z'], capture_output=True)
|
|
36
|
+
if r.returncode != 0:
|
|
37
|
+
return None
|
|
38
|
+
return {p.decode('utf-8', 'replace') for p in r.stdout.split(b'\0') if p}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def lint_plans(root: Path) -> list[str]:
|
|
42
|
+
plan_dir = root / 'docs' / 'plan'
|
|
43
|
+
findings: list[str] = []
|
|
44
|
+
if not plan_dir.is_dir():
|
|
45
|
+
return findings
|
|
46
|
+
for p in sorted(plan_dir.glob('*.md')):
|
|
47
|
+
boxes = _boxes(p)
|
|
48
|
+
if boxes and all(done for _, done in boxes):
|
|
49
|
+
findings.append(f"[DONE] {p}:1 | all {len(boxes)} items ticked — move to docs/plan/done/")
|
|
50
|
+
for p in sorted((plan_dir / 'done').rglob('*.md')):
|
|
51
|
+
for n, done in _boxes(p):
|
|
52
|
+
if not done:
|
|
53
|
+
findings.append(f"[OPEN] {p}:{n} | unticked item in a done plan — finish it, or move the plan back to docs/plan/")
|
|
54
|
+
return findings
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def lint_index(root: Path) -> list[str]:
|
|
58
|
+
index = root / 'docs' / 'index.md'
|
|
59
|
+
if not index.is_file():
|
|
60
|
+
return []
|
|
61
|
+
tracked = _tracked(root)
|
|
62
|
+
findings: list[str] = []
|
|
63
|
+
for n, raw in enumerate(index.read_text(encoding='utf-8', errors='replace').splitlines(), 1):
|
|
64
|
+
for target in _LINK.findall(raw):
|
|
65
|
+
if '://' in target:
|
|
66
|
+
continue
|
|
67
|
+
f = (index.parent / target).resolve()
|
|
68
|
+
if not f.is_file():
|
|
69
|
+
findings.append(f"[LINK] {index}:{n} | {target} does not exist")
|
|
70
|
+
continue
|
|
71
|
+
try:
|
|
72
|
+
rel = f.relative_to(root.resolve()).as_posix()
|
|
73
|
+
except ValueError:
|
|
74
|
+
continue
|
|
75
|
+
if tracked is not None and rel not in tracked:
|
|
76
|
+
findings.append(f"[UNTRACKED] {index}:{n} | {target} exists but is not in git — `git add {rel}` or the commit ships a dead link")
|
|
77
|
+
return findings
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def review_changelog(root: Path) -> list[str]:
|
|
81
|
+
changelog = root / 'CHANGELOG.md'
|
|
82
|
+
if not changelog.is_file():
|
|
83
|
+
return []
|
|
84
|
+
lines = changelog.read_text(encoding='utf-8', errors='replace').splitlines()
|
|
85
|
+
starts = [i for i, raw in enumerate(lines) if _VERSION.match(raw)]
|
|
86
|
+
if not starts:
|
|
87
|
+
return []
|
|
88
|
+
end = starts[1] if len(starts) > 1 else len(lines)
|
|
89
|
+
findings: list[str] = []
|
|
90
|
+
seen: set[str] = set()
|
|
91
|
+
for i in range(starts[0], end):
|
|
92
|
+
for name in _PLAN_REF.findall(lines[i]):
|
|
93
|
+
plan = root / 'docs' / 'plan' / name
|
|
94
|
+
if name in seen or not plan.is_file():
|
|
95
|
+
continue
|
|
96
|
+
seen.add(name)
|
|
97
|
+
open_boxes = [n for n, done in _boxes(plan) if not done]
|
|
98
|
+
if open_boxes:
|
|
99
|
+
findings.append(f"[CLAIM] {changelog}:{i + 1} | cites docs/plan/{name}, which has {len(open_boxes)} unticked item(s) (first at line {open_boxes[0]}) — review")
|
|
100
|
+
return findings
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def main() -> None:
|
|
104
|
+
targets = [a for a in sys.argv[1:] if not a.startswith('--')]
|
|
105
|
+
if not targets:
|
|
106
|
+
print("usage: plan_lint.py <project-dir> [...]", file=sys.stderr)
|
|
107
|
+
sys.exit(2)
|
|
108
|
+
verdicts: list[str] = []
|
|
109
|
+
reviews: list[str] = []
|
|
110
|
+
for t in targets:
|
|
111
|
+
root = Path(t)
|
|
112
|
+
if not root.is_dir():
|
|
113
|
+
print(f"plan_lint: not a directory: {t}", file=sys.stderr)
|
|
114
|
+
sys.exit(2)
|
|
115
|
+
verdicts += lint_plans(root) + lint_index(root)
|
|
116
|
+
reviews += review_changelog(root)
|
|
117
|
+
for line in verdicts + reviews:
|
|
118
|
+
print(line)
|
|
119
|
+
sys.exit(1 if verdicts else 0)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__ == '__main__':
|
|
123
|
+
main()
|
|
@@ -159,6 +159,7 @@ def _lint_md(path: str) -> list[str]:
|
|
|
159
159
|
|
|
160
160
|
front = False
|
|
161
161
|
fence = False
|
|
162
|
+
fence_run = ''
|
|
162
163
|
fence_marker: re.Pattern | None = None
|
|
163
164
|
fence_body: list[tuple[int, str]] = []
|
|
164
165
|
prev = ''
|
|
@@ -172,21 +173,22 @@ def _lint_md(path: str) -> list[str]:
|
|
|
172
173
|
if re.match(r'^---[ \t]*$', raw):
|
|
173
174
|
front = False
|
|
174
175
|
continue
|
|
175
|
-
fm = re.match(r'^[ \t]*(
|
|
176
|
-
if
|
|
177
|
-
|
|
176
|
+
fm = re.match(r'^[ \t]*(`{3,}|~{3,})[ \t]*([A-Za-z0-9_+#-]*)', raw)
|
|
177
|
+
if fence:
|
|
178
|
+
# CommonMark: only a bare run of the opening character, at least as long as the opening run, closes the block; a ``` line inside a ```` block is content.
|
|
179
|
+
if fm and fm.group(1)[0] == fence_run[0] and len(fm.group(1)) >= len(fence_run) and not raw[fm.end(1):].strip():
|
|
178
180
|
if fence_marker is not None:
|
|
179
181
|
findings.extend(_scan_comment_runs(path, fence_body, fence_marker, False))
|
|
180
|
-
fence, fence_marker, fence_body = False, None, []
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
fence, fence_run, fence_marker, fence_body = False, '', None, []
|
|
183
|
+
prevset = False
|
|
184
|
+
elif fence_marker is not None:
|
|
185
|
+
fence_body.append((lineno, raw))
|
|
186
|
+
continue
|
|
187
|
+
if fm:
|
|
188
|
+
fence, fence_run, fence_marker, fence_body = True, fm.group(1), _fence_marker(fm.group(2)), []
|
|
183
189
|
# A fence is a block boundary: the lines either side of it are not a wrapped pair.
|
|
184
190
|
prevset = False
|
|
185
191
|
continue
|
|
186
|
-
if fence:
|
|
187
|
-
if fence_marker is not None:
|
|
188
|
-
fence_body.append((lineno, raw))
|
|
189
|
-
continue
|
|
190
192
|
|
|
191
193
|
if prevset:
|
|
192
194
|
if (
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# ship_gate.py — refuses push/deploy when an /akiship run's B7 receipt is incomplete or holds an unverified flow (RULE-release.md B7 fail-closed contract, step 7; B8).
|
|
3
|
+
# Usage: ship_gate.py <receipt.md> The receipt is the run's report block written to a scratchpad file before Phase 3 step 4 (skills/akiship/SKILL.md § Report).
|
|
4
|
+
# Receipt grammar: one line per gate step `S<n> PASS|FIXED|FAIL|N/A — <evidence>` for S0–S8; self-interrogation answers as lines `(1)`–`(4)`; open items as lines starting `Q<n>` / `N<n>`. A leading `- ` or backticks are ignored.
|
|
5
|
+
# Output: [TAG] path:line | short label Exit: 0 push allowed · 1 push refused · 2 usage error. Same grammar as scythe.py and release_lint.py.
|
|
6
|
+
# Tags: [MISSING] a step or self-interrogation answer with no line (NOT RUN = FAIL) · [FAIL] a step scored FAIL · [EVIDENCE] a step with no evidence after the dash · [HEDGE] PASS/FIXED evidence resting on a forbidden word (should, presumably, probably, looks fine, seems, expected to) · [HOLD] a `Q` item that is unverified.
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
STEPS = range(9)
|
|
15
|
+
QUESTIONS = range(1, 5)
|
|
16
|
+
HEDGES = re.compile(r'\b(should|presumably|probably|looks fine|seems|expected to)\b', re.I)
|
|
17
|
+
|
|
18
|
+
_PREFIX = re.compile(r'^\s*(?:[-*]\s+)?`?')
|
|
19
|
+
_STEP = re.compile(r'S(\d)`?\s+(PASS|FIXED|FAIL|N/A)\b\s*(?:[—–-]+\s*(.*))?$', re.I)
|
|
20
|
+
_ANSWER = re.compile(r'\((\d)\)\s*(.*)$')
|
|
21
|
+
_QITEM = re.compile(r'Q\d+\b`?(.*)$')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def check(path: Path) -> list[str]:
|
|
25
|
+
lines = path.read_text(encoding='utf-8', errors='replace').splitlines()
|
|
26
|
+
steps: dict[int, int] = {}
|
|
27
|
+
answers: dict[int, int] = {}
|
|
28
|
+
findings: list[str] = []
|
|
29
|
+
for n, raw in enumerate(lines, 1):
|
|
30
|
+
body = _PREFIX.sub('', raw, count=1)
|
|
31
|
+
if m := _STEP.match(body):
|
|
32
|
+
step, status, evidence = int(m.group(1)), m.group(2).upper(), (m.group(3) or '').strip()
|
|
33
|
+
steps.setdefault(step, n)
|
|
34
|
+
if status == 'FAIL':
|
|
35
|
+
findings.append(f"[FAIL] {path}:{n} | S{step} scored FAIL — fix it before push")
|
|
36
|
+
if len(evidence) < 3:
|
|
37
|
+
findings.append(f"[EVIDENCE] {path}:{n} | S{step} {status} has no evidence after the dash")
|
|
38
|
+
elif status in ('PASS', 'FIXED') and (h := HEDGES.search(evidence)):
|
|
39
|
+
findings.append(f"[HEDGE] {path}:{n} | S{step} {status} rests on `{h.group(0)}` — an unverified claim, never a PASS")
|
|
40
|
+
elif m := _ANSWER.match(body):
|
|
41
|
+
if m.group(2).strip():
|
|
42
|
+
answers.setdefault(int(m.group(1)), n)
|
|
43
|
+
elif (m := _QITEM.match(body)) and 'unverified' in m.group(1).lower():
|
|
44
|
+
findings.append(f"[HOLD] {path}:{n} | unverified touched flow is an open question — push and deploy stay held (B7 step 7)")
|
|
45
|
+
findings += [f"[MISSING] {path}:1 | no S{s} line — a step with no receipt was NOT RUN" for s in STEPS if s not in steps]
|
|
46
|
+
findings += [f"[MISSING] {path}:1 | no self-interrogation answer ({q})" for q in QUESTIONS if q not in answers]
|
|
47
|
+
return findings
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
targets = [a for a in sys.argv[1:] if not a.startswith('--')]
|
|
52
|
+
if len(targets) != 1 or not Path(targets[0]).is_file():
|
|
53
|
+
print("usage: ship_gate.py <receipt.md>", file=sys.stderr)
|
|
54
|
+
sys.exit(2)
|
|
55
|
+
findings = check(Path(targets[0]))
|
|
56
|
+
for line in findings:
|
|
57
|
+
print(line)
|
|
58
|
+
if findings:
|
|
59
|
+
print(f"push refused: {len(findings)} finding(s)")
|
|
60
|
+
sys.exit(1)
|
|
61
|
+
print("push allowed")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
main()
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
#
|
|
3
|
-
# Usage:
|
|
2
|
+
# suite_lint.py — mechanical detectors for the test-file failure shapes RULE-test.md owns (test.D1); each tag names the item it serves.
|
|
3
|
+
# Usage: suite_lint.py [--all] <path|dir> [...] A dir expands to its git-tracked files matching the test-path signature (the RULE-test.md route of route-map.json); a file is linted as given.
|
|
4
4
|
# Output: [TAG] path:line | short label Exit: 0 clean · 1 any CERTAIN tag · 2 usage error. Same grammar as scythe.py and release_lint.py.
|
|
5
5
|
# CERTAIN (verdicts): [TMPLIT] temp dir or file created at a literal /tmp path (B3) · [CLEANUP] a file that creates a temp dir and contains no removal call, unless the repo configures a suite preload (B2) · [EXIT] process.exit/sys.exit/os.Exit in a test (C3).
|
|
6
6
|
# SUGGESTED (review): [CLEANUP-FINALLY] removal present but no finally/after hook (B3) · [SLEEP] fixed sleep (C3) · [VACUOUS] assertion whose only argument is Array.isArray, typeof === 'function' or a bare identifier (C2) · [AMBIENT] an if on env/filesystem/platform state with an assertion or continue under it (C2) · [HOMEREAD] real HOME read with no preload and no restored override (B1) · [NET] literal non-loopback URL fetched in the default suite (B1) · [PORT] fixed or random-range port (B1) · [SRCPIN] a project source file read by a test (C1) · [HISTORY] change-history comment (A3).
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import json
|
|
10
11
|
import re
|
|
11
12
|
import subprocess
|
|
12
13
|
import sys
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
def test_route() -> dict:
|
|
18
|
+
for p in (Path.home() / '.aki' / 'akidevrule' / 'route-map.json', Path(__file__).resolve().parents[3] / 'payload' / 'route-map.json'):
|
|
19
|
+
try:
|
|
20
|
+
return next(r for r in json.loads(p.read_text())['routes'] if 'RULE-test.md' in r['rules'])
|
|
21
|
+
except (OSError, ValueError, KeyError, StopIteration):
|
|
22
|
+
pass
|
|
23
|
+
print("suite_lint: no RULE-test.md route in route-map.json (~/.aki/akidevrule or payload/)", file=sys.stderr)
|
|
24
|
+
raise SystemExit(2)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_route = test_route()
|
|
28
|
+
TEST_NAME = re.compile(_route['nameRe'])
|
|
29
|
+
TEST_DIR = re.compile(_route['dirRe'])
|
|
17
30
|
CODE_EXT = {'.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx', '.py', '.go', '.rs', '.sh'}
|
|
18
31
|
CERTAIN = {'TMPLIT', 'CLEANUP', 'EXIT'}
|
|
19
32
|
|
|
@@ -127,7 +140,7 @@ def main() -> None:
|
|
|
127
140
|
show_all = '--all' in sys.argv
|
|
128
141
|
targets = [a for a in sys.argv[1:] if not a.startswith('--')]
|
|
129
142
|
if not targets:
|
|
130
|
-
print("usage:
|
|
143
|
+
print("usage: suite_lint.py [--all] <path|dir> [...]", file=sys.stderr)
|
|
131
144
|
sys.exit(2)
|
|
132
145
|
files: list[Path] = []
|
|
133
146
|
for t in targets:
|
|
@@ -75,7 +75,7 @@ These exist because a later `git add` can swallow files meant for an earlier com
|
|
|
75
75
|
## Commit message rules
|
|
76
76
|
|
|
77
77
|
- Use **Conventional Commits**: `type(scope): short summary`. Body optional, in imperative mood, explaining *why* when it isn't obvious.
|
|
78
|
-
- **
|
|
78
|
+
- **No model-credit trailer** (`RULE-agent-behavior.md` B4): no `Co-Authored-By:` or similar line — the commit carries only the human-authored intent.
|
|
79
79
|
- Match the language and style already used in the repo's recent commit history (`git log --oneline -15` to check).
|
|
80
80
|
|
|
81
81
|
## Boundaries
|
package/skills/akihelp/SKILL.md
CHANGED
|
@@ -20,7 +20,7 @@ Invoke with `/akihelp`, or whenever the user asks, in any wording, what this set
|
|
|
20
20
|
- **Agent definitions (who the work gets handed to)** — one row per installed `aki-` agent from step 3: what it is for, and the property that is mechanical rather than promised (its `tools:` list, which is what makes a read-only agent actually read-only, and its `model:`, so a tier is never improvised). Say the thing people get wrong: this is a catalog, not a roster — an agent is spawned because a specific requirement needs it, never because it exists.
|
|
21
21
|
- **Passive system (akirule)** — explain the load mechanisms: the behavior floor and the router always loaded (`@`-imported by `CLAUDE.md`); every other rule read when the task's domain matches a route — by meaning, never keywords — and, on Claude Code, enforced for artifact routes by the `aki-route-guard` hook (the first edit of a code file, `.md`, `CHANGELOG.md`, `.vue`, `.rs`, `.sql` … is denied until its rule was read); full load when the owner asks for the whole corpus. `akirule` is hidden from the `/` menu by design (`user-invocable: false`) — it is imported, not a command.
|
|
22
22
|
- **One brain, three modes** — `METHOD-deep-think.md` is read passively by the router inside normal tasks (brief, inline, at most one clarifying question), as a triggered self-run when an `agent.A3` trigger holds or `/akithink` self-runs on a genuine decision (non-interactive, depth scaled to difficulty, ends in decide-and-report or escalation), and interactively by `/akithink` when the owner asks for a session. Short version of the comparison, not the full METHOD text.
|
|
23
|
-
- **Editing rules** — this whole system is generated from a source repo (akidevrule); the installed copies under `~/.aki/akidevrule` and `~/.claude` are deployed output, never edited directly. Changes go through the source repo + `install.sh`. Note for context: the same skill corpus (not the rule corpus) is also synced by `install.sh` to Antigravity/Gemini and to Codex, Kiro, and Grok CLIs on this machine if present — this skill itself only introduces the Claude Code side.
|
|
23
|
+
- **Editing rules** — this whole system is generated from a source repo (akidevrule); the installed copies under `~/.aki/akidevrule` and `~/.claude` are deployed output, never edited directly. Changes go through the source repo + `install.sh`. Note for context: the same skill corpus (not the rule corpus) is also synced by `install.sh` to Antigravity/Gemini and to Codex, Kiro, and Grok CLIs and to WorkBuddy on this machine if present — this skill itself only introduces the Claude Code side.
|
|
24
24
|
|
|
25
25
|
5. Render a **painpoint → what to say** table. This is the section most people actually need: a capability list tells them what exists, this tells them which words to type when a specific problem is in front of them. Build every row from what steps 1–3 actually returned, and **drop any row whose skill or rule file did not appear there** — a row pointing at something uninstalled is worse than a missing row.
|
|
26
26
|
|
|
@@ -31,7 +31,8 @@ Invoke with `/akihelp`, or whenever the user asks, in any wording, what this set
|
|
|
31
31
|
| Long half-finished working tree, unclear what is safe to commit | `/akigitcommit` | Triages finished vs mid-edit vs abandoned vs accidental **before** grouping; stages by explicit path, never `git add -A` |
|
|
32
32
|
| Work is finished but not pushed, and they want to know if it is genuinely shippable | *"Is this ready to ship?"* | `RULE-release.md` B7 pre-ship gate — a pass/fail check, not a document |
|
|
33
33
|
| A decision is big, hard to reverse, or the real goal is still fuzzy | `/akithink` | Full 5-phase session: restate → goal excavation → first principles → mandatory critique → decision record. Small reversible calls should just be decided instead |
|
|
34
|
-
|
|
|
34
|
+
| A reply is padded or too long | `/noyap`, or name the card: *"`[FLUFF]`"* | `noyap` — rewrites the reply just given keeping only the answer and what the owner must do or heed, the rest cut and leftovers settled; 10–40% of the replaced text, persisting for later replies; the fix procedure behind `[FLUFF]` (`RULE-agent-behavior.md` §0, root `agent.A4`) |
|
|
35
|
+
| Lines are hard-wrapped mid-sentence, or a comment is bloated | Name the penalty card: *"`[WRAP]`"* / *"`[YAP]`"*, or run `/akilint` | `RULE-agent-behavior.md` §0. `/akilint` runs the deterministic detector for the two mechanical cards; `[FLUFF]` stays human judgment and no script claims it |
|
|
35
36
|
| A mandatory step was skipped — no `[RULES]` line after a compaction, a task closed without re-reading the request, a known file read with `cat` | Name the penalty card: *"`[SKIP]`"* | `RULE-agent-behavior.md` `B7` — akirule wins over the harness's own brevity and speed directives; the step is redone, not explained |
|
|
36
37
|
| One task genuinely needs several kinds of judgment at once (architecture *and* UX *and* market) | `/akiflow` | Lead-coordinated council with `aki-challenger`'s subtraction pass ("what can be cut?") and a mechanical closure gate. Overkill for ordinary work — say so plainly rather than routing everything here |
|
|
37
38
|
| Work is large and parallel but the answer is already knowable — a sweep, a migration, a fan-out across many files | `/akiflow`, as a **dispatch** rather than a council | Same anchor, rule receipts, durable record and closure gate; lanes with an exclusive `writes:` file set replace items with adversaries, and `--convene` refuses two lanes claiming one path. Wanting a challenger mid-run means it was a council question after all |
|
package/skills/akilint/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: akilint
|
|
3
|
-
description: Mechanical format lint for the penalty-card classes of RULE-agent-behavior.md §0 — hard-wrapped code comments and markdown prose ([WRAP]) and oversize comments ([YAP]) — via the shared scythe.py detector. Deterministic file:line output; judgment stays with the session. Use whenever formatting is in question — the user wants lines or comments checked, complains that text is hard-wrapped or comments are bloated, or calls
|
|
3
|
+
description: Mechanical format lint for the penalty-card classes of RULE-agent-behavior.md §0 — hard-wrapped code comments and markdown prose ([WRAP]) and oversize comments ([YAP]) — via the shared scythe.py detector. Deterministic file:line output; judgment stays with the session. Use whenever formatting is in question — the user wants lines or comments checked, complains that text is hard-wrapped or comments are bloated, or calls [WRAP] or [YAP] on recent output. A [FLUFF] call is judgment, not lint — on a reply it is the `noyap` skill, on a file it is `docs.B3`.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
6
6
|
|
package/skills/akirule/SKILL.md
CHANGED
|
@@ -12,8 +12,9 @@ user-invocable: false
|
|
|
12
12
|
- **Antigravity (IDE and `agy`):** routing is native — every rule is installed as `akirule-<topic>.md` (`agent` `always_on`, the rest by descriptions the installer generates from the routes below), so do not invoke this skill there.
|
|
13
13
|
- **Codex:** resident — the installer writes the behavior floor and this router as a managed block in `$CODEX_HOME/AGENTS.md` (default `~/.codex/AGENTS.md`), so do not invoke the skill as well. Codex has no route gate: the `Read` of a routed file is the model's own mandatory step before the first edit of that artifact type.
|
|
14
14
|
- **Other harnesses (Kiro, Grok):** it is a skill; invoke it before acting on any task turn.
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
15
|
+
- **WorkBuddy:** a skill at `~/.workbuddy-ai/skills/`; invoke it before acting on any task turn, then `Read` `~/.aki/akidevrule/RULE-agent-behavior.md` once per session — this harness has no `@`-import or managed block, so the behavior floor is not resident and that read is what `(core)` reports. There is no route gate either.
|
|
16
|
+
- **Not routed here:** `RULE-agent-behavior.md` (`agent`) — core, harness-embedded (on WorkBuddy: the once-per-session `Read` named in Delivery above), never listed as `(router)`.
|
|
17
|
+
- **The second hop — reading a routed file — is the model's `Read`, and on Claude Code it is enforced for every route with an artifact signature:** the `aki-route-guard` PreToolUse hook denies the first Edit/Write of each artifact type in a session (code file → `coding`+`pattern`, `.md` → `docs`, `CHANGELOG.md` → `release`, `.vue`/`.css` → `ui`, Nuxt project → `stack`, `.rs` → `tauri`, `.sql` → `db`, `locales/` → `content`, test file or `test/` dir → `test`) until those files have been read whole in this transcript after the last compaction (a `Read` with `limit`/`offset` or a `head`/`sed`/`tail` print does not count, and the hook widens a partial `Read` of a rule file to the whole file) — a compaction drops them from context, and the `aki-compact-reread` SessionStart notice says so once; the deny reason names them — read them in full, update the receipt, retry the edit. The list above is the human summary; the path → rule map the hook, the audit and the lint read is `~/.aki/akidevrule/route-map.json`. Routes with no artifact signature (`think`, `proportion`, `biz`, `ux`, the audits) rely on this table alone, so nothing below is optional — it is the reason the receipt exists.
|
|
17
18
|
|
|
18
19
|
## How to route — meaning first, signals as evidence
|
|
19
20
|
|
|
@@ -35,8 +36,8 @@ All files live in `~/.aki/akidevrule/`.
|
|
|
35
36
|
| `RULE-docs.md` · `docs` | creates, edits, moves or completes any Markdown, doc, plan, instruction file (`CLAUDE.md`, `SKILL.md`, `README`, `CHANGELOG`), or checks docs against the code | any `.md`, `docs/**`, `SKILL.md`; docs, plan, README, diagram, mermaid, architecture, drift, stale/outdated docs · tài liệu, sơ đồ, kiến trúc, lệch, lỗi thời, rà soát tài liệu |
|
|
36
37
|
| `RULE-content-write.md` · `content` | writes, renames, translates or audits text an end user reads — UI copy, messages, labels, i18n strings, page metadata copy, articles and posts | button/label/heading, error message, tooltip, empty state, tone, i18n, locale, translation, `locales/**`, renaming a user-facing term, article, blog/news post, announcement, content data file (`posts.ts`, `content/**`) · nội dung giao diện, nhãn, thông báo lỗi, bản dịch, bài viết, tin tức, bài đăng |
|
|
37
38
|
| `RULE-stack-akiNuxtCf.md` · `stack` | works in a Nuxt / Vue / Cloudflare Pages-Workers project — ON for the whole project when its binding names that stack | `.vue`, `nuxt.config`, `wrangler.toml`, Nuxt, Vue, Cloudflare Workers/Pages, D1, KV, Nitro, composable, middleware, `useFetch`, breadcrumb, layout width |
|
|
38
|
-
| `RULE-stack-tauri.md` · `tauri` | works in a Tauri / Rust desktop project — ON for the whole project | `.rs`, `src-tauri/`, `tauri.conf.json`, `Cargo.toml`, `#[tauri::command]`, IPC, `spawn_blocking`, freeze, hang, blocking UI, settings breaking after an upgrade · treo app, đứng app, đơ, khựng |
|
|
39
|
-
| `RULE-ui-pattern.md` · `ui` | builds, styles, minimizes or audits frontend components, classes, tokens or style blocks, or implements a pointer/keyboard gesture | `.vue`/`.css`/`.scss`/`.tsx`, Tailwind, class, style block, inline style, design token, variant, `@apply`, `@theme`, arbitrary value, duplicate/bloated CSS, looks inconsistent, drag and drop, reorder, resize, slider, live preview then commit · dọn CSS, class trùng, tối giản CSS, nhiều CSS quá, kéo thả, sắp xếp lại, xem trước |
|
|
39
|
+
| `RULE-stack-tauri.md` · `tauri` | works in a Tauri / Rust desktop project — ON for the whole project | `.rs`, `src-tauri/`, `tauri.conf.json`, `Cargo.toml`, `#[tauri::command]`, IPC, `spawn_blocking`, freeze, hang, blocking UI, settings breaking after an upgrade, Windows build or path, `\\?\`, `PATHEXT`, os error 5 / 193, cross-compile, npm shim · treo app, đứng app, đơ, khựng, lỗi trên Windows |
|
|
40
|
+
| `RULE-ui-pattern.md` · `ui` | builds, styles, minimizes or audits frontend components, classes, tokens or style blocks, or implements a pointer/keyboard gesture | `.vue`/`.css`/`.scss`/`.tsx`, Tailwind, class, style block, inline style, design token, variant, `@apply`, `@theme`, arbitrary value, duplicate/bloated CSS, looks inconsistent, drag and drop, reorder, resize, slider, live preview then commit, popup, dialog, modal, toast, SweetAlert2 · dọn CSS, class trùng, tối giản CSS, nhiều CSS quá, kéo thả, sắp xếp lại, xem trước, hộp thoại, thông báo nổi |
|
|
40
41
|
| `RULE-seo.md` · `seo` | shapes how pages are found or represented — metadata, structured data, sitemap/robots, canonical/hreflang, search or AI visibility, entity identity | SEO, meta title/description, OG image, JSON-LD, schema.org, sitemap, robots, canonical, hreflang, trailing slash, absolute vs relative URL, image path, AI visibility, not indexed · không lên Google, link ảnh |
|
|
41
42
|
| `RULE-release.md` · `release` | records, versions, commits, pushes, tags, publishes, deploys or migrates; watches CI or verifies a deploy; or asks whether finished work is shippable | commit, push, deploy, tag, release, release notes, `CHANGELOG`, version, semver, bump, publish, npm/registry, 2FA/OTP, CI, GitHub Actions, migration, post-deploy, health check, "is it done / ready to ship?" · phát hành, phiên bản, nâng version, đẩy lên, triển khai, xong chưa, CI đỏ |
|
|
42
43
|
| `RULE-db-design.md` · `db` | designs or changes the shape of stored data — schema, migration, query structure, data refactor | `.sql`, `migrations/`, schema, table, column, index, D1, SQL, ERD, event sourcing, normalization, keeping history of a value, choosing a database · thiết kế DB, đổi schema, thêm cột |
|
|
@@ -70,7 +71,7 @@ One line at the start of the response, reporting the **whole rule context**:
|
|
|
70
71
|
| Element | Rule |
|
|
71
72
|
|---|---|
|
|
72
73
|
| Names | the topic beside each file in the Routes table, `agent` for the core file — no new vocabulary. An item inside a file is addressed `topic.A1`: group letter, item number (`coding.B2`) |
|
|
73
|
-
| `(core)` | the
|
|
74
|
+
| `(core)` | the resident behavior floor, always listed (`agent`): `@`-imported on Claude Code, a managed block on Codex, the once-per-session `Read` on WorkBuddy — its presence is otherwise unobservable |
|
|
74
75
|
| `(router)` | files this router loaded; full load writes `(router:full)` |
|
|
75
76
|
| `(brief)` | a worker/subagent's files named by its spawning prompt and actually read — it inherits no router, and emits the line first in its single round (`agent.A5`) |
|
|
76
77
|
|
package/skills/akiship/SKILL.md
CHANGED
|
@@ -22,7 +22,7 @@ If a step in this file disagrees with the rule file, the rule file wins — exce
|
|
|
22
22
|
|
|
23
23
|
**1. Release order.** The current user turn carries either the exact token `/akiship`, or a turn explicitly ordering the release ritual for this repo, in any wording (worked examples in the table below). A completion-intensity phrase with no release object activates nothing: it names no ritual, so it is ordinary vocabulary about finishing something, not an order to run this skill. Seeing this file, or `release.B8`, in context is not an invocation either: being loaded is not being called.
|
|
24
24
|
|
|
25
|
-
**2.
|
|
25
|
+
**2. An order, not a question** (`agent.A3`). The order alone authorizes nothing — the turn must ask for the run to be *performed*. Where both readings are available, consult.
|
|
26
26
|
|
|
27
27
|
**Why the token is not required.** The incident phrase ("tóm lại cần làm gì để trọn vẹn", `docs/research/akiship-literal-activation-aug22.md`) fails both conditions independently — no release object, and interrogative — and `agent.A3` alone was already resident when it misfired, which is why condition 1 stays a mechanical release-object check rather than judgment; the literal token on top adds only false negatives on a plainly-worded release order.
|
|
28
28
|
|
|
@@ -31,7 +31,7 @@ If a step in this file disagrees with the rule file, the rule file wins — exce
|
|
|
31
31
|
| `/akiship` · "release trọn vẹn đi" · "chạy full release" · "ship đợt này luôn" | **execute** — run the phases below |
|
|
32
32
|
| "nếu chạy /akiship thì cần gì để trọn vẹn?" · "/akiship sẽ làm những gì?" · "làm cho trọn vẹn" (no release object) | **consult / no activation** — read the checklist below and answer in chat what the run would do and what is still open on this tree; edit no file, no commit, no push, no tag, no release |
|
|
33
33
|
|
|
34
|
-
Consult is the default whenever both readings are available. A withheld execution costs one extra turn; a wrongly performed one costs a published push that cannot be taken back (`agent.A3`
|
|
34
|
+
Consult is the default whenever both readings are available. A withheld execution costs one extra turn; a wrongly performed one costs a published push that cannot be taken back (`agent.A3`).
|
|
35
35
|
|
|
36
36
|
## Phase 1 — front check (all asks happen here or never)
|
|
37
37
|
|
|
@@ -46,22 +46,22 @@ Run B7 steps 2–7 in order, fixing findings as they surface (this is a gate, no
|
|
|
46
46
|
|
|
47
47
|
- **Hygiene, diff scope only**: `python3 ~/.claude/skills/akiflow/scripts/scythe.py <files changed since boundary>` for `[WRAP]`/`[YAP]`; dead code / redundant guards / duplication the accumulation introduced (`pattern.A8`); doc refs in touched comments still resolve (`docs.B3`). Never widen to the whole repo.
|
|
48
48
|
- **Record shape (B7 step 4)**: `python3 ~/.claude/skills/akiflow/scripts/release_lint.py --latest .` — verdict tags fixed in place; each `[HILITE]` line gets a written answer in the receipt (`release.C2`).
|
|
49
|
-
- **Migration & external-action completeness — FIRST gate step, every release.** Run the `release.B5` detector over the accumulation diff and paste its output. A hit (startup-embedded migration code included) obliges written answers to B5 points 2–5, including a rehearsal from the PREVIOUS state; a pending migration qualifying under `stack.C8`'s execution-ownership clause is run here, not deferred. Then record truthfulness (CHANGELOG + `releases.json` parity where it exists) and doc sync over every record surface B7 step 5 enumerates (plans → `done/`, `arch`/`feat` stamps per `docs.A4`, `README.md`, the task-note file via `akidevsync-notes`, any standards doc the project `CLAUDE.md` binds).
|
|
49
|
+
- **Migration & external-action completeness — FIRST gate step, every release.** Run the `release.B5` detector over the accumulation diff and paste its output. A hit (startup-embedded migration code included) obliges written answers to B5 points 2–5, including a rehearsal from the PREVIOUS state; a pending migration qualifying under `stack.C8`'s execution-ownership clause is run here, not deferred. Then record truthfulness (CHANGELOG + `releases.json` parity where it exists) and doc sync over every record surface B7 step 5 enumerates (`python3 ~/.claude/skills/akiflow/scripts/plan_lint.py .` exit 0, plans → `done/`, `arch`/`feat` stamps per `docs.A4`, `README.md`, the task-note file via `akidevsync-notes`, any standards doc the project `CLAUDE.md` binds).
|
|
50
50
|
- **Build & test — mirror CI (B7 step 6)**: derive commands from `.github/workflows/*` first, else the manifest's own scripts; run them all locally; a failure blocks and is fixed in place, same as the hygiene step above; a CI-only leg (other-OS matrix, secrets) is named and left to `release.B10`.
|
|
51
|
-
- Verification honesty
|
|
51
|
+
- **Verification honesty (B7 step 7)**: each touched flow whose risk cannot be settled statically is run first (`coding.B3` rung 5: the app on a port of its own, or the CLI/binary/installer against a scratch HOME, the run recorded); what survives is **unverified** and blocks Phase 3 step 4. A migration that does not qualify above is carried to the final report as **unverified**, never silently assumed.
|
|
52
52
|
|
|
53
53
|
## Phase 3 — commit, mint, artifacts
|
|
54
54
|
|
|
55
55
|
1. Commit in logical groups per `/akigitcommit` (domain-grouped mode; anti-stage-loss rules apply in full). B8 pre-answers its confirmation step — "commit luôn" semantics.
|
|
56
56
|
2. Version decision per `release.A4`/`A5`: mint exactly once at the highest accumulated severity, or defer on the materiality test. Deferring is a normal outcome, not a failure.
|
|
57
57
|
3. Artifacts per the repo's own convention: bare tag only if the repo already tags (`release.A3` B8 exception); GitHub Release per `release.B4`; `releases.json` sync check per `release.C4`; registry publish per `release.B9` — tarball verified first, and an OTP-gated publish is the report's single hand-off with its `npm view` check.
|
|
58
|
-
4. **Push / deploy only if B8's push/deploy authorization holds for this invocation (named explicitly, or completion-intensity phrasing per `release.B8`).** Otherwise the run stays local-only. After any push, watch CI per `release.B10` — always, regardless of stack. If the stack additionally deploys on push, run live deploy verification per `release.C5` once CI is green. After ANY deploy or restart, `release.B11` is mandatory: verify a data path the release touched, not only the version.
|
|
58
|
+
4. **Push / deploy only if B8's push/deploy authorization holds for this invocation (named explicitly, or completion-intensity phrasing per `release.B8`) and no flow the accumulation touched is left `unverified` (B7 step 7).** Otherwise the run stays local-only. The hold is mechanical: write the Report's first block to a scratchpad file (`agent.C5`) and run `python3 ~/.claude/skills/akiflow/scripts/ship_gate.py <file>`; any exit but 0 means no push, no tag push and no deploy, whatever the invocation said — fix what it names and rerun, or report its lines as the run's `Q` items. After any push, watch CI per `release.B10` — always, regardless of stack. If the stack additionally deploys on push, run live deploy verification per `release.C5` once CI is green. After ANY deploy or restart, `release.B11` is mandatory: verify a data path the release touched, not only the version.
|
|
59
59
|
|
|
60
60
|
## Report
|
|
61
61
|
|
|
62
|
-
**The FIRST block is the checklist receipt, and it is mandatory:** the `release.B7` lines `S0`–`S8` (`PASS | FIXED | FAIL | N/A — evidence`), the B5 detector output,
|
|
62
|
+
**The FIRST block is the checklist receipt, and it is mandatory:** the `release.B7` lines `S0`–`S8` (`PASS | FIXED | FAIL | N/A — evidence`), the B5 detector output, the four written self-interrogation answers as lines `(1)`–`(4)`, and each open item as a line starting with its code (`Q1 …`, `N1 …`) — the grammar `ship_gate.py` reads. A report without them declares the run INCOMPLETE and says which steps were NOT RUN; an unreported step is a failed step (`release.B7` fail-closed contract), never an implicit pass.
|
|
63
63
|
|
|
64
|
-
Then one dense summary (`agent.A4`): state derived → findings fixed (counts per gate step) → commits made → version minted or deferred with the reason → artifacts created → CI results (`release.B10`) → any owner-worded criteria self-decided this run, as an `agent.A3` decision block (`Decided: X · because Y · rejected Z (why) · reopen if W`) → anything left **unverified**, each with the exact command that would settle it
|
|
64
|
+
Then one dense summary (`agent.A4`): state derived → findings fixed (counts per gate step) → commits made → version minted or deferred with the reason → artifacts created → CI results (`release.B10`) → any owner-worded criteria self-decided this run, as an `agent.A3` decision block (`Decided: X · because Y · rejected Z (why) · reopen if W`) → anything left **unverified**, each with the rung that failed and the exact command that would settle it: a `Q` when it touches a flow the accumulation changed (push and deploy held), else an `N`.
|
|
65
65
|
|
|
66
66
|
**The LAST block is the release copy, every run, in `release.B6`'s shape** — Headline, Short, Full, and the announce verdict — quoting the `releases.json` entry and GitHub Release body the run already wrote rather than composing a third text; a deferred version prints `deferred — no copy`. It is the owner's paste-ready text for whatever channel they announce on (a post, a notification, a store listing); the block never names a channel the project's own records do not.
|
|
67
67
|
|
package/skills/akithink/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: akithink
|
|
3
|
-
description: Structured deep thinking for decisions — restate the problem, excavate the goal chain to the ultimate goal, first-principles decomposition (facts/constraints/assumptions), mandatory critique (steelman, inversion, pre-mortem), then converge into a decision record. Thinking only: it never edits, runs or ships anything —
|
|
3
|
+
description: Structured deep thinking for decisions — restate the problem, excavate the goal chain to the ultimate goal, first-principles decomposition (facts/constraints/assumptions), mandatory critique (steelman, inversion, pre-mortem), then converge into a decision record. Thinking only: it never edits, runs or ships anything — acting on the record needs the owner's order (`agent.A3`), outside this skill. Self-run mode (non-interactive, decide and report) fires on an `agent.A3` deep-think trigger or on owner authorization; trivial two-way-door calls stay inline. Interactive session only when the owner asks for one. Best on a top-tier model (Opus/Fable).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# akithink — structured deep-thinking session
|
|
@@ -60,7 +60,7 @@ Runs all phases without waiting, when the owner authorizes the agent to decide o
|
|
|
60
60
|
- Phase 1 restatement is written, not confirmed.
|
|
61
61
|
- The Interaction rules pacing (1–2 questions per turn) does not apply — no questions are asked mid-session.
|
|
62
62
|
- Questions reach the owner only via `agent.A3`'s escalation outcomes, never through this skill's own turn-by-turn interaction.
|
|
63
|
-
- Phase 5 converges and reports the decision block (`agent.A3`'s converged outcome), and the session ends there. This skill thinks and never acts (`pattern.A3`):
|
|
63
|
+
- Phase 5 converges and reports the decision block (`agent.A3`'s converged outcome), and the session ends there. This skill thinks and never acts (`pattern.A3`): an order proceeds under `agent.A3`; a communication turn gets the block and nothing else. A durable decision gets a decision-record doc per `RULE-docs.md` — written on an order, proposed on a communication turn.
|
|
64
64
|
|
|
65
65
|
## Invocation scope
|
|
66
66
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: noyap
|
|
3
|
+
description: Rewrite the reply just given, or answer the current request, keeping only the answer asked for and what the owner must do or heed — obvious, redundant and process ideas are cut, never compressed. The fix procedure behind the `[FLUFF]` penalty card on a reply (RULE-agent-behavior.md §0, root `agent.A4`). Use whenever the owner says a reply is too long or asks for a short one, in any language — `[FLUFF]`, "noyap", "no yapping", TL;DR, "too long", "shorter". Replies to the owner only; a `[FLUFF]` on a file is fixed under `docs.B3`, not here.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# noyap — the answer, and what the owner must act on; nothing else
|
|
8
|
+
|
|
9
|
+
## Invocation
|
|
10
|
+
|
|
11
|
+
- Bare `/noyap`, `[FLUFF]` or the word, after a reply → rewrite that reply. Card semantics (`agent.§0`): every instance, not only the cited one.
|
|
12
|
+
- `/noyap <request>`, or a request carrying "no yapping" / "keep it short" in any language → answer it this way the first time.
|
|
13
|
+
- Once invoked, every later reply to the owner in this conversation keeps this shape until the owner asks for detail. Worker briefs, files and commit messages keep their own rules (`agent.A5`, `docs.B3`, `release`).
|
|
14
|
+
|
|
15
|
+
## What stays — everything else is cut, never moved to a note or an `N`
|
|
16
|
+
|
|
17
|
+
1. The `[RULES]` receipt when the set changed (`akirule` § Load confirmation).
|
|
18
|
+
2. **The answer**, in the first words: the state or decision asked for; a yes/no question starts with yes or no.
|
|
19
|
+
3. **What the owner must do or heed**: an act only their hands can do, a decision only they can make (`agent.A3` escalation list), a risk that changes their next step, the workflow's next step (`agent.A4` closing line). One plain sentence each, with its weight; a surviving open item keeps its `agent.A4` letter and number so the owner can name it.
|
|
20
|
+
|
|
21
|
+
An idea stays only if the owner asked for it, or without it the owner would do or decide something differently. True, new, careful-looking or "might want to know" is not a reason.
|
|
22
|
+
|
|
23
|
+
## Leftovers are settled, never listed
|
|
24
|
+
|
|
25
|
+
- Doable within the order already given → do it before replying (`agent.A4`); report it done in a few words, or not at all.
|
|
26
|
+
- Not important — the owner would act the same either way (`agent.A3` Impact test) → say nothing about it.
|
|
27
|
+
- Important and decidable — a call within the order, or a question failing an `agent.A3` kill-test → self-run `/akithink` until it converges, then report `agent.A3`'s decision block in plain words.
|
|
28
|
+
|
|
29
|
+
## Always cut
|
|
30
|
+
|
|
31
|
+
Passed checks, except the run record kept below; files touched; how the work was done; which seat, model or run produced it; the work's scope or cost; a file's or prior message's content (give its path and a few-word gloss); a hypothetical that has not happened; reasoning for an answer the owner did not question; apology or self-assessment; the preambles, progress lines and recaps a harness asks for (`agent.B7`: brevity shapes prose, never steps); "shorter version:"; any mention of this skill.
|
|
32
|
+
|
|
33
|
+
## Kept exact, said short
|
|
34
|
+
|
|
35
|
+
- A word carrying state, tense, negation or number (đã, chưa, không, "not yet").
|
|
36
|
+
- A failed check or an unverified claim: its status in a few words on the claim itself, never a paragraph (`agent.B2`).
|
|
37
|
+
- An exact command, path, error or version the owner needs to act. A code, marker or term the owner did not name is said in plain words or dropped, never kept to save space.
|
|
38
|
+
- A shape another rule or skill mandates — `agent.A3`'s decision block, a rule line quoted with its meaning lines, an `akiship` or audit report, a worker receipt, the `coding.B3` run record a done-claim rests on (one line: command · exit · log path) — stays as that rule defines it; this skill shapes only the prose around it.
|
|
39
|
+
|
|
40
|
+
## Writing
|
|
41
|
+
|
|
42
|
+
- Plain full sentences, one idea per line, key term first, in the conversation's language (`agent.A1`), never flipped to English to save words; no fragments, no invented codes.
|
|
43
|
+
- A rewrite lands at 10–40% of the reply it replaces, mandated shapes aside, because ideas were cut, never because words were squeezed; over 40% means an idea failing the test above is still in.
|
|
44
|
+
- Send the final reply only; the sorting happens in thinking, never printed, and no count, script or hook ever measures it (`[FLUFF]` is judgment, `agent.§0`).
|