@event4u/agent-config 9.26.0 → 9.28.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 (252) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/AGENTS.md +12 -11
  3. package/CHANGELOG.md +134 -207
  4. package/README.md +1 -1
  5. package/dist/agent-src/commands/analyze/conformance.md +43 -0
  6. package/dist/agent-src/commands/roadmap/next.md +65 -3
  7. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +10 -3
  8. package/dist/agent-src/rules/active-remediation.md +2 -0
  9. package/dist/agent-src/rules/analysis-skill-routing.md +2 -0
  10. package/dist/agent-src/rules/architecture.md +2 -0
  11. package/dist/agent-src/rules/artifact-drafting-protocol.md +2 -0
  12. package/dist/agent-src/rules/artifact-engagement-recording.md +6 -1
  13. package/dist/agent-src/rules/augment-edit-discipline.md +2 -0
  14. package/dist/agent-src/rules/autonomous-execution.md +3 -1
  15. package/dist/agent-src/rules/brand-consistency.md +2 -0
  16. package/dist/agent-src/rules/brand-source-of-truth.md +35 -6
  17. package/dist/agent-src/rules/broken-access-control.md +2 -0
  18. package/dist/agent-src/rules/cli-output-handling.md +2 -0
  19. package/dist/agent-src/rules/code-comment-discipline.md +2 -0
  20. package/dist/agent-src/rules/code-provenance.md +2 -0
  21. package/dist/agent-src/rules/command-suggestion-policy.md +2 -0
  22. package/dist/agent-src/rules/commit-conventions.md +2 -0
  23. package/dist/agent-src/rules/communication-through-line.md +2 -0
  24. package/dist/agent-src/rules/content-quoting-floor.md +2 -0
  25. package/dist/agent-src/rules/context-hygiene.md +13 -1
  26. package/dist/agent-src/rules/copilot-routing.md +2 -0
  27. package/dist/agent-src/rules/council-availability.md +93 -0
  28. package/dist/agent-src/rules/cross-source-consistency.md +5 -0
  29. package/dist/agent-src/rules/decision-revisit-gate.md +2 -0
  30. package/dist/agent-src/rules/delegation-policy.md +31 -5
  31. package/dist/agent-src/rules/design-fidelity.md +5 -0
  32. package/dist/agent-src/rules/design-review-after-ui-write.md +4 -0
  33. package/dist/agent-src/rules/devcontainer-routing.md +2 -0
  34. package/dist/agent-src/rules/doc-screenshot-hygiene.md +2 -0
  35. package/dist/agent-src/rules/docker-commands.md +2 -0
  36. package/dist/agent-src/rules/domain-adoption-policy.md +2 -0
  37. package/dist/agent-src/rules/domain-safety-disclaimer.md +2 -0
  38. package/dist/agent-src/rules/domain-safety-pii.md +2 -0
  39. package/dist/agent-src/rules/domain-safety-retention.md +2 -0
  40. package/dist/agent-src/rules/downstream-changes.md +2 -0
  41. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  42. package/dist/agent-src/rules/evaluator-independence.md +14 -3
  43. package/dist/agent-src/rules/external-code-graph-interop.md +4 -1
  44. package/dist/agent-src/rules/external-reference-deep-dive.md +2 -0
  45. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -0
  46. package/dist/agent-src/rules/finance-safety-floor.md +3 -1
  47. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +2 -0
  48. package/dist/agent-src/rules/git-history-discipline.md +3 -1
  49. package/dist/agent-src/rules/guidelines.md +2 -0
  50. package/dist/agent-src/rules/history-discipline.md +5 -1
  51. package/dist/agent-src/rules/icon-consistency.md +2 -0
  52. package/dist/agent-src/rules/image-likeness-and-rights.md +2 -0
  53. package/dist/agent-src/rules/improve-before-implement.md +2 -0
  54. package/dist/agent-src/rules/invite-challenge.md +2 -0
  55. package/dist/agent-src/rules/laravel-routing.md +2 -0
  56. package/dist/agent-src/rules/laravel-translations.md +2 -0
  57. package/dist/agent-src/rules/legal-safety-floor.md +3 -1
  58. package/dist/agent-src/rules/lethal-trifecta-guard.md +2 -0
  59. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +2 -0
  60. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +2 -0
  61. package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -0
  62. package/dist/agent-src/rules/media-governance-routing.md +2 -0
  63. package/dist/agent-src/rules/media-sync-ground-truth.md +2 -0
  64. package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
  65. package/dist/agent-src/rules/missing-tool-handling.md +2 -0
  66. package/dist/agent-src/rules/model-recommendation.md +2 -0
  67. package/dist/agent-src/rules/no-attribution-footers.md +2 -0
  68. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +2 -0
  69. package/dist/agent-src/rules/no-pr-progress-comments.md +5 -1
  70. package/dist/agent-src/rules/no-roadmap-references.md +2 -0
  71. package/dist/agent-src/rules/notes-first-reasoning.md +2 -0
  72. package/dist/agent-src/rules/onboarding-gate.md +5 -1
  73. package/dist/agent-src/rules/output-discipline.md +2 -0
  74. package/dist/agent-src/rules/package-ci-checks.md +2 -0
  75. package/dist/agent-src/rules/persona-governance.md +2 -0
  76. package/dist/agent-src/rules/php-coding.md +2 -0
  77. package/dist/agent-src/rules/prefer-enums-over-literals.md +2 -0
  78. package/dist/agent-src/rules/preservation-guard.md +2 -0
  79. package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -0
  80. package/dist/agent-src/rules/question-not-instruction.md +2 -0
  81. package/dist/agent-src/rules/reviewer-awareness.md +2 -0
  82. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +6 -1
  83. package/dist/agent-src/rules/roadmap-progress-sync.md +2 -0
  84. package/dist/agent-src/rules/role-mode-adherence.md +3 -1
  85. package/dist/agent-src/rules/rule-type-governance.md +2 -0
  86. package/dist/agent-src/rules/runtime-safety.md +2 -0
  87. package/dist/agent-src/rules/scale-discipline.md +5 -1
  88. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  89. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  90. package/dist/agent-src/rules/self-repair-loop.md +103 -0
  91. package/dist/agent-src/rules/senior-engineering-discipline.md +2 -0
  92. package/dist/agent-src/rules/session-canary.md +62 -19
  93. package/dist/agent-src/rules/settings-ask-protocol.md +4 -0
  94. package/dist/agent-src/rules/size-enforcement.md +2 -0
  95. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -0
  96. package/dist/agent-src/rules/skill-quality.md +2 -0
  97. package/dist/agent-src/rules/slash-command-routing-policy.md +2 -0
  98. package/dist/agent-src/rules/source-confidentiality.md +2 -0
  99. package/dist/agent-src/rules/source-discovery-gate.md +2 -0
  100. package/dist/agent-src/rules/source-of-truth.md +2 -0
  101. package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -0
  102. package/dist/agent-src/rules/strategy-safety-floor.md +3 -1
  103. package/dist/agent-src/rules/symfony-routing.md +2 -0
  104. package/dist/agent-src/rules/think-before-action.md +2 -0
  105. package/dist/agent-src/rules/token-budget-discipline.md +5 -1
  106. package/dist/agent-src/rules/token-efficiency.md +2 -0
  107. package/dist/agent-src/rules/token-optimizer-maintenance.md +2 -0
  108. package/dist/agent-src/rules/tool-safety.md +7 -1
  109. package/dist/agent-src/rules/ui-audit-gate.md +4 -0
  110. package/dist/agent-src/rules/untrusted-input-defense.md +2 -0
  111. package/dist/agent-src/rules/upstream-proposal.md +2 -0
  112. package/dist/agent-src/rules/user-interaction.md +2 -0
  113. package/dist/agent-src/rules/user-interrupt-priority.md +2 -0
  114. package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
  115. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  116. package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
  117. package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
  118. package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
  119. package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
  120. package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
  121. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  122. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  123. package/dist/agent-src/templates/AGENTS.md +6 -10
  124. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  125. package/dist/cli/registry.js +9 -0
  126. package/dist/cli/registry.js.map +1 -1
  127. package/dist/cli-delegate/chunk-22GCIJ2O.js +270 -0
  128. package/dist/cli-delegate/{chunk-BSLUHV2F.js → chunk-2BE5I2MN.js} +156 -141
  129. package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-7OMQCH4V.js} +1 -1
  130. package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-GB2FSUEE.js} +57 -7
  131. package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-JXARCGVN.js} +3 -3
  132. package/dist/cli-delegate/{chunk-SJQMJI7M.js → chunk-PQSAQKHW.js} +467 -305
  133. package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
  134. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  135. package/dist/cli-delegate/cmd_brand_status.js +134 -0
  136. package/dist/cli-delegate/cmd_conformance.js +7 -7
  137. package/dist/cli-delegate/cmd_converge.js +3 -3
  138. package/dist/cli-delegate/cmd_doctor.js +4 -4
  139. package/dist/cli-delegate/cmd_explain.js +80 -330
  140. package/dist/cli-delegate/cmd_export.js +5 -5
  141. package/dist/cli-delegate/cmd_fleet.js +3 -3
  142. package/dist/cli-delegate/cmd_handoff.js +2 -2
  143. package/dist/cli-delegate/cmd_mcp_available.js +433 -0
  144. package/dist/cli-delegate/cmd_migrate.js +3 -3
  145. package/dist/cli-delegate/cmd_packs_active.js +153 -0
  146. package/dist/cli-delegate/cmd_preflight.js +1 -1
  147. package/dist/cli-delegate/cmd_prune.js +5 -5
  148. package/dist/cli-delegate/cmd_route_audit.js +8 -8
  149. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  150. package/dist/cli-delegate/cmd_settings_get.js +272 -0
  151. package/dist/cli-delegate/cmd_settings_migrate.js +5 -5
  152. package/dist/cli-delegate/cmd_settings_set.js +7 -2967
  153. package/dist/cli-delegate/cmd_sync.js +5 -5
  154. package/dist/cli-delegate/cmd_uninstall.js +5 -5
  155. package/dist/cli-delegate/cmd_update.js +4 -4
  156. package/dist/cli-delegate/cmd_upgrade.js +4 -4
  157. package/dist/cli-delegate/cmd_validate.js +5 -5
  158. package/dist/cli-delegate/cmd_versions.js +4 -4
  159. package/dist/discovery/deprecation-report.md +1 -1
  160. package/dist/discovery/discovery-manifest.json +184 -124
  161. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  162. package/dist/discovery/discovery-manifest.summary.md +3 -3
  163. package/dist/discovery/orphan-report.md +1 -1
  164. package/dist/discovery/packs.json +7 -5
  165. package/dist/discovery/trust-report.md +11 -11
  166. package/dist/discovery/workspaces.json +6 -4
  167. package/dist/hooks/dispatch.js +9080 -5701
  168. package/dist/install/install.mjs +698 -508
  169. package/dist/mcp/registry-manifest.json +3 -3
  170. package/dist/mcp/server.json +2 -2
  171. package/dist/mcp/server.mjs +698 -437
  172. package/dist/router.json +1 -1
  173. package/dist/scripts/_lib/agent_settings.js +80 -15
  174. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  175. package/dist/scripts/condense.js +33 -2
  176. package/dist/scripts/condense.js.map +1 -1
  177. package/dist/server/io/yamlIO.js +85 -0
  178. package/dist/server/io/yamlIO.js.map +1 -1
  179. package/dist/server/routes/settings.js +1 -12
  180. package/dist/server/routes/settings.js.map +1 -1
  181. package/dist/server/routes/wizard.js +52 -2
  182. package/dist/server/routes/wizard.js.map +1 -1
  183. package/dist/shared/settingsCarveOut.js +118 -0
  184. package/dist/shared/settingsCarveOut.js.map +1 -0
  185. package/dist/shared/settingsSurface.js +7 -1
  186. package/dist/shared/settingsSurface.js.map +1 -1
  187. package/dist/ui/assets/index-DmR0mbk4.js.map +1 -1
  188. package/docs/contracts/settings-classes.md +29 -8
  189. package/docs/guidelines/agent-infra/memory-access.md +14 -3
  190. package/package.json +1 -1
  191. package/src/agent-src/templates/AGENTS.md +6 -10
  192. package/src/config/budgets.yml +29 -0
  193. package/src/config/evaluator-budgets.json +4 -4
  194. package/src/config/gate-coverage.yml +26 -0
  195. package/src/scripts/_cli/cmd_brand_status.ts +174 -0
  196. package/src/scripts/_cli/cmd_doctor.ts +6 -21
  197. package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
  198. package/src/scripts/_cli/cmd_packs_active.ts +225 -0
  199. package/src/scripts/_cli/cmd_settings_get.ts +324 -0
  200. package/src/scripts/_dispatch.bash +75 -0
  201. package/src/scripts/_lib/agent_settings.ts +82 -16
  202. package/src/scripts/_lib/carrier_divergence.ts +135 -0
  203. package/src/scripts/_lib/git_common_dir.ts +128 -0
  204. package/src/scripts/_lib/host_capability.ts +84 -1
  205. package/src/scripts/_lib/obligation_frequency.ts +391 -0
  206. package/src/scripts/_lib/prompt_shape.ts +88 -0
  207. package/src/scripts/_lib/review_skipped_record.ts +102 -0
  208. package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
  209. package/src/scripts/_lib/self_repair.ts +342 -0
  210. package/src/scripts/_lib/self_repair_store.ts +100 -0
  211. package/src/scripts/_lib/session_register.ts +361 -0
  212. package/src/scripts/_lib/transcript_entry.ts +80 -0
  213. package/src/scripts/check_branch_freshness.ts +255 -0
  214. package/src/scripts/check_council_config_location.ts +125 -1
  215. package/src/scripts/check_enforcement_coverage.ts +192 -7
  216. package/src/scripts/check_rule_projection_integrity.ts +364 -0
  217. package/src/scripts/check_standing_rule_delivery.ts +314 -0
  218. package/src/scripts/condense.ts +36 -2
  219. package/src/scripts/config/profiles.ts +13 -3
  220. package/src/scripts/conformance_scan.ts +307 -24
  221. package/src/scripts/council_availability_hook.ts +188 -0
  222. package/src/scripts/council_cli.ts +126 -7
  223. package/src/scripts/generate_settings_reference.ts +232 -0
  224. package/src/scripts/hook_manifest.yaml +155 -33
  225. package/src/scripts/hooks/block_no_verify.ts +95 -3
  226. package/src/scripts/hooks/block_unauthorized_git.ts +217 -2
  227. package/src/scripts/hooks/concern_registry.ts +12 -0
  228. package/src/scripts/hooks/delegation_nudge_hook.ts +450 -0
  229. package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
  230. package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
  231. package/src/scripts/install.ts +151 -0
  232. package/src/scripts/language_mirror_hook.ts +49 -6
  233. package/src/scripts/measure_scope_dedup.ts +19 -13
  234. package/src/scripts/onboarding_gate_hook.ts +40 -1
  235. package/src/scripts/orchestration_backfill.ts +354 -0
  236. package/src/scripts/orchestration_record.ts +4 -1
  237. package/src/scripts/preamble_byte_census.ts +9 -20
  238. package/src/scripts/release.ts +142 -36
  239. package/src/scripts/report_carrier_divergence.ts +364 -0
  240. package/src/scripts/report_skill_activation.ts +257 -0
  241. package/src/scripts/report_skill_obligation_violations.ts +579 -0
  242. package/src/scripts/routing_doctor.ts +77 -6
  243. package/src/scripts/schemas/rule.schema.json +5 -0
  244. package/src/scripts/self_repair_cli.ts +240 -0
  245. package/src/scripts/self_repair_hook.ts +241 -0
  246. package/src/scripts/session_canary_hook.ts +35 -3
  247. package/src/scripts/session_register_hook.ts +288 -0
  248. package/src/scripts/sessions_cli.ts +140 -0
  249. package/src/scripts/validate_frontmatter.ts +68 -0
  250. package/src/server/io/yamlIO.ts +87 -0
  251. package/src/shared/settingsCarveOut.ts +143 -0
  252. package/src/shared/settingsSurface.ts +7 -1
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * report_skill_activation.ts — the census that answers "are the skills used?"
4
+ * by showing why the question cannot currently be answered as a rate.
5
+ *
6
+ * Executes round-6 Phase 3.1. Advisory: **it gates on nothing**, has no
7
+ * threshold, and must not acquire one — for the same reason
8
+ * `report_imperative_density` must not, plus one specific to this surface.
9
+ *
10
+ * WHY THIS IS NOT PART OF `conformance_scan`
11
+ * ------------------------------------------
12
+ * The conformance scan carries a binding constraint adopted verbatim from the
13
+ * round-1 council: it may measure ONLY classes that have a mechanism, because
14
+ * "a conformance scan that checks un-mechanised rules is theatre". Skill
15
+ * activation has no mechanism at all — there is no runtime router, and nothing
16
+ * observes whether a skill that should have fired did. Putting these numbers in
17
+ * the scan would read as enforcement. They belong in a census that says what it
18
+ * is.
19
+ *
20
+ * WHAT THE ROUND-6 PASS MEASURED, AND WHY THE SHAPE INVERTED
21
+ * ----------------------------------------------------------
22
+ * Usage, across 59 sessions and 33,618 assistant turns in three stores: **31
23
+ * Skill invocations, 6 distinct skills of 288 shipped (2.1%)**. Five of the six
24
+ * are slash-commands the human typed; one looks agent-initiated.
25
+ *
26
+ * The first draft of the round-6 phase planned a missed-activation detector
27
+ * keyed on "a skill's own frontmatter triggers". There are none: 0 of 288 skills
28
+ * carry a `triggers:` key. Matching the `description:` prose instead is the
29
+ * FC-8-shaped prose-matching the same phase forbids. So a rate is not available
30
+ * and the census is the finding — which is why this file prints counts and an
31
+ * explicit unmeasurable verdict rather than a percentage that would look like an
32
+ * answer.
33
+ *
34
+ * THE GAP THIS SCRIPT CANNOT CLOSE, STATED SO NOBODY READS IT AS COVERED
35
+ * ---------------------------------------------------------------------
36
+ * The strongest candidate cause is a delivery defect: in an observed session the
37
+ * host's injected skill catalogue carried descriptions for roughly the first
38
+ * forty entries and BARE NAMES thereafter, and a bare `- flux` carries no
39
+ * activation signal at all. That is a single-session observation, not a
40
+ * measurement, because the injected catalogue is **not persisted in the
41
+ * transcript** — grep for it across the store and it is absent. So this script
42
+ * prints the hypothesis and its falsifier instead of a number: capture the
43
+ * catalogue deliberately (a `session_start` concern logging the block once), then
44
+ * count descriptions against bare names. Until that runs, "most skills reach the
45
+ * model without a description" is a suspicion.
46
+ *
47
+ * Exit: 0 always, except a usage/IO error (1). Deliberate.
48
+ */
49
+
50
+ import * as fs from 'node:fs';
51
+ import * as os from 'node:os';
52
+ import * as path from 'node:path';
53
+ import { fileURLToPath, pathToFileURL } from 'node:url';
54
+
55
+ const _HERE = fileURLToPath(import.meta.url);
56
+ const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
57
+
58
+ export const SKILLS_ROOT = 'src/skills';
59
+
60
+ /** A trigger key the host could match on without reading prose. */
61
+ const TRIGGER_KEYS = ['triggers:', 'trigger_description:', 'file_pattern:', 'path_prefix:'];
62
+
63
+ /**
64
+ * A deterministic obligation is one whose violation is observable without
65
+ * judgement — the line-start absolutes. Prose that merely urges ("prefer",
66
+ * "consider") is excluded on purpose: it is the FC-8 class, and counting it here
67
+ * would inflate the only number in this census that bounds what SK-2 can cover.
68
+ */
69
+ export const DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
70
+
71
+ export interface SkillCensus {
72
+ total: number;
73
+ withTriggerKey: string[];
74
+ withDeterministicObligation: string[];
75
+ }
76
+
77
+ export function censusSkills(root: string): SkillCensus {
78
+ const out: SkillCensus = { total: 0, withTriggerKey: [], withDeterministicObligation: [] };
79
+ if (!fs.existsSync(root)) {
80
+ return out;
81
+ }
82
+ for (const entry of fs.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
83
+ if (!entry.isDirectory()) {
84
+ continue;
85
+ }
86
+ const file = path.join(root, entry.name, 'SKILL.md');
87
+ if (!fs.existsSync(file)) {
88
+ continue;
89
+ }
90
+ out.total += 1;
91
+ const text = fs.readFileSync(file, 'utf8');
92
+ // Frontmatter is everything between the first two `---` fences; a trigger
93
+ // key anywhere else is prose about triggers, not a matchable declaration.
94
+ const fmEnd = text.startsWith('---') ? text.indexOf('\n---', 3) : -1;
95
+ const fm = fmEnd === -1 ? '' : text.slice(0, fmEnd);
96
+ if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, 'm').test(fm))) {
97
+ out.withTriggerKey.push(entry.name);
98
+ }
99
+ const body = fmEnd === -1 ? text : text.slice(fmEnd + 4);
100
+ if (DETERMINISTIC_RE.test(body)) {
101
+ out.withDeterministicObligation.push(entry.name);
102
+ }
103
+ }
104
+ return out;
105
+ }
106
+
107
+ export interface UsageReport {
108
+ store: string;
109
+ sessions: number;
110
+ assistantTurns: number;
111
+ invocations: number;
112
+ bySkill: Record<string, number>;
113
+ }
114
+
115
+ /** Default store for the current working directory, mangled the way the host does. */
116
+ export function defaultStore(cwd: string): string {
117
+ return path.join(os.homedir(), '.claude', 'projects', cwd.replace(/\//g, '-'));
118
+ }
119
+
120
+ export function measureUsage(store: string, limit: number): UsageReport {
121
+ const rep: UsageReport = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
122
+ if (!fs.existsSync(store)) {
123
+ return rep;
124
+ }
125
+ const files = fs
126
+ .readdirSync(store)
127
+ .filter((f) => f.endsWith('.jsonl'))
128
+ .map((f) => path.join(store, f))
129
+ .sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs)
130
+ .slice(0, limit);
131
+ rep.sessions = files.length;
132
+ for (const file of files) {
133
+ for (const line of fs.readFileSync(file, 'utf8').split('\n')) {
134
+ if (!line.trim()) {
135
+ continue;
136
+ }
137
+ let entry: Record<string, unknown>;
138
+ try {
139
+ entry = JSON.parse(line) as Record<string, unknown>;
140
+ } catch {
141
+ continue;
142
+ }
143
+ if (entry['type'] !== 'assistant') {
144
+ continue;
145
+ }
146
+ rep.assistantTurns += 1;
147
+ const msg = entry['message'];
148
+ const content = msg !== null && typeof msg === 'object' ? (msg as Record<string, unknown>)['content'] : null;
149
+ if (!Array.isArray(content)) {
150
+ continue;
151
+ }
152
+ for (const part of content) {
153
+ if (part === null || typeof part !== 'object') {
154
+ continue;
155
+ }
156
+ const p = part as Record<string, unknown>;
157
+ if (p['type'] !== 'tool_use' || p['name'] !== 'Skill') {
158
+ continue;
159
+ }
160
+ rep.invocations += 1;
161
+ const input = p['input'];
162
+ const name = input !== null && typeof input === 'object' ? (input as Record<string, unknown>)['skill'] : null;
163
+ const key = typeof name === 'string' && name !== '' ? name : '<unnamed>';
164
+ rep.bySkill[key] = (rep.bySkill[key] ?? 0) + 1;
165
+ }
166
+ }
167
+ }
168
+ return rep;
169
+ }
170
+
171
+ function _pct(n: number, d: number): string {
172
+ return d === 0 ? 'n/a' : `${((100 * n) / d).toFixed(1)}%`;
173
+ }
174
+
175
+ export function render(census: SkillCensus, usage: UsageReport[]): string {
176
+ const lines: string[] = [];
177
+ lines.push('skill activation census — advisory, gates on nothing');
178
+ lines.push('');
179
+ lines.push(` skills shipped ${census.total}`);
180
+ lines.push(
181
+ ` with a machine-matchable trigger key ${census.withTriggerKey.length} (${_pct(census.withTriggerKey.length, census.total)})`,
182
+ );
183
+ lines.push(
184
+ ` with a deterministic obligation ${census.withDeterministicObligation.length} (${_pct(census.withDeterministicObligation.length, census.total)})`,
185
+ );
186
+ if (census.withDeterministicObligation.length > 0) {
187
+ lines.push(` ${census.withDeterministicObligation.join(', ')}`);
188
+ }
189
+ lines.push('');
190
+ let totalInv = 0;
191
+ const distinct = new Set<string>();
192
+ for (const u of usage) {
193
+ for (const k of Object.keys(u.bySkill)) {
194
+ distinct.add(k);
195
+ }
196
+ totalInv += u.invocations;
197
+ lines.push(
198
+ ` ${path.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`,
199
+ );
200
+ }
201
+ lines.push('');
202
+ lines.push(` invocations total ${totalInv}`);
203
+ lines.push(
204
+ ` distinct skills invoked ${distinct.size} of ${census.total} (${_pct(distinct.size, census.total)})`,
205
+ );
206
+ if (distinct.size > 0) {
207
+ lines.push(` ${[...distinct].sort().join(', ')}`);
208
+ }
209
+ lines.push('');
210
+ if (census.withTriggerKey.length === 0) {
211
+ lines.push(' VERDICT: activation is not measurable as a rate. No skill declares a');
212
+ lines.push(' machine-matchable trigger, so a missed-activation detector has nothing to');
213
+ lines.push(' match against, and matching the description prose is the class this suite');
214
+ lines.push(' excludes. The counts above are the finding, not an input to a percentage.');
215
+ }
216
+ lines.push('');
217
+ lines.push(' NOT MEASURED: whether each skill reached the model WITH its description.');
218
+ lines.push(' The host\'s injected catalogue is not persisted in the transcript, so the');
219
+ lines.push(' bare-name hypothesis is a single-session observation. Falsifier: log the');
220
+ lines.push(' catalogue once per session, then count descriptions against bare names.');
221
+ return lines.join('\n');
222
+ }
223
+
224
+ function main(argv: string[]): number {
225
+ let limit = 30;
226
+ const stores: string[] = [];
227
+ for (let i = 0; i < argv.length; i += 1) {
228
+ const a = argv[i];
229
+ if (a === '--limit' && argv[i + 1] !== undefined) {
230
+ limit = Number.parseInt(argv[i + 1] as string, 10);
231
+ i += 1;
232
+ } else if (a === '--store' && argv[i + 1] !== undefined) {
233
+ stores.push(argv[i + 1] as string);
234
+ i += 1;
235
+ } else if (a === '--help' || a === '-h') {
236
+ process.stdout.write('usage: report_skill_activation [--limit N] [--store PATH]...\n');
237
+ return 0;
238
+ }
239
+ }
240
+ if (!Number.isFinite(limit) || limit <= 0) {
241
+ process.stderr.write('report_skill_activation: --limit must be a positive integer\n');
242
+ return 1;
243
+ }
244
+ if (stores.length === 0) {
245
+ stores.push(defaultStore(REPO_ROOT));
246
+ }
247
+ const census = censusSkills(path.join(REPO_ROOT, SKILLS_ROOT));
248
+ const usage = stores.map((s) => measureUsage(s, limit));
249
+ process.stdout.write(`${render(census, usage)}\n`);
250
+ return 0;
251
+ }
252
+
253
+ if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
254
+ process.exit(main(process.argv.slice(2)));
255
+ }
256
+
257
+ export { main };