arkaos 4.5.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/CONSTITUTION.md +30 -16
  2. package/VERSION +1 -1
  3. package/arka/SKILL.md +26 -35
  4. package/arka/skills/bootstrap-agent/SKILL.md +6 -0
  5. package/arka/skills/checkpoint/SKILL.md +1 -1
  6. package/arka/skills/costs/SKILL.md +14 -5
  7. package/arka/skills/flow/SKILL.md +29 -14
  8. package/arka/skills/forge/SKILL.md +19 -15
  9. package/arka/skills/human-writing/SKILL.md +16 -7
  10. package/arka/skills/research/SKILL.md +20 -7
  11. package/arka/templates/skill-template.md +102 -0
  12. package/config/claude-agents/architect.md +51 -0
  13. package/config/claude-agents/backend-dev.md +51 -0
  14. package/config/claude-agents/dba.md +51 -0
  15. package/config/claude-agents/devops-eng.md +51 -0
  16. package/config/claude-agents/eduardo-copy.md +14 -7
  17. package/config/claude-agents/francisca-tech.md +24 -6
  18. package/config/claude-agents/frontend-dev.md +51 -0
  19. package/config/claude-agents/marta-cqo.md +28 -8
  20. package/config/claude-agents/qa-eng.md +51 -0
  21. package/config/claude-agents/research-assistant.md +50 -0
  22. package/config/claude-agents/security-eng.md +51 -0
  23. package/config/constitution.yaml +127 -88
  24. package/config/hooks/session-start.ps1 +3 -1
  25. package/config/hooks/session-start.sh +3 -1
  26. package/config/hooks/user-prompt-submit-v2.sh +4 -11
  27. package/config/hooks/user-prompt-submit.ps1 +4 -7
  28. package/config/hooks/user-prompt-submit.sh +1 -1
  29. package/core/agents/__pycache__/behavioral_compiler.cpython-313.pyc +0 -0
  30. package/core/agents/behavioral_compiler.py +294 -0
  31. package/core/governance/__pycache__/closing_marker_check.cpython-313.pyc +0 -0
  32. package/core/governance/__pycache__/closing_marker_check.cpython-314.pyc +0 -0
  33. package/core/governance/__pycache__/phantom_action_check.cpython-313.pyc +0 -0
  34. package/core/governance/__pycache__/phantom_action_check.cpython-314.pyc +0 -0
  35. package/core/governance/__pycache__/qg_verdict.cpython-313.pyc +0 -0
  36. package/core/governance/closing_marker_check.py +2 -2
  37. package/core/governance/phantom_action_check.py +206 -0
  38. package/core/governance/qg_verdict.py +12 -0
  39. package/core/hooks/__pycache__/post_tool_use.cpython-313.pyc +0 -0
  40. package/core/hooks/__pycache__/stop.cpython-313.pyc +0 -0
  41. package/core/hooks/__pycache__/stop.cpython-314.pyc +0 -0
  42. package/core/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  43. package/core/hooks/post_tool_use.py +10 -0
  44. package/core/hooks/stop.py +25 -0
  45. package/core/hooks/user_prompt_submit.py +6 -8
  46. package/core/knowledge/__pycache__/vector_store.cpython-312.pyc +0 -0
  47. package/core/runtime/__pycache__/mcp_telemetry.cpython-313.pyc +0 -0
  48. package/core/runtime/__pycache__/mcp_telemetry_cli.cpython-313.pyc +0 -0
  49. package/core/runtime/mcp_telemetry.py +184 -0
  50. package/core/runtime/mcp_telemetry_cli.py +62 -0
  51. package/core/shared/__pycache__/temp_paths.cpython-312.pyc +0 -0
  52. package/core/synapse/__pycache__/engine.cpython-312.pyc +0 -0
  53. package/core/synapse/__pycache__/engine.cpython-313.pyc +0 -0
  54. package/core/synapse/__pycache__/engine.cpython-314.pyc +0 -0
  55. package/core/synapse/__pycache__/layers.cpython-312.pyc +0 -0
  56. package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
  57. package/core/synapse/__pycache__/layers.cpython-314.pyc +0 -0
  58. package/core/synapse/engine.py +4 -2
  59. package/core/synapse/layers.py +0 -49
  60. package/dashboard/package.json +1 -1
  61. package/departments/brand/SKILL.md +5 -13
  62. package/departments/brand/skills/archetype-finder/SKILL.md +3 -11
  63. package/departments/brand/skills/colors/SKILL.md +3 -11
  64. package/departments/brand/skills/design-review/SKILL.md +11 -3
  65. package/departments/brand/skills/design-system/SKILL.md +3 -11
  66. package/departments/brand/skills/identity-system/SKILL.md +3 -11
  67. package/departments/brand/skills/logo-brief/SKILL.md +3 -11
  68. package/departments/brand/skills/mockup-generate/SKILL.md +3 -11
  69. package/departments/brand/skills/naming-evaluate/SKILL.md +3 -11
  70. package/departments/brand/skills/positioning-statement/SKILL.md +3 -11
  71. package/departments/brand/skills/primal-audit/SKILL.md +3 -11
  72. package/departments/brand/skills/ux-audit/SKILL.md +3 -11
  73. package/departments/brand/skills/voice-guide/SKILL.md +3 -11
  74. package/departments/brand/skills/wireframe/SKILL.md +3 -11
  75. package/departments/community/SKILL.md +4 -12
  76. package/departments/community/skills/ai-community/SKILL.md +3 -11
  77. package/departments/community/skills/betting-setup/SKILL.md +3 -11
  78. package/departments/community/skills/business-model/SKILL.md +3 -11
  79. package/departments/community/skills/content-calendar/SKILL.md +3 -11
  80. package/departments/community/skills/events-plan/SKILL.md +3 -11
  81. package/departments/community/skills/gamification-design/SKILL.md +3 -11
  82. package/departments/community/skills/growth-plan/SKILL.md +13 -12
  83. package/departments/community/skills/metrics-track/SKILL.md +3 -11
  84. package/departments/community/skills/moderation/SKILL.md +3 -11
  85. package/departments/community/skills/monetize-plan/SKILL.md +3 -11
  86. package/departments/community/skills/niche-setup/SKILL.md +3 -11
  87. package/departments/community/skills/onboarding-flow/SKILL.md +3 -11
  88. package/departments/community/skills/platform-select/SKILL.md +3 -11
  89. package/departments/content/SKILL.md +4 -12
  90. package/departments/content/skills/ai-workflow/SKILL.md +3 -11
  91. package/departments/content/skills/analytics/SKILL.md +3 -11
  92. package/departments/content/skills/calendar/SKILL.md +3 -11
  93. package/departments/content/skills/content-system/SKILL.md +3 -11
  94. package/departments/content/skills/monetization-plan/SKILL.md +3 -11
  95. package/departments/content/skills/newsletter-write/SKILL.md +3 -11
  96. package/departments/content/skills/platform-optimize/SKILL.md +3 -11
  97. package/departments/content/skills/repurpose-plan/SKILL.md +3 -11
  98. package/departments/content/skills/script-structure/SKILL.md +3 -11
  99. package/departments/content/skills/short-form/SKILL.md +3 -11
  100. package/departments/content/skills/thumbnail-package/SKILL.md +3 -11
  101. package/departments/content/skills/viral-design/SKILL.md +3 -11
  102. package/departments/content/skills/youtube-strategy/SKILL.md +3 -11
  103. package/departments/dev/SKILL.md +4 -12
  104. package/departments/dev/agents/security-eng.yaml +1 -1
  105. package/departments/dev/skills/adversarial-review/SKILL.md +10 -2
  106. package/departments/dev/skills/ai-assisted-dev/SKILL.md +3 -11
  107. package/departments/dev/skills/architecture-design/SKILL.md +3 -11
  108. package/departments/dev/skills/clean-code-review/SKILL.md +9 -2
  109. package/departments/dev/skills/code-review/SKILL.md +12 -12
  110. package/departments/dev/skills/db-design/SKILL.md +3 -11
  111. package/departments/dev/skills/ddd-model/SKILL.md +3 -11
  112. package/departments/dev/skills/demo-gif/SKILL.md +3 -11
  113. package/departments/dev/skills/deploy/SKILL.md +3 -11
  114. package/departments/dev/skills/devops-pipeline/SKILL.md +3 -11
  115. package/departments/dev/skills/docs/SKILL.md +3 -11
  116. package/departments/dev/skills/mcp/SKILL.md +3 -11
  117. package/departments/dev/skills/performance-audit/SKILL.md +3 -11
  118. package/departments/dev/skills/refactor-plan/SKILL.md +3 -11
  119. package/departments/dev/skills/research/SKILL.md +16 -12
  120. package/departments/dev/skills/security-compliance/SKILL.md +3 -11
  121. package/departments/dev/skills/spec/SKILL.md +15 -10
  122. package/departments/dev/skills/stack-check/SKILL.md +3 -11
  123. package/departments/ecom/SKILL.md +4 -12
  124. package/departments/ecom/skills/analytics/SKILL.md +3 -11
  125. package/departments/ecom/skills/browse-competitor/SKILL.md +3 -11
  126. package/departments/ecom/skills/cart-recovery/SKILL.md +3 -11
  127. package/departments/ecom/skills/cro-optimize/SKILL.md +3 -11
  128. package/departments/ecom/skills/customer-journey/SKILL.md +3 -11
  129. package/departments/ecom/skills/fulfillment-plan/SKILL.md +3 -11
  130. package/departments/ecom/skills/marketplace-manage/SKILL.md +3 -11
  131. package/departments/ecom/skills/pricing-strategy/SKILL.md +3 -11
  132. package/departments/ecom/skills/product-launch/SKILL.md +3 -11
  133. package/departments/ecom/skills/rfm-segment/SKILL.md +3 -11
  134. package/departments/ecom/skills/social-commerce/SKILL.md +3 -11
  135. package/departments/ecom/skills/store-audit/SKILL.md +3 -11
  136. package/departments/ecom/skills/subscription-model/SKILL.md +3 -11
  137. package/departments/finance/SKILL.md +4 -12
  138. package/departments/finance/skills/budget-plan/SKILL.md +3 -11
  139. package/departments/finance/skills/cashflow-forecast/SKILL.md +3 -11
  140. package/departments/finance/skills/ciso-advisor/SKILL.md +3 -11
  141. package/departments/finance/skills/financial-model/SKILL.md +3 -11
  142. package/departments/finance/skills/pitch-deck/SKILL.md +3 -11
  143. package/departments/finance/skills/scenario-analysis/SKILL.md +3 -11
  144. package/departments/finance/skills/unit-economics/SKILL.md +3 -11
  145. package/departments/finance/skills/valuation-model/SKILL.md +3 -11
  146. package/departments/kb/SKILL.md +4 -12
  147. package/departments/kb/skills/ai-research/SKILL.md +3 -11
  148. package/departments/kb/skills/competitive-intel/SKILL.md +3 -11
  149. package/departments/kb/skills/knowledge-review/SKILL.md +3 -11
  150. package/departments/kb/skills/learn-content/SKILL.md +3 -11
  151. package/departments/kb/skills/moc-create/SKILL.md +3 -11
  152. package/departments/kb/skills/persona-build/SKILL.md +3 -11
  153. package/departments/kb/skills/research-plan/SKILL.md +3 -11
  154. package/departments/kb/skills/search-kb/SKILL.md +3 -11
  155. package/departments/kb/skills/source-evaluate/SKILL.md +3 -11
  156. package/departments/kb/skills/taxonomy-manage/SKILL.md +3 -11
  157. package/departments/kb/skills/write-as-persona/SKILL.md +3 -11
  158. package/departments/landing/SKILL.md +4 -12
  159. package/departments/landing/skills/ab-test/SKILL.md +3 -11
  160. package/departments/landing/skills/affiliate-bridge/SKILL.md +3 -11
  161. package/departments/landing/skills/awareness-diagnose/SKILL.md +3 -11
  162. package/departments/landing/skills/copy-framework/SKILL.md +1 -1
  163. package/departments/landing/skills/email-sequence/SKILL.md +3 -11
  164. package/departments/landing/skills/funnel-metrics/SKILL.md +3 -11
  165. package/departments/landing/skills/headline-write/SKILL.md +3 -11
  166. package/departments/landing/skills/launch-sequence/SKILL.md +3 -11
  167. package/departments/landing/skills/offer-create/SKILL.md +3 -11
  168. package/departments/landing/skills/optimize-page/SKILL.md +3 -11
  169. package/departments/landing/skills/page-architect/SKILL.md +3 -11
  170. package/departments/landing/skills/persuasion-apply/SKILL.md +3 -11
  171. package/departments/landing/skills/webinar-funnel/SKILL.md +3 -11
  172. package/departments/leadership/SKILL.md +4 -12
  173. package/departments/leadership/skills/change-manage/SKILL.md +3 -11
  174. package/departments/leadership/skills/conflict-resolve/SKILL.md +3 -11
  175. package/departments/leadership/skills/culture-audit/SKILL.md +3 -11
  176. package/departments/leadership/skills/delegation-matrix/SKILL.md +3 -11
  177. package/departments/leadership/skills/disc-assess/SKILL.md +3 -11
  178. package/departments/leadership/skills/feedback-give/SKILL.md +3 -11
  179. package/departments/leadership/skills/hiring-plan/SKILL.md +3 -11
  180. package/departments/leadership/skills/performance-review/SKILL.md +3 -11
  181. package/departments/marketing/SKILL.md +4 -12
  182. package/departments/marketing/skills/ab-test/SKILL.md +3 -11
  183. package/departments/marketing/skills/analytics-report/SKILL.md +3 -11
  184. package/departments/marketing/skills/audience-segment/SKILL.md +3 -11
  185. package/departments/marketing/skills/calendar-plan/SKILL.md +3 -11
  186. package/departments/marketing/skills/competitor-analysis/SKILL.md +3 -11
  187. package/departments/marketing/skills/content-audit/SKILL.md +3 -11
  188. package/departments/marketing/skills/email-sequence/SKILL.md +3 -11
  189. package/departments/marketing/skills/growth-loop/SKILL.md +15 -13
  190. package/departments/marketing/skills/marketing-automation/SKILL.md +3 -11
  191. package/departments/marketing/skills/paid-campaign/SKILL.md +3 -11
  192. package/departments/marketing/skills/programmatic-seo/SKILL.md +3 -11
  193. package/departments/marketing/skills/seo-audit/SKILL.md +3 -11
  194. package/departments/marketing/skills/social-strategy/SKILL.md +3 -11
  195. package/departments/ops/SKILL.md +4 -12
  196. package/departments/ops/skills/bottleneck-find/SKILL.md +3 -11
  197. package/departments/ops/skills/dashboard-build/SKILL.md +3 -11
  198. package/departments/ops/skills/gdpr-compliance/SKILL.md +3 -11
  199. package/departments/ops/skills/gtd-setup/SKILL.md +3 -11
  200. package/departments/ops/skills/integration-design/SKILL.md +3 -11
  201. package/departments/ops/skills/iso27001/SKILL.md +3 -11
  202. package/departments/ops/skills/lean-audit/SKILL.md +3 -11
  203. package/departments/ops/skills/metrics-dashboard/SKILL.md +3 -11
  204. package/departments/ops/skills/n8n-flow/SKILL.md +3 -11
  205. package/departments/ops/skills/quality-management/SKILL.md +3 -11
  206. package/departments/ops/skills/risk-management/SKILL.md +3 -11
  207. package/departments/ops/skills/soc2-compliance/SKILL.md +3 -11
  208. package/departments/ops/skills/sop-create/SKILL.md +3 -11
  209. package/departments/ops/skills/workflow-automate/SKILL.md +3 -11
  210. package/departments/ops/skills/zapier-flow/SKILL.md +3 -11
  211. package/departments/org/SKILL.md +4 -12
  212. package/departments/org/skills/compensation-plan/SKILL.md +3 -11
  213. package/departments/org/skills/culture-define/SKILL.md +3 -11
  214. package/departments/org/skills/decision-framework/SKILL.md +3 -11
  215. package/departments/org/skills/hiring-plan/SKILL.md +3 -11
  216. package/departments/org/skills/meeting-optimize/SKILL.md +3 -11
  217. package/departments/org/skills/onboarding-design/SKILL.md +3 -11
  218. package/departments/org/skills/org-design/SKILL.md +3 -11
  219. package/departments/org/skills/remote-setup/SKILL.md +3 -11
  220. package/departments/org/skills/sop-process/SKILL.md +3 -11
  221. package/departments/org/skills/team-assess/SKILL.md +3 -11
  222. package/departments/pm/SKILL.md +4 -12
  223. package/departments/pm/skills/backlog-groom/SKILL.md +3 -11
  224. package/departments/pm/skills/discovery-plan/SKILL.md +3 -11
  225. package/departments/pm/skills/estimate-forecast/SKILL.md +3 -11
  226. package/departments/pm/skills/impact-map/SKILL.md +3 -11
  227. package/departments/pm/skills/kanban-setup/SKILL.md +3 -11
  228. package/departments/pm/skills/risk-register/SKILL.md +3 -11
  229. package/departments/pm/skills/roadmap-build/SKILL.md +3 -11
  230. package/departments/pm/skills/sprint-plan/SKILL.md +3 -11
  231. package/departments/pm/skills/stakeholder-map/SKILL.md +3 -11
  232. package/departments/pm/skills/standup-run/SKILL.md +3 -11
  233. package/departments/pm/skills/story-write/SKILL.md +3 -11
  234. package/departments/quality/agents/copy-director.yaml +10 -4
  235. package/departments/saas/SKILL.md +4 -12
  236. package/departments/saas/skills/benchmark-compare/SKILL.md +3 -11
  237. package/departments/saas/skills/churn-analysis/SKILL.md +3 -11
  238. package/departments/saas/skills/customer-success/SKILL.md +3 -11
  239. package/departments/saas/skills/growth-plan/SKILL.md +13 -12
  240. package/departments/saas/skills/gtm-strategy/SKILL.md +3 -11
  241. package/departments/saas/skills/launch-execute/SKILL.md +3 -11
  242. package/departments/saas/skills/metrics-dashboard/SKILL.md +3 -11
  243. package/departments/saas/skills/micro-saas-stack/SKILL.md +3 -11
  244. package/departments/saas/skills/mvp-build/SKILL.md +3 -11
  245. package/departments/saas/skills/niche-evaluate/SKILL.md +13 -12
  246. package/departments/saas/skills/onboarding-optimize/SKILL.md +3 -11
  247. package/departments/saas/skills/plg-setup/SKILL.md +3 -11
  248. package/departments/saas/skills/pricing-strategy/SKILL.md +3 -11
  249. package/departments/saas/skills/validate-idea/SKILL.md +13 -13
  250. package/departments/sales/SKILL.md +4 -12
  251. package/departments/sales/skills/challenger-sell/SKILL.md +3 -11
  252. package/departments/sales/skills/deal-qualify/SKILL.md +3 -11
  253. package/departments/sales/skills/discovery-call/SKILL.md +3 -11
  254. package/departments/sales/skills/forecast-revenue/SKILL.md +3 -11
  255. package/departments/sales/skills/negotiate-plan/SKILL.md +3 -11
  256. package/departments/sales/skills/objection-handle/SKILL.md +3 -11
  257. package/departments/sales/skills/pipeline-manage/SKILL.md +3 -11
  258. package/departments/sales/skills/pricing-negotiate/SKILL.md +3 -11
  259. package/departments/strategy/SKILL.md +4 -12
  260. package/departments/strategy/skills/blue-ocean/SKILL.md +3 -11
  261. package/departments/strategy/skills/bmc/SKILL.md +3 -11
  262. package/departments/strategy/skills/board-advisor/SKILL.md +3 -11
  263. package/departments/strategy/skills/cto-advisor/SKILL.md +3 -11
  264. package/departments/strategy/skills/extract-data/SKILL.md +3 -11
  265. package/departments/strategy/skills/five-forces/SKILL.md +3 -11
  266. package/departments/strategy/skills/growth-strategy/SKILL.md +15 -14
  267. package/departments/strategy/skills/moat-analysis/SKILL.md +3 -11
  268. package/departments/strategy/skills/position/SKILL.md +3 -11
  269. package/departments/strategy/skills/scenario-plan/SKILL.md +3 -11
  270. package/package.json +1 -1
  271. package/pyproject.toml +1 -1
  272. package/scripts/__pycache__/migrate_skills_kb_first.cpython-313.pyc +0 -0
  273. package/scripts/migrate_skills_kb_first.py +41 -21
  274. package/scripts/tools/__pycache__/prompt_lint.cpython-313.pyc +0 -0
  275. package/scripts/tools/prompt_lint.py +276 -0
@@ -0,0 +1,184 @@
1
+ """MCP usage telemetry (audit E2E v4.3.6, P1).
2
+
3
+ Writer + summarizer for ``~/.arkaos/telemetry/mcp-usage.jsonl``. The
4
+ PostToolUse hook calls :func:`record` on every tool event; MCP tool
5
+ names (``mcp__<server>__<tool>``) are parsed and appended as one JSONL
6
+ line, everything else is ignored. Before this module the only usage
7
+ signal was grepping session transcripts.
8
+
9
+ Mirrors ``core.governance.enforcement_telemetry`` so periods,
10
+ malformed-line tolerance, and zero-division safety behave the same way
11
+ across telemetry surfaces. :func:`summarise` is read-only.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ from collections import Counter
18
+ from dataclasses import dataclass, field
19
+ from datetime import datetime, timedelta, timezone
20
+ from pathlib import Path
21
+ from typing import Any, Iterable
22
+
23
+ DEFAULT_PATH: Path = Path.home() / ".arkaos" / "telemetry" / "mcp-usage.jsonl"
24
+ _VALID_PERIODS: frozenset[str] = frozenset({"today", "week", "month", "all"})
25
+ _TOP_SERVERS: int = 10
26
+ _TOP_TOOLS: int = 5
27
+ _MCP_PREFIX = "mcp__"
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class McpUsageSummary:
32
+ """Aggregated MCP usage over a time slice."""
33
+ period: str
34
+ total_calls: int
35
+ unique_servers: int
36
+ top_servers: list[tuple[str, int]] = field(default_factory=list)
37
+ top_tools: list[tuple[str, int]] = field(default_factory=list)
38
+ corrupt_line_count: int = 0
39
+
40
+
41
+ def parse_mcp_tool(tool_name: str) -> tuple[str, str] | None:
42
+ """Split ``mcp__<server>__<tool>`` into (server, tool).
43
+
44
+ Returns None for non-MCP tool names. Handles servers whose slug
45
+ contains single underscores (``claude_ai_Canva``, plugin servers
46
+ like ``plugin_claude-mem_mcp-search``) by splitting on the FIRST
47
+ double underscore after the prefix.
48
+ """
49
+ if not tool_name.startswith(_MCP_PREFIX):
50
+ return None
51
+ rest = tool_name[len(_MCP_PREFIX):]
52
+ server, sep, tool = rest.partition("__")
53
+ if not sep or not server or not tool:
54
+ return None
55
+ return server, tool
56
+
57
+
58
+ def record(
59
+ tool_name: str,
60
+ *,
61
+ session_id: str = "",
62
+ path: Path | None = None,
63
+ ) -> bool:
64
+ """Append one usage line when tool_name is an MCP tool.
65
+
66
+ Never raises — the caller is a hook that must not block on
67
+ telemetry. Returns True when a line was written.
68
+ """
69
+ parsed = parse_mcp_tool(tool_name)
70
+ if parsed is None:
71
+ return False
72
+ server, tool = parsed
73
+ dest = path or DEFAULT_PATH
74
+ entry = {
75
+ "ts": datetime.now(timezone.utc).isoformat(),
76
+ "server": server,
77
+ "tool": tool,
78
+ "session": session_id,
79
+ }
80
+ try:
81
+ dest.parent.mkdir(parents=True, exist_ok=True)
82
+ with dest.open("a", encoding="utf-8") as fh:
83
+ fh.write(json.dumps(entry, ensure_ascii=False) + "\n")
84
+ except OSError:
85
+ return False
86
+ return True
87
+
88
+
89
+ def summarise(period: str, *, path: Path | None = None) -> McpUsageSummary:
90
+ """Return a McpUsageSummary for the requested period.
91
+
92
+ period: one of "today", "week", "month", "all".
93
+ path: override telemetry source (used by tests; defaults to DEFAULT_PATH).
94
+ """
95
+ if period not in _VALID_PERIODS:
96
+ raise ValueError(f"invalid period: {period!r}")
97
+ src = path or DEFAULT_PATH
98
+ cutoff = _period_cutoff(period)
99
+ entries, corrupt = _read_jsonl(src, cutoff)
100
+ return _build_summary(period, entries, corrupt)
101
+
102
+
103
+ def _period_cutoff(period: str, now: datetime | None = None) -> datetime | None:
104
+ ref = now or datetime.now(timezone.utc)
105
+ if period == "today":
106
+ return ref.replace(hour=0, minute=0, second=0, microsecond=0)
107
+ if period == "week":
108
+ return ref - timedelta(days=7)
109
+ if period == "month":
110
+ return ref - timedelta(days=30)
111
+ return None
112
+
113
+
114
+ def _read_jsonl(src: Path, cutoff: datetime | None) -> tuple[list[dict[str, Any]], int]:
115
+ if not src.exists():
116
+ return [], 0
117
+ entries: list[dict[str, Any]] = []
118
+ corrupt = 0
119
+ # Line-stream to keep memory O(1) — this file grows on every MCP call.
120
+ try:
121
+ with src.open("r", encoding="utf-8", errors="replace") as fh:
122
+ for line in fh:
123
+ if not line.strip():
124
+ continue
125
+ try:
126
+ entry = json.loads(line)
127
+ except json.JSONDecodeError:
128
+ corrupt += 1
129
+ continue
130
+ if not isinstance(entry, dict):
131
+ corrupt += 1
132
+ continue
133
+ if cutoff is not None and not _within_cutoff(entry, cutoff):
134
+ continue
135
+ entries.append(entry)
136
+ except OSError:
137
+ return entries, corrupt
138
+ return entries, corrupt
139
+
140
+
141
+ def _within_cutoff(entry: dict[str, Any], cutoff: datetime) -> bool:
142
+ ts = _parse_ts(entry.get("ts"))
143
+ if ts is None:
144
+ return False
145
+ return ts >= cutoff
146
+
147
+
148
+ def _parse_ts(raw: Any) -> datetime | None:
149
+ if not isinstance(raw, str) or not raw:
150
+ return None
151
+ try:
152
+ parsed = datetime.fromisoformat(raw.replace("Z", "+00:00"))
153
+ except ValueError:
154
+ return None
155
+ if parsed.tzinfo is None:
156
+ parsed = parsed.replace(tzinfo=timezone.utc)
157
+ return parsed
158
+
159
+
160
+ def _build_summary(
161
+ period: str,
162
+ entries: Iterable[dict[str, Any]],
163
+ corrupt: int,
164
+ ) -> McpUsageSummary:
165
+ total = 0
166
+ servers: Counter[str] = Counter()
167
+ tools: Counter[str] = Counter()
168
+ for entry in entries:
169
+ server = str(entry.get("server", ""))
170
+ tool = str(entry.get("tool", ""))
171
+ if not server:
172
+ continue
173
+ total += 1
174
+ servers[server] += 1
175
+ if tool:
176
+ tools[f"{server}/{tool}"] += 1
177
+ return McpUsageSummary(
178
+ period=period,
179
+ total_calls=total,
180
+ unique_servers=len(servers),
181
+ top_servers=servers.most_common(_TOP_SERVERS),
182
+ top_tools=tools.most_common(_TOP_TOOLS),
183
+ corrupt_line_count=corrupt,
184
+ )
@@ -0,0 +1,62 @@
1
+ """CLI entry for the MCP usage telemetry summarizer.
2
+
3
+ Invoked as ``python -m core.runtime.mcp_telemetry_cli <period>`` where
4
+ ``<period>`` is one of: today, week, month, all (default: today).
5
+
6
+ Output is plain markdown so it renders cleanly in both the terminal and
7
+ the ``/arka status`` skill which concatenates it into its report.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import sys
13
+
14
+ from core.runtime.mcp_telemetry import McpUsageSummary, summarise
15
+
16
+
17
+ def _sanitize_md(value: str) -> str:
18
+ """Strip markdown-breaking characters before rendering JSONL strings.
19
+
20
+ Telemetry is local-writer-only, but a malformed server/tool value
21
+ (newline, backtick) can still distort the markdown if /arka status
22
+ pipes the output to a UI.
23
+ """
24
+ return value.replace("\n", " ").replace("\r", " ").replace("`", "").strip()
25
+
26
+
27
+ def _render(summary: McpUsageSummary) -> str:
28
+ lines = [
29
+ f"# MCP usage — {summary.period}",
30
+ "",
31
+ f"- Calls: **{summary.total_calls}**",
32
+ f"- Servers in use: **{summary.unique_servers}**",
33
+ ]
34
+ if summary.top_servers:
35
+ lines += ["", "## Top servers"]
36
+ for server, count in summary.top_servers:
37
+ lines.append(f"- `{_sanitize_md(server)}` — {count}")
38
+ if summary.top_tools:
39
+ lines += ["", "## Top tools"]
40
+ for tool, count in summary.top_tools:
41
+ lines.append(f"- `{_sanitize_md(tool)}` — {count}")
42
+ if summary.corrupt_line_count:
43
+ lines += ["", f"_Skipped {summary.corrupt_line_count} corrupt line(s)._"]
44
+ if summary.total_calls == 0:
45
+ lines += ["", "_No MCP calls recorded for this period._"]
46
+ return "\n".join(lines)
47
+
48
+
49
+ def main(argv: list[str] | None = None) -> int:
50
+ args = argv if argv is not None else sys.argv[1:]
51
+ period = args[0] if args else "today"
52
+ try:
53
+ summary = summarise(period)
54
+ except ValueError as exc:
55
+ print(f"error: {exc}", file=sys.stderr)
56
+ return 2
57
+ print(_render(summary))
58
+ return 0
59
+
60
+
61
+ if __name__ == "__main__":
62
+ raise SystemExit(main())
@@ -181,7 +181,6 @@ def create_default_engine(
181
181
  BranchLayer,
182
182
  CommandHintsLayer,
183
183
  QualityGateLayer,
184
- TimeLayer,
185
184
  KnowledgeRetrievalLayer,
186
185
  KBContextLayer,
187
186
  ForgeContextLayer,
@@ -221,7 +220,10 @@ def create_default_engine(
221
220
  engine.register_layer(BranchLayer())
222
221
  engine.register_layer(CommandHintsLayer(commands=commands))
223
222
  engine.register_layer(QualityGateLayer())
224
- engine.register_layer(TimeLayer())
223
+ # L7 TimeLayer removed (prompt-surface P0 2026-07-08): the time-of-day tag
224
+ # had no consumer rule and invalidated the prompt cache at every
225
+ # 5h/12h/18h boundary — same rationale as the session-start hook's
226
+ # time-of-day removal.
225
227
  engine.register_layer(ForgeContextLayer())
226
228
  # L7.5 (PR4 v3.75.0) — Pattern Library injection. Surfaces prior
227
229
  # `PatternCard`s when the user prompt has matching keywords, so
@@ -496,55 +496,6 @@ class QualityGateLayer(Layer):
496
496
  )
497
497
 
498
498
 
499
- # --- L7: Time Signal ---
500
-
501
-
502
- class TimeLayer(Layer):
503
- """L7: Time-of-day signal for context-aware behavior."""
504
-
505
- @property
506
- def id(self) -> str:
507
- return "L7"
508
-
509
- @property
510
- def name(self) -> str:
511
- return "Time"
512
-
513
- @property
514
- def cache_ttl(self) -> int:
515
- # 1 hour — time-of-day period only changes at 5/12/18 boundaries.
516
- # Cache bucket drift of up to 1h is acceptable for a low-signal tag
517
- # and dramatically improves prompt-cache hit rate.
518
- return 3600
519
-
520
- @property
521
- def priority(self) -> int:
522
- return 70
523
-
524
- def compute(self, ctx: PromptContext) -> LayerResult:
525
- start = time.time()
526
- import datetime
527
-
528
- hour = datetime.datetime.now().hour
529
- if 5 <= hour < 12:
530
- period = "morning"
531
- elif 12 <= hour < 18:
532
- period = "afternoon"
533
- else:
534
- period = "evening"
535
-
536
- tag = f"[time:{period}]"
537
- ms = int((time.time() - start) * 1000)
538
- return LayerResult(
539
- layer_id=self.id,
540
- tag=tag,
541
- content=period,
542
- tokens_est=1,
543
- compute_ms=ms,
544
- cached=False,
545
- )
546
-
547
-
548
499
  # --- L3.5: Knowledge Retrieval ---
549
500
 
550
501
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "nuxt-ui-template-dashboard",
2
+ "name": "arkaos-dashboard",
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "scripts": {
@@ -8,17 +8,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
8
8
  ---
9
9
 
10
10
  <!-- arka:kb-first-prefix begin -->
11
- ## KB-First Research (non-negotiable)
12
-
13
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
14
-
15
- 1. Call `mcp__obsidian__search_notes` on the query first.
16
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
17
- 3. Only after (1) and (2) may external tools run.
18
-
19
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
20
- treat them as your default source. External research supplements, it
21
- does not replace the vault.
11
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
12
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
13
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
22
14
  <!-- arka:kb-first-prefix end -->
23
15
 
24
16
  # Brand & Design Department — ArkaOS v2
@@ -52,7 +44,7 @@ does not replace the vault.
52
44
  | **Isabel** | Visual Designer | 2 | I+S | Colors, logos, mockups, visual assets |
53
45
  | **Sofia D.** | UX/UI Designer | 2 | C+I | Wireframes, usability, accessibility |
54
46
 
55
- ## Brand Creation Method (NON-NEGOTIABLE: strategy before visuals)
47
+ ## Brand Creation Method (MUST: strategy before visuals)
56
48
 
57
49
  ```
58
50
  Level 1 — FOUNDATION (Mateus leads)
@@ -103,7 +95,7 @@ Level 4 — DELIVERY (Valentina leads)
103
95
  When dispatching subagent work via the Task tool, include the `model` parameter from the target agent's YAML `model:` field:
104
96
 
105
97
  - Agent YAMLs at `departments/*/agents/*.yaml` have `model: opus | sonnet | haiku`
106
- - Quality Gate dispatch (Marta/Eduardo/Francisca) ALWAYS uses `model: opus` — NON-NEGOTIABLE
98
+ - Quality Gate dispatch model: constitution `quality_gate.model_policy` (single source best-available via Model Fabric; veto is model-independent)
107
99
  - Default to `sonnet` if the agent YAML has no `model` field
108
100
  - Mechanical tasks (commit messages, routing, keyword extraction) use `model: haiku`
109
101
 
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Archetype Finder — `/brand archetype <brand>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Colors — `/brand colors <mood>`
@@ -1,9 +1,17 @@
1
1
  ---
2
2
  name: brand/design-review
3
3
  description: >
4
- Open a design tool (Figma, Sketch, Canva desktop) and compare live designs
5
- against brand guidelines. Screenshot and annotate differences.
6
- Requires Computer Use (/mcp computer-use).
4
+ Visual review of live designs against brand guidelines opens Figma,
5
+ Sketch, or Canva desktop via Computer Use, screenshots each artboard, and
6
+ annotates palette, typography, spacing, and logo deviations. Requires
7
+ Computer Use (/mcp -> computer-use). TRIGGER: "/brand design-review",
8
+ "design review", "visual review", "revê o design", "compara com o
9
+ brandbook", "está on-brand?", "visual QA", "UI review" of mockups or
10
+ screenshots, design file paths (*.fig, *.sketch, Canva links). SKIP:
11
+ reviewing the CODE behind a UI (components, CSS, diffs, PRs) ->
12
+ dev/code-review wins; SOLID/style sweep of frontend code ->
13
+ dev/clean-code-review wins; trying to break flows or find abuse vectors ->
14
+ dev/adversarial-review wins.
7
15
  allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent]
8
16
  ---
9
17
 
@@ -7,17 +7,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
7
7
  ---
8
8
 
9
9
  <!-- arka:kb-first-prefix begin -->
10
- ## KB-First Research (non-negotiable)
11
-
12
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
13
-
14
- 1. Call `mcp__obsidian__search_notes` on the query first.
15
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
16
- 3. Only after (1) and (2) may external tools run.
17
-
18
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
19
- treat them as your default source. External research supplements, it
20
- does not replace the vault.
10
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
11
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
12
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
21
13
  <!-- arka:kb-first-prefix end -->
22
14
 
23
15
  # Design System — `/brand design-system`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Identity System — `/brand identity <name>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Logo — `/brand logo <brief>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Mockup — `/brand mockup <type>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Brand Naming — `/brand naming <project>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Positioning Statement — `/brand positioning <name>`
@@ -7,17 +7,9 @@ allowed-tools: [Read, Write, Edit, Agent, WebFetch, WebSearch]
7
7
  ---
8
8
 
9
9
  <!-- arka:kb-first-prefix begin -->
10
- ## KB-First Research (non-negotiable)
11
-
12
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
13
-
14
- 1. Call `mcp__obsidian__search_notes` on the query first.
15
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
16
- 3. Only after (1) and (2) may external tools run.
17
-
18
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
19
- treat them as your default source. External research supplements, it
20
- does not replace the vault.
10
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
11
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
12
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
21
13
  <!-- arka:kb-first-prefix end -->
22
14
 
23
15
  # Primal Brand Audit — `/brand audit`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Ux Audit — `/brand ux-audit <url>`
@@ -6,17 +6,9 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
6
6
  ---
7
7
 
8
8
  <!-- arka:kb-first-prefix begin -->
9
- ## KB-First Research (non-negotiable)
10
-
11
- Before any external research (Context7, WebSearch, WebFetch, Firecrawl):
12
-
13
- 1. Call `mcp__obsidian__search_notes` on the query first.
14
- 2. Cite relevant hits with `[[wikilinks]]` or explicitly declare a KB gap.
15
- 3. Only after (1) and (2) may external tools run.
16
-
17
- The Synapse L2.5 layer pre-injects top KB matches on every user prompt;
18
- treat them as your default source. External research supplements, it
19
- does not replace the vault.
9
+ > **KB-first:** query `mcp__obsidian__search_notes` and cite
10
+ > `[[wikilinks]]` — or declare the gap — BEFORE any external research.
11
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
20
12
  <!-- arka:kb-first-prefix end -->
21
13
 
22
14
  # Voice Guide — `/brand voice <context>`