@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +12 -11
- package/CHANGELOG.md +134 -207
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/conformance.md +43 -0
- package/dist/agent-src/commands/roadmap/next.md +65 -3
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +10 -3
- package/dist/agent-src/rules/active-remediation.md +2 -0
- package/dist/agent-src/rules/analysis-skill-routing.md +2 -0
- package/dist/agent-src/rules/architecture.md +2 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +2 -0
- package/dist/agent-src/rules/artifact-engagement-recording.md +6 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +2 -0
- package/dist/agent-src/rules/autonomous-execution.md +3 -1
- package/dist/agent-src/rules/brand-consistency.md +2 -0
- package/dist/agent-src/rules/brand-source-of-truth.md +35 -6
- package/dist/agent-src/rules/broken-access-control.md +2 -0
- package/dist/agent-src/rules/cli-output-handling.md +2 -0
- package/dist/agent-src/rules/code-comment-discipline.md +2 -0
- package/dist/agent-src/rules/code-provenance.md +2 -0
- package/dist/agent-src/rules/command-suggestion-policy.md +2 -0
- package/dist/agent-src/rules/commit-conventions.md +2 -0
- package/dist/agent-src/rules/communication-through-line.md +2 -0
- package/dist/agent-src/rules/content-quoting-floor.md +2 -0
- package/dist/agent-src/rules/context-hygiene.md +13 -1
- package/dist/agent-src/rules/copilot-routing.md +2 -0
- package/dist/agent-src/rules/council-availability.md +93 -0
- package/dist/agent-src/rules/cross-source-consistency.md +5 -0
- package/dist/agent-src/rules/decision-revisit-gate.md +2 -0
- package/dist/agent-src/rules/delegation-policy.md +31 -5
- package/dist/agent-src/rules/design-fidelity.md +5 -0
- package/dist/agent-src/rules/design-review-after-ui-write.md +4 -0
- package/dist/agent-src/rules/devcontainer-routing.md +2 -0
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +2 -0
- package/dist/agent-src/rules/docker-commands.md +2 -0
- package/dist/agent-src/rules/domain-adoption-policy.md +2 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +2 -0
- package/dist/agent-src/rules/domain-safety-pii.md +2 -0
- package/dist/agent-src/rules/domain-safety-retention.md +2 -0
- package/dist/agent-src/rules/downstream-changes.md +2 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/evaluator-independence.md +14 -3
- package/dist/agent-src/rules/external-code-graph-interop.md +4 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +2 -0
- package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -0
- package/dist/agent-src/rules/finance-safety-floor.md +3 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +2 -0
- package/dist/agent-src/rules/git-history-discipline.md +3 -1
- package/dist/agent-src/rules/guidelines.md +2 -0
- package/dist/agent-src/rules/history-discipline.md +5 -1
- package/dist/agent-src/rules/icon-consistency.md +2 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +2 -0
- package/dist/agent-src/rules/improve-before-implement.md +2 -0
- package/dist/agent-src/rules/invite-challenge.md +2 -0
- package/dist/agent-src/rules/laravel-routing.md +2 -0
- package/dist/agent-src/rules/laravel-translations.md +2 -0
- package/dist/agent-src/rules/legal-safety-floor.md +3 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +2 -0
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +2 -0
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +2 -0
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -0
- package/dist/agent-src/rules/media-governance-routing.md +2 -0
- package/dist/agent-src/rules/media-sync-ground-truth.md +2 -0
- package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
- package/dist/agent-src/rules/missing-tool-handling.md +2 -0
- package/dist/agent-src/rules/model-recommendation.md +2 -0
- package/dist/agent-src/rules/no-attribution-footers.md +2 -0
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +2 -0
- package/dist/agent-src/rules/no-pr-progress-comments.md +5 -1
- package/dist/agent-src/rules/no-roadmap-references.md +2 -0
- package/dist/agent-src/rules/notes-first-reasoning.md +2 -0
- package/dist/agent-src/rules/onboarding-gate.md +5 -1
- package/dist/agent-src/rules/output-discipline.md +2 -0
- package/dist/agent-src/rules/package-ci-checks.md +2 -0
- package/dist/agent-src/rules/persona-governance.md +2 -0
- package/dist/agent-src/rules/php-coding.md +2 -0
- package/dist/agent-src/rules/prefer-enums-over-literals.md +2 -0
- package/dist/agent-src/rules/preservation-guard.md +2 -0
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -0
- package/dist/agent-src/rules/question-not-instruction.md +2 -0
- package/dist/agent-src/rules/reviewer-awareness.md +2 -0
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +6 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +2 -0
- package/dist/agent-src/rules/role-mode-adherence.md +3 -1
- package/dist/agent-src/rules/rule-type-governance.md +2 -0
- package/dist/agent-src/rules/runtime-safety.md +2 -0
- package/dist/agent-src/rules/scale-discipline.md +5 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/self-repair-loop.md +103 -0
- package/dist/agent-src/rules/senior-engineering-discipline.md +2 -0
- package/dist/agent-src/rules/session-canary.md +62 -19
- package/dist/agent-src/rules/settings-ask-protocol.md +4 -0
- package/dist/agent-src/rules/size-enforcement.md +2 -0
- package/dist/agent-src/rules/skill-improvement-trigger.md +2 -0
- package/dist/agent-src/rules/skill-quality.md +2 -0
- package/dist/agent-src/rules/slash-command-routing-policy.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +2 -0
- package/dist/agent-src/rules/source-discovery-gate.md +2 -0
- package/dist/agent-src/rules/source-of-truth.md +2 -0
- package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -0
- package/dist/agent-src/rules/strategy-safety-floor.md +3 -1
- package/dist/agent-src/rules/symfony-routing.md +2 -0
- package/dist/agent-src/rules/think-before-action.md +2 -0
- package/dist/agent-src/rules/token-budget-discipline.md +5 -1
- package/dist/agent-src/rules/token-efficiency.md +2 -0
- package/dist/agent-src/rules/token-optimizer-maintenance.md +2 -0
- package/dist/agent-src/rules/tool-safety.md +7 -1
- package/dist/agent-src/rules/ui-audit-gate.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +2 -0
- package/dist/agent-src/rules/upstream-proposal.md +2 -0
- package/dist/agent-src/rules/user-interaction.md +2 -0
- package/dist/agent-src/rules/user-interrupt-priority.md +2 -0
- package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/templates/AGENTS.md +6 -10
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +9 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-22GCIJ2O.js +270 -0
- package/dist/cli-delegate/{chunk-BSLUHV2F.js → chunk-2BE5I2MN.js} +156 -141
- package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-7OMQCH4V.js} +1 -1
- package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-GB2FSUEE.js} +57 -7
- package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-JXARCGVN.js} +3 -3
- package/dist/cli-delegate/{chunk-SJQMJI7M.js → chunk-PQSAQKHW.js} +467 -305
- package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +134 -0
- package/dist/cli-delegate/cmd_conformance.js +7 -7
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +4 -4
- package/dist/cli-delegate/cmd_explain.js +80 -330
- package/dist/cli-delegate/cmd_export.js +5 -5
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_mcp_available.js +433 -0
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +153 -0
- package/dist/cli-delegate/cmd_preflight.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +5 -5
- package/dist/cli-delegate/cmd_route_audit.js +8 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_settings_get.js +272 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +5 -5
- package/dist/cli-delegate/cmd_settings_set.js +7 -2967
- package/dist/cli-delegate/cmd_sync.js +5 -5
- package/dist/cli-delegate/cmd_uninstall.js +5 -5
- package/dist/cli-delegate/cmd_update.js +4 -4
- package/dist/cli-delegate/cmd_upgrade.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +5 -5
- package/dist/cli-delegate/cmd_versions.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +184 -124
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +11 -11
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +9080 -5701
- package/dist/install/install.mjs +698 -508
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +698 -437
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +80 -15
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/condense.js +33 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/io/yamlIO.js +85 -0
- package/dist/server/io/yamlIO.js.map +1 -1
- package/dist/server/routes/settings.js +1 -12
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/wizard.js +52 -2
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/shared/settingsCarveOut.js +118 -0
- package/dist/shared/settingsCarveOut.js.map +1 -0
- package/dist/shared/settingsSurface.js +7 -1
- package/dist/shared/settingsSurface.js.map +1 -1
- package/dist/ui/assets/index-DmR0mbk4.js.map +1 -1
- package/docs/contracts/settings-classes.md +29 -8
- package/docs/guidelines/agent-infra/memory-access.md +14 -3
- package/package.json +1 -1
- package/src/agent-src/templates/AGENTS.md +6 -10
- package/src/config/budgets.yml +29 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +26 -0
- package/src/scripts/_cli/cmd_brand_status.ts +174 -0
- package/src/scripts/_cli/cmd_doctor.ts +6 -21
- package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
- package/src/scripts/_cli/cmd_packs_active.ts +225 -0
- package/src/scripts/_cli/cmd_settings_get.ts +324 -0
- package/src/scripts/_dispatch.bash +75 -0
- package/src/scripts/_lib/agent_settings.ts +82 -16
- package/src/scripts/_lib/carrier_divergence.ts +135 -0
- package/src/scripts/_lib/git_common_dir.ts +128 -0
- package/src/scripts/_lib/host_capability.ts +84 -1
- package/src/scripts/_lib/obligation_frequency.ts +391 -0
- package/src/scripts/_lib/prompt_shape.ts +88 -0
- package/src/scripts/_lib/review_skipped_record.ts +102 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
- package/src/scripts/_lib/self_repair.ts +342 -0
- package/src/scripts/_lib/self_repair_store.ts +100 -0
- package/src/scripts/_lib/session_register.ts +361 -0
- package/src/scripts/_lib/transcript_entry.ts +80 -0
- package/src/scripts/check_branch_freshness.ts +255 -0
- package/src/scripts/check_council_config_location.ts +125 -1
- package/src/scripts/check_enforcement_coverage.ts +192 -7
- package/src/scripts/check_rule_projection_integrity.ts +364 -0
- package/src/scripts/check_standing_rule_delivery.ts +314 -0
- package/src/scripts/condense.ts +36 -2
- package/src/scripts/config/profiles.ts +13 -3
- package/src/scripts/conformance_scan.ts +307 -24
- package/src/scripts/council_availability_hook.ts +188 -0
- package/src/scripts/council_cli.ts +126 -7
- package/src/scripts/generate_settings_reference.ts +232 -0
- package/src/scripts/hook_manifest.yaml +155 -33
- package/src/scripts/hooks/block_no_verify.ts +95 -3
- package/src/scripts/hooks/block_unauthorized_git.ts +217 -2
- package/src/scripts/hooks/concern_registry.ts +12 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +450 -0
- package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
- package/src/scripts/install.ts +151 -0
- package/src/scripts/language_mirror_hook.ts +49 -6
- package/src/scripts/measure_scope_dedup.ts +19 -13
- package/src/scripts/onboarding_gate_hook.ts +40 -1
- package/src/scripts/orchestration_backfill.ts +354 -0
- package/src/scripts/orchestration_record.ts +4 -1
- package/src/scripts/preamble_byte_census.ts +9 -20
- package/src/scripts/release.ts +142 -36
- package/src/scripts/report_carrier_divergence.ts +364 -0
- package/src/scripts/report_skill_activation.ts +257 -0
- package/src/scripts/report_skill_obligation_violations.ts +579 -0
- package/src/scripts/routing_doctor.ts +77 -6
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/self_repair_cli.ts +240 -0
- package/src/scripts/self_repair_hook.ts +241 -0
- package/src/scripts/session_canary_hook.ts +35 -3
- package/src/scripts/session_register_hook.ts +288 -0
- package/src/scripts/sessions_cli.ts +140 -0
- package/src/scripts/validate_frontmatter.ts +68 -0
- package/src/server/io/yamlIO.ts +87 -0
- package/src/shared/settingsCarveOut.ts +143 -0
- 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 };
|