@event4u/agent-config 9.14.0 → 9.16.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 (287) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +118 -99
  3. package/README.md +8 -0
  4. package/dist/agent-src/commands/agents/audit.md +7 -7
  5. package/dist/agent-src/commands/agents/optimize.md +1 -1
  6. package/dist/agent-src/commands/analyze/reference-repo.md +1 -1
  7. package/dist/agent-src/commands/chat-history.md +1 -0
  8. package/dist/agent-src/commands/context.md +1 -0
  9. package/dist/agent-src/commands/council.md +1 -1
  10. package/dist/agent-src/commands/ghostwriter.md +1 -1
  11. package/dist/agent-src/commands/memory.md +2 -1
  12. package/dist/agent-src/commands/module.md +1 -0
  13. package/dist/agent-src/commands/optimize/agents-dir.md +1 -1
  14. package/dist/agent-src/commands/optimize/deep.md +5 -2
  15. package/dist/agent-src/commands/optimize/skills.md +5 -5
  16. package/dist/agent-src/commands/override.md +1 -0
  17. package/dist/agent-src/commands/prediction-pool.md +4 -4
  18. package/dist/agent-src/commands/research/deep.md +1 -1
  19. package/dist/agent-src/commands/roadmap.md +2 -1
  20. package/dist/agent-src/commands/rule-compliance-audit.md +1 -1
  21. package/dist/agent-src/commands/tdd.md +1 -0
  22. package/dist/agent-src/commands/tests.md +1 -0
  23. package/dist/agent-src/commands/upstream-contribute.md +5 -5
  24. package/dist/agent-src/commands/video/from-script.md +1 -1
  25. package/dist/agent-src/commands/video/from-song.md +1 -1
  26. package/dist/agent-src/commands/video/scene.md +1 -1
  27. package/dist/agent-src/commands/video/stitch.md +1 -1
  28. package/dist/agent-src/commands/video/storyboard.md +1 -1
  29. package/dist/agent-src/commands/worktree/create.md +2 -1
  30. package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
  31. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +5 -5
  32. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -3
  33. package/dist/agent-src/contexts/contracts/emergency-triage-block.md +2 -2
  34. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +4 -3
  35. package/dist/agent-src/contexts/execution/subagent-routing.md +19 -0
  36. package/dist/agent-src/contexts/override-system.md +1 -1
  37. package/dist/agent-src/ghostwriter/fictional-fixture-v1.md +1 -1
  38. package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
  39. package/dist/agent-src/rules/autonomous-execution.md +2 -1
  40. package/dist/agent-src/rules/brand-consistency.md +1 -0
  41. package/dist/agent-src/rules/brand-source-of-truth.md +1 -0
  42. package/dist/agent-src/rules/code-comment-discipline.md +2 -0
  43. package/dist/agent-src/rules/communication-through-line.md +1 -0
  44. package/dist/agent-src/rules/content-quoting-floor.md +1 -0
  45. package/dist/agent-src/rules/cross-source-consistency.md +0 -1
  46. package/dist/agent-src/rules/downstream-changes.md +1 -0
  47. package/dist/agent-src/rules/external-code-graph-interop.md +1 -0
  48. package/dist/agent-src/rules/external-reference-deep-dive.md +1 -0
  49. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  50. package/dist/agent-src/rules/finance-safety-floor.md +0 -1
  51. package/dist/agent-src/rules/icon-consistency.md +1 -0
  52. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  53. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  54. package/dist/agent-src/rules/invite-challenge.md +1 -0
  55. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  56. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  57. package/dist/agent-src/rules/markdown-safe-codeblocks.md +1 -0
  58. package/dist/agent-src/rules/media-governance-routing.md +4 -3
  59. package/dist/agent-src/rules/media-sync-ground-truth.md +1 -0
  60. package/dist/agent-src/rules/no-attribution-footers.md +1 -0
  61. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +1 -0
  62. package/dist/agent-src/rules/no-pr-progress-comments.md +1 -0
  63. package/dist/agent-src/rules/onboarding-gate.md +1 -0
  64. package/dist/agent-src/rules/output-discipline.md +1 -0
  65. package/dist/agent-src/rules/prefer-enums-over-literals.md +1 -0
  66. package/dist/agent-src/rules/preservation-guard.md +1 -0
  67. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  68. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +1 -0
  69. package/dist/agent-src/rules/role-mode-adherence.md +1 -0
  70. package/dist/agent-src/rules/runtime-safety.md +1 -0
  71. package/dist/agent-src/rules/security-sensitive-stop.md +1 -0
  72. package/dist/agent-src/rules/session-canary.md +9 -2
  73. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  74. package/dist/agent-src/rules/source-of-truth.md +1 -0
  75. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -0
  76. package/dist/agent-src/rules/think-before-action.md +1 -0
  77. package/dist/agent-src/rules/token-budget-discipline.md +1 -0
  78. package/dist/agent-src/rules/token-efficiency.md +1 -0
  79. package/dist/agent-src/rules/token-optimizer-maintenance.md +5 -5
  80. package/dist/agent-src/rules/tool-safety.md +1 -0
  81. package/dist/agent-src/rules/untrusted-input-defense.md +2 -0
  82. package/dist/agent-src/rules/user-interaction.md +1 -0
  83. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  84. package/dist/agent-src/skills/adr-create/SKILL.md +1 -1
  85. package/dist/agent-src/skills/check-refs/SKILL.md +1 -1
  86. package/dist/agent-src/skills/competitive-positioning/SKILL.md +1 -1
  87. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  88. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  89. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +1 -1
  90. package/dist/agent-src/skills/description-assist/SKILL.md +1 -1
  91. package/dist/agent-src/skills/github-ci/SKILL.md +1 -0
  92. package/dist/agent-src/skills/guideline-writing/SKILL.md +1 -1
  93. package/dist/agent-src/skills/lint-skills/SKILL.md +1 -1
  94. package/dist/agent-src/skills/readme-reviewer/SKILL.md +1 -1
  95. package/dist/agent-src/skills/roadmap-management/SKILL.md +8 -1
  96. package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
  97. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  98. package/dist/agent-src/skills/skill-writing/SKILL.md +4 -4
  99. package/dist/agent-src/skills/token-optimizer/SKILL.md +4 -4
  100. package/dist/agent-src/skills/upstream-contribute/SKILL.md +6 -6
  101. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +25 -0
  102. package/dist/agent-src/templates/AGENTS.md +1 -1
  103. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  104. package/dist/agent-src/templates/command.md +1 -1
  105. package/dist/agent-src/templates/copilot-instructions.md +3 -3
  106. package/dist/agent-src/templates/rule.md +2 -2
  107. package/dist/agent-src/templates/scripts/work_engine/orchestration.ts +1 -1
  108. package/dist/agent-src/templates/skill-archive-note.md +5 -5
  109. package/dist/agent-src/templates/skill.md +1 -1
  110. package/dist/cli/agent-config.js +66 -19
  111. package/dist/cli/agent-config.js.map +1 -1
  112. package/dist/cli/main.js +9 -4
  113. package/dist/cli/main.js.map +1 -1
  114. package/dist/cli/mcp/content.js +1 -1
  115. package/dist/cli/mcp/content.js.map +1 -1
  116. package/dist/cli/python/workspace_drive.js +2 -0
  117. package/dist/cli/python/workspace_drive.js.map +1 -1
  118. package/dist/cli/python/workspace_drive_health.js +2 -0
  119. package/dist/cli/python/workspace_drive_health.js.map +1 -1
  120. package/dist/cli/python/workspace_hosts.js +2 -0
  121. package/dist/cli/python/workspace_hosts.js.map +1 -1
  122. package/dist/cli/python/workspace_sessions.js +2 -0
  123. package/dist/cli/python/workspace_sessions.js.map +1 -1
  124. package/dist/cli/registry.js +1 -0
  125. package/dist/cli/registry.js.map +1 -1
  126. package/dist/cli-delegate/{chunk-A3HJ6NTI.js → chunk-63WSP6YZ.js} +2 -1
  127. package/dist/cli-delegate/{chunk-EJYIGZ3T.js → chunk-BKO2AZ7Z.js} +1 -1
  128. package/dist/cli-delegate/{chunk-GCVFLBP2.js → chunk-H574KOUH.js} +338 -494
  129. package/dist/cli-delegate/chunk-NXFWFAYV.js +339 -0
  130. package/dist/cli-delegate/{chunk-TEGJU2JX.js → chunk-ZXXJLL5K.js} +2 -2
  131. package/dist/cli-delegate/cmd_conformance.js +29 -23
  132. package/dist/cli-delegate/cmd_doctor.js +3 -3
  133. package/dist/cli-delegate/cmd_export.js +4 -4
  134. package/dist/cli-delegate/cmd_preflight.js +2 -2
  135. package/dist/cli-delegate/cmd_prune.js +4 -4
  136. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  137. package/dist/cli-delegate/cmd_sync.js +4 -4
  138. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  139. package/dist/cli-delegate/cmd_validate.js +4 -4
  140. package/dist/discovery/deprecation-report.md +1 -1
  141. package/dist/discovery/discovery-manifest.json +127 -95
  142. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  143. package/dist/discovery/discovery-manifest.summary.md +1 -1
  144. package/dist/discovery/orphan-report.md +1 -1
  145. package/dist/discovery/packs.json +2 -2
  146. package/dist/discovery/trust-report.md +1 -1
  147. package/dist/discovery/workspaces.json +2 -2
  148. package/dist/hooks/dispatch.js +729 -430
  149. package/dist/install/install.mjs +52 -11
  150. package/dist/install/rule_scope.js +18 -2
  151. package/dist/install/rule_scope.js.map +1 -1
  152. package/dist/mcp/registry-manifest.json +2 -2
  153. package/dist/mcp/server.json +2 -2
  154. package/dist/mcp/server.mjs +518 -411
  155. package/dist/router.json +1 -1
  156. package/dist/scripts/_lib/claude_settings_hooks.js +30 -5
  157. package/dist/scripts/_lib/claude_settings_hooks.js.map +1 -1
  158. package/dist/scripts/_lib/scoped_projection.js +223 -0
  159. package/dist/scripts/_lib/scoped_projection.js.map +1 -0
  160. package/dist/scripts/_lib/surface_tiers.js +125 -0
  161. package/dist/scripts/_lib/surface_tiers.js.map +1 -0
  162. package/dist/scripts/_lib/token_count.js +166 -0
  163. package/dist/scripts/_lib/token_count.js.map +1 -0
  164. package/dist/scripts/_lib/trigger_eval_floors.js +8 -0
  165. package/dist/scripts/_lib/trigger_eval_floors.js.map +1 -1
  166. package/dist/scripts/condense.js +139 -9
  167. package/dist/scripts/condense.js.map +1 -1
  168. package/dist/scripts/project_thin_rules.js +450 -0
  169. package/dist/scripts/project_thin_rules.js.map +1 -0
  170. package/dist/server/routes/workspace.js +3 -1
  171. package/dist/server/routes/workspace.js.map +1 -1
  172. package/dist/server/schemas/settings.js +9 -3
  173. package/dist/server/schemas/settings.js.map +1 -1
  174. package/dist/shared/userMd/utils.js +1 -1
  175. package/dist/shared/userMd/utils.js.map +1 -1
  176. package/dist/ui/assets/index-DmR0mbk4.js +26 -0
  177. package/dist/ui/assets/index-DmR0mbk4.js.map +1 -0
  178. package/dist/ui/index.html +1 -1
  179. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  180. package/package.json +14 -14
  181. package/src/agent-src/templates/AGENTS.md +1 -1
  182. package/src/agent-src/templates/scripts/work_engine/orchestration.ts +1 -1
  183. package/src/config/agent-settings.template.yml +61 -11
  184. package/src/config/budget-routing.json +7 -0
  185. package/src/config/ci-local-parity.yml +8 -0
  186. package/src/config/discovery/unassigned-artefacts.yml +23 -25
  187. package/src/config/evaluator-budgets.json +35 -5
  188. package/src/config/gate-coverage.yml +147 -0
  189. package/src/config/gate-violation-baselines.json +25 -0
  190. package/src/install/rule_scope.ts +27 -2
  191. package/src/scripts/_cli/cmd_conformance.ts +13 -24
  192. package/src/scripts/_dispatch.bash +10 -0
  193. package/src/scripts/_lib/claude_settings_hooks.ts +30 -4
  194. package/src/scripts/_lib/gate_baseline.ts +213 -0
  195. package/src/scripts/_lib/scoped_projection.ts +50 -0
  196. package/src/scripts/_lib/tier_budget_routing.ts +360 -0
  197. package/src/scripts/_lib/tool_adapter_registry.ts +8 -1
  198. package/src/scripts/_lib/trigger_eval_floors.ts +9 -0
  199. package/src/scripts/_lib/trigger_routers.ts +17 -5
  200. package/src/scripts/adr/regenerate_index.ts +4 -3
  201. package/src/scripts/ai-video/lib/parse-blueprint.sh +1 -1
  202. package/src/scripts/ai_council/compile_corpus.ts +1 -1
  203. package/src/scripts/anchor_scoring_run.ts +1 -1
  204. package/src/scripts/audit_cloud_compatibility.ts +37 -2
  205. package/src/scripts/audit_initial_context.ts +53 -19
  206. package/src/scripts/audit_likelihood.ts +31 -2
  207. package/src/scripts/audit_user_type_axis.ts +58 -11
  208. package/src/scripts/bench_hook_latency.ts +172 -41
  209. package/src/scripts/bench_persona_placebo.ts +1 -1
  210. package/src/scripts/bench_quality_run.ts +1 -1
  211. package/src/scripts/build_mcp_catalog.ts +12 -1
  212. package/src/scripts/check_always_budget.ts +122 -11
  213. package/src/scripts/check_augment_description_cap.ts +24 -3
  214. package/src/scripts/check_ci_strict_superset.ts +150 -0
  215. package/src/scripts/check_cli_registry_budget_sync.ts +168 -0
  216. package/src/scripts/check_cluster_patterns.ts +100 -0
  217. package/src/scripts/check_consumer_scope_flip.ts +26 -4
  218. package/src/scripts/check_evaluator_budgets.ts +198 -19
  219. package/src/scripts/check_gate_coverage.ts +338 -2
  220. package/src/scripts/check_generator_output_coverage.ts +2 -1
  221. package/src/scripts/check_iron_law_prominence.ts +1 -1
  222. package/src/scripts/check_kernel_rule_bundle.ts +1 -1
  223. package/src/scripts/check_no_new_legacy_path.ts +167 -3
  224. package/src/scripts/check_pack_size.ts +18 -4
  225. package/src/scripts/check_portability.ts +37 -7
  226. package/src/scripts/check_references.ts +19 -3
  227. package/src/scripts/check_release_pr_shape.ts +13 -0
  228. package/src/scripts/check_token_quality_golden.ts +1 -1
  229. package/src/scripts/check_token_regression.ts +9 -2
  230. package/src/scripts/condense.ts +155 -12
  231. package/src/scripts/cost/budget.mjs +77 -2
  232. package/src/scripts/evaluator_umbrella.sh +34 -1
  233. package/src/scripts/generate_capability_matrix.ts +8 -0
  234. package/src/scripts/generate_router_coverage_from_matrix.ts +155 -0
  235. package/src/scripts/hook_manifest.yaml +17 -3
  236. package/src/scripts/hooks/block_config_weakening.ts +337 -0
  237. package/src/scripts/hooks/concern_registry.ts +2 -0
  238. package/src/scripts/hooks/probe_throttle.ts +75 -0
  239. package/src/scripts/install-hooks.sh +24 -2
  240. package/src/scripts/install.ts +2 -2
  241. package/src/scripts/lint_agents_md.ts +9 -3
  242. package/src/scripts/lint_archived_skills.ts +1 -1
  243. package/src/scripts/lint_artefact_frontmatter.ts +185 -37
  244. package/src/scripts/lint_command_routing.ts +21 -52
  245. package/src/scripts/lint_command_verbs.ts +47 -28
  246. package/src/scripts/lint_context_spine_usage.ts +38 -12
  247. package/src/scripts/lint_framework_leakage.ts +25 -6
  248. package/src/scripts/lint_handoffs.ts +49 -2
  249. package/src/scripts/lint_media_policy_linkage.ts +62 -30
  250. package/src/scripts/lint_namespace.ts +92 -7
  251. package/src/scripts/lint_new_skill_gate.ts +39 -31
  252. package/src/scripts/lint_originality_shingles.ts +7 -1
  253. package/src/scripts/lint_override_kernel_guard.ts +21 -3
  254. package/src/scripts/lint_pack_boundaries.ts +461 -91
  255. package/src/scripts/lint_pack_dependencies.ts +24 -57
  256. package/src/scripts/lint_persona_governance.ts +1 -1
  257. package/src/scripts/lint_role_experiences.ts +34 -5
  258. package/src/scripts/lint_trigger_precision.ts +142 -0
  259. package/src/scripts/mcp_server/consumer_tool_catalog.json +12 -201
  260. package/src/scripts/mcp_server/tools.ts +1 -1
  261. package/src/scripts/prepack-check.mjs +40 -1
  262. package/src/scripts/prepack_router_targets.d.mts +7 -0
  263. package/src/scripts/prepack_router_targets.mjs +93 -0
  264. package/src/scripts/print_required_checks.ts +72 -18
  265. package/src/scripts/profile_staleness_hook.ts +12 -0
  266. package/src/scripts/record_evaluator_measurements.mjs +105 -0
  267. package/src/scripts/recruit_preflight.sh +1 -1
  268. package/src/scripts/release.ts +214 -7
  269. package/src/scripts/router_target_paths.d.mts +4 -0
  270. package/src/scripts/router_target_paths.mjs +69 -0
  271. package/src/scripts/router_telemetry.ts +52 -1
  272. package/src/scripts/routing_doctor.ts +560 -0
  273. package/src/scripts/rule_trigger_eval.ts +403 -0
  274. package/src/scripts/schemas/rule.schema.json +5 -1
  275. package/src/scripts/session_canary_hook.ts +96 -5
  276. package/src/scripts/skill_linter.ts +9 -28
  277. package/src/scripts/smoke/skills.sh +1 -1
  278. package/src/scripts/sweep_dead_scan_roots.ts +356 -10
  279. package/src/scripts/trigger_coverage.ts +13 -2
  280. package/src/scripts/update_counts.ts +1 -1
  281. package/src/scripts/validate_telegraph_carveouts.ts +1 -1
  282. package/src/scripts/wrapper_freshness_hook.ts +14 -0
  283. package/src/server/schemas/settings.ts +19 -5
  284. package/src/shared/userMd/utils.ts +1 -1
  285. package/dist/cli-delegate/chunk-TJIAM5FW.js +0 -133
  286. package/dist/ui/assets/index-BpSQt5vm.js +0 -40
  287. package/dist/ui/assets/index-BpSQt5vm.js.map +0 -1
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Surface-tier (core vs lab) resolution for the install split.
3
+ *
4
+ * Ported from the retired Python `src/scripts/_lib/surface_tiers.py` (ADR-200 — Python→TS
5
+ * migration). Public API mirrors the Python module exactly (snake_case kept
6
+ * deliberately — fidelity over TS idiom).
7
+ *
8
+ * road-to-install-contract-stability Phase 2. `core` = the lean stable engine
9
+ * users install; `lab` = experimental / pilot tooling. A core-only install
10
+ * excludes `lab`-tier artefacts so lab churn cannot destabilise the adoptable
11
+ * surface.
12
+ *
13
+ * Pack tier lives in `src/config/discovery/packs.yml` (`surface_tier: lab`);
14
+ * the deployed artefacts carry it in frontmatter — commands as `pack:` (scalar),
15
+ * skills as `packs:` (list). The script-cluster tier registry is
16
+ * `src/scripts/surface-tiers.yml` (consumed by the boundary guard, not here).
17
+ */
18
+ import * as fs from 'node:fs';
19
+ import * as path from 'node:path';
20
+ // Conservative fallback if packs.yml is unreadable: the day-one lab packs.
21
+ const _LAB_FALLBACK = new Set(['ai-video', 'ai-image', 'fun']);
22
+ /** Pack ids tagged `surface_tier: lab` in packs.yml (+ safe fallback). */
23
+ export function load_lab_pack_ids(repo_root) {
24
+ const vocab = path.join(repo_root, 'src', 'config', 'discovery', 'packs.yml');
25
+ const ids = new Set();
26
+ try {
27
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
28
+ const YAML = require('yaml');
29
+ // version '1.1' matches PyYAML's safe_load.
30
+ const data = YAML.parse(fs.readFileSync(vocab, 'utf-8'), { version: '1.1' });
31
+ for (const entry of data ?? []) {
32
+ if (entry && typeof entry === 'object' && !Array.isArray(entry)) {
33
+ const rec = entry;
34
+ if (rec['surface_tier'] === 'lab') {
35
+ const pid = rec['id'];
36
+ if (typeof pid === 'string') {
37
+ ids.add(pid);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ catch {
44
+ // packs.yml missing / unparseable / no yaml → conservative fallback.
45
+ return new Set(_LAB_FALLBACK);
46
+ }
47
+ return ids.size > 0 ? ids : new Set(_LAB_FALLBACK);
48
+ }
49
+ /**
50
+ * Parse a markdown file's leading frontmatter into its pack set.
51
+ *
52
+ * Handles both shapes: `pack: <id>` (commands) and `packs:` followed by
53
+ * `- <id>` list items (skills). Returns an empty set on any parse failure
54
+ * or when the file carries no pack tag.
55
+ */
56
+ export function frontmatter_packs(md_path) {
57
+ let text;
58
+ try {
59
+ text = fs.readFileSync(md_path, 'utf-8');
60
+ }
61
+ catch {
62
+ // OSError / decode error → empty.
63
+ return new Set();
64
+ }
65
+ if (!text.startsWith('---')) {
66
+ return new Set();
67
+ }
68
+ const end = text.indexOf('\n---', 3);
69
+ const block = end !== -1 ? text.slice(3, end) : text.slice(3);
70
+ const packs = new Set();
71
+ let in_packs_list = false;
72
+ for (const raw of block.split('\n')) {
73
+ const line = raw.replace(/\s+$/, '');
74
+ const stripped = line.trim();
75
+ if (in_packs_list) {
76
+ if (stripped.startsWith('- ')) {
77
+ packs.add(_strip_quotes(stripped.slice(2).trim()));
78
+ continue;
79
+ }
80
+ in_packs_list = false;
81
+ }
82
+ if (stripped.startsWith('pack:')) {
83
+ const val = _strip_quotes(stripped.split(':').slice(1).join(':').trim());
84
+ if (val) {
85
+ packs.add(val);
86
+ }
87
+ }
88
+ else if (stripped.startsWith('packs:')) {
89
+ const inline = stripped.split(':').slice(1).join(':').trim();
90
+ if (inline.startsWith('[') && inline.endsWith(']')) {
91
+ for (const raw_item of inline.slice(1, -1).split(',')) {
92
+ const item = _strip_quotes(raw_item.trim());
93
+ if (item) {
94
+ packs.add(item);
95
+ }
96
+ }
97
+ }
98
+ else {
99
+ in_packs_list = true;
100
+ }
101
+ }
102
+ }
103
+ return packs;
104
+ }
105
+ /** True when a deployed markdown artefact belongs to a lab-tier pack. */
106
+ export function is_lab_artefact(md_path, lab_ids) {
107
+ for (const p of frontmatter_packs(md_path)) {
108
+ if (lab_ids.has(p)) {
109
+ return true;
110
+ }
111
+ }
112
+ return false;
113
+ }
114
+ /** Mirror of Python `str.strip("'\"")` — strips matching outer quote chars. */
115
+ function _strip_quotes(s) {
116
+ let out = s;
117
+ while (out.length > 0 && (out[0] === "'" || out[0] === '"')) {
118
+ out = out.slice(1);
119
+ }
120
+ while (out.length > 0 && (out[out.length - 1] === "'" || out[out.length - 1] === '"')) {
121
+ out = out.slice(0, -1);
122
+ }
123
+ return out;
124
+ }
125
+ //# sourceMappingURL=surface_tiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface_tiers.js","sourceRoot":"","sources":["../../../src/scripts/_lib/surface_tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,2EAA2E;AAC3E,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAEpF,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,CAAC;QACD,iEAAiE;QACjE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAsB,CAAC;QAClD,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7E,KAAK,MAAM,KAAK,IAAK,IAAkB,IAAI,EAAE,EAAE,CAAC;YAC5C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;gBAC7C,IAAI,GAAG,CAAC,cAAc,CAAC,KAAK,KAAK,EAAE,CAAC;oBAChC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;oBACtB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;wBAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACjB,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,qEAAqE;QACrE,OAAO,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC7C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACD,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACL,kCAAkC;QAClC,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE9D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,aAAa,EAAE,CAAC;YAChB,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnD,SAAS;YACb,CAAC;YACD,aAAa,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzE,IAAI,GAAG,EAAE,CAAC;gBACN,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACL,CAAC;aAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpD,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC5C,IAAI,IAAI,EAAE,CAAC;wBACP,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,aAAa,GAAG,IAAI,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,OAAoB;IACjE,KAAK,MAAM,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,SAAS,aAAa,CAAC,CAAS;IAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1D,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACpF,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Real-tokenizer counting for the budget tooling
3
+ * (roadmap 0B.1 → token-saving Phase 0, "real tokenizer into the bench path").
4
+ *
5
+ * `char != token`. Every budget in this suite is historically in characters;
6
+ * this helper reports a token count *alongside* chars so chars stay the cheap
7
+ * proxy and tokens become the truth where a real tokenizer is available.
8
+ *
9
+ * Design — optional dependency, graceful proxy fallback, **synchronous** API:
10
+ *
11
+ * - **GPT** — uses `js-tiktoken` (encoding `cl100k_base`) when the dependency
12
+ * is present, producing EXACT BPE counts flagged `exact: true`. `js-tiktoken`
13
+ * is a build/measurement-time **devDependency** (consumed by the bench /
14
+ * audit tooling, never shipped to a consumer runtime). When it is absent —
15
+ * e.g. a consumer that installed without devDependencies — the module falls
16
+ * back to the documented `chars / 4` proxy flagged `exact: false`. The
17
+ * optional load is a synchronous `createRequire(...)` inside a try/catch so
18
+ * the public `measure()` / `gpt_tokens()` API stays synchronous and never
19
+ * hard-fails on a missing dependency (no mandatory install, no network).
20
+ * - **Claude** — no offline Claude tokenizer exists; documented `chars / 3.6`
21
+ * proxy, always `exact: false`. (Anthropic's exact count is API-only.)
22
+ *
23
+ * Both proxies are intentionally conservative ratios drawn from English-prose +
24
+ * markdown samples; they are estimates, never gates.
25
+ *
26
+ * The `*_proxy` helpers (`gpt_tokens_proxy`, `measure_proxy`,
27
+ * `method_note_proxy`) expose the fallback math directly — they are used by the
28
+ * fallback regression guard in the test suite and by any report that wants to
29
+ * record both the exact and the proxy count to flag the delta.
30
+ *
31
+ * Parity notes: "chars" counts Unicode code points (`len(str)` parity), not
32
+ * UTF-16 units; proxy rounding is banker's rounding.
33
+ */
34
+ import { createRequire } from "node:module";
35
+ // Proxy ratios (chars per token) for the no-tokenizer fallback. Tuned for
36
+ // English markdown rule/skill prose; deliberately conservative.
37
+ const _GPT_CHARS_PER_TOKEN = 4.0;
38
+ const _CLAUDE_CHARS_PER_TOKEN = 3.6;
39
+ // Roadmap (token-saving Phase 0) mandates the `cl100k_base` encoding. The
40
+ // dependency also bundles `o200k_base` (GPT-4o / GPT-4.1 family); switching the
41
+ // GPT count basis is a one-line change to this constant. The exact-vs-proxy
42
+ // delta is recorded in every report via `method_note()`.
43
+ const _TIKTOKEN_ENCODING = "cl100k_base";
44
+ /**
45
+ * Load the optional `js-tiktoken` encoder synchronously, returning `null` when
46
+ * the dependency is absent or fails to initialise (graceful proxy fallback).
47
+ * `createRequire` resolves the CJS build so the call stays synchronous even
48
+ * though this module is ESM.
49
+ */
50
+ function _loadEncoder() {
51
+ try {
52
+ const require = createRequire(import.meta.url);
53
+ const mod = require("js-tiktoken");
54
+ return mod.getEncoding(_TIKTOKEN_ENCODING);
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ // Resolved once at module load. js-tiktoken's `getEncoding` is synchronous with
61
+ // bundled rank tables, so eager init is cheap and keeps `TIKTOKEN_AVAILABLE` a
62
+ // plain const (the historical API shape).
63
+ const _ENCODER = _loadEncoder();
64
+ /** True when the real tokenizer is available (exact GPT counts), else proxy. */
65
+ export const TIKTOKEN_AVAILABLE = _ENCODER !== null;
66
+ /** A single token measurement and whether it is exact or a proxy. */
67
+ export class TokenCount {
68
+ tokens;
69
+ exact;
70
+ constructor(tokens, exact) {
71
+ this.tokens = tokens;
72
+ this.exact = exact;
73
+ Object.freeze(this); // dataclass(frozen=True) parity
74
+ }
75
+ }
76
+ /** Count Unicode code points — `len(str)` parity. */
77
+ function _len(text) {
78
+ let count = 0;
79
+ // for..of iterates code points, so astral chars count once.
80
+ for (const _ch of text)
81
+ count += 1;
82
+ return count;
83
+ }
84
+ /** Banker's rounding (round half to even) — proxy-path parity. */
85
+ function _python_round(x) {
86
+ const floor = Math.floor(x);
87
+ const diff = x - floor;
88
+ if (diff > 0.5)
89
+ return floor + 1;
90
+ if (diff < 0.5)
91
+ return floor;
92
+ return floor % 2 === 0 ? floor : floor + 1;
93
+ }
94
+ /** Render a float like a Python f-string (4.0 → "4.0", 3.6 → "3.6"). */
95
+ function _py_float_repr(x) {
96
+ return Number.isInteger(x) ? `${x}.0` : `${x}`;
97
+ }
98
+ /**
99
+ * GPT token count — EXACT via js-tiktoken (`cl100k_base`) when available,
100
+ * otherwise the documented `chars / 4` proxy.
101
+ */
102
+ export function gpt_tokens(text) {
103
+ if (_ENCODER !== null) {
104
+ return new TokenCount(_ENCODER.encode(text).length, true);
105
+ }
106
+ return gpt_tokens_proxy(text);
107
+ }
108
+ /**
109
+ * GPT proxy count (`chars / 4`, banker's rounding) — the fallback path,
110
+ * exposed directly for the fallback regression guard and delta reporting.
111
+ */
112
+ export function gpt_tokens_proxy(text) {
113
+ return new TokenCount(_python_round(_len(text) / _GPT_CHARS_PER_TOKEN), false);
114
+ }
115
+ /** Claude token count — documented offline proxy (no local Claude tokenizer). */
116
+ export function claude_tokens(text) {
117
+ return new TokenCount(_python_round(_len(text) / _CLAUDE_CHARS_PER_TOKEN), false);
118
+ }
119
+ /**
120
+ * Return chars + per-model token counts for one text blob.
121
+ *
122
+ * `tokens_gpt` is exact (js-tiktoken) when available; `tokens_gpt_exact` tells
123
+ * the report consumer which path produced it. `tokens_claude` is always the
124
+ * proxy (no offline Claude tokenizer).
125
+ */
126
+ export function measure(text) {
127
+ const g = gpt_tokens(text);
128
+ const c = claude_tokens(text);
129
+ return {
130
+ chars: _len(text),
131
+ tokens_gpt: g.tokens,
132
+ tokens_gpt_exact: g.exact,
133
+ tokens_claude: c.tokens,
134
+ tokens_claude_exact: c.exact,
135
+ };
136
+ }
137
+ /**
138
+ * Proxy-only measure (forces the chars-based estimate for GPT regardless of
139
+ * tokenizer availability). Use to record both the exact and the proxy count
140
+ * and flag the delta, and as the fallback regression guard.
141
+ */
142
+ export function measure_proxy(text) {
143
+ const g = gpt_tokens_proxy(text);
144
+ const c = claude_tokens(text);
145
+ return {
146
+ chars: _len(text),
147
+ tokens_gpt: g.tokens,
148
+ tokens_gpt_exact: g.exact,
149
+ tokens_claude: c.tokens,
150
+ tokens_claude_exact: c.exact,
151
+ };
152
+ }
153
+ /** Proxy-path provenance string (the fallback note). */
154
+ export function method_note_proxy() {
155
+ return (`tokens_gpt: proxy (chars/${_py_float_repr(_GPT_CHARS_PER_TOKEN)}, tiktoken not installed); ` +
156
+ `tokens_claude: proxy (chars/${_py_float_repr(_CLAUDE_CHARS_PER_TOKEN)})`);
157
+ }
158
+ /** One-line provenance of how token counts were produced (for reports). */
159
+ export function method_note() {
160
+ if (TIKTOKEN_AVAILABLE) {
161
+ return (`tokens_gpt: exact (tiktoken ${_TIKTOKEN_ENCODING}); ` +
162
+ `tokens_claude: proxy (chars/${_py_float_repr(_CLAUDE_CHARS_PER_TOKEN)})`);
163
+ }
164
+ return method_note_proxy();
165
+ }
166
+ //# sourceMappingURL=token_count.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token_count.js","sourceRoot":"","sources":["../../../src/scripts/_lib/token_count.ts"],"names":[],"mappings":"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"}
@@ -21,4 +21,12 @@ export const DOMAIN_FLOORS = {
21
21
  export function floor_for(skill) {
22
22
  return (skill !== null && skill !== undefined && DOMAIN_FLOORS[skill]) || DEFAULT_FLOOR;
23
23
  }
24
+ /**
25
+ * Advisory floor for the rules-mode canary leg (`rule_trigger_eval.ts`,
26
+ * road-to-tested-routing Phase 4). Deliberately loose: it is a drift canary
27
+ * over a ~40-case derived suite spanning ~97 rules, not a per-rule quality
28
+ * gate — ratchet only after live baseline data exists. A breach fails the
29
+ * scheduled canary job only, never a PR.
30
+ */
31
+ export const RULES_MODE_FLOOR = { minRecall: 0.5, minPrecision: 0.5 };
24
32
  //# sourceMappingURL=trigger_eval_floors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trigger_eval_floors.js","sourceRoot":"","sources":["../../../src/scripts/_lib/trigger_eval_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAqB,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;AAErF,qFAAqF;AACrF,MAAM,CAAC,MAAM,aAAa,GAA+C;IACrE,kBAAkB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE;IAC1D,WAAW,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;IAClD,gBAAgB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;CAC1D,CAAC;AAEF,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,KAAgC;IACtD,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC;AAC5F,CAAC"}
1
+ {"version":3,"file":"trigger_eval_floors.js","sourceRoot":"","sources":["../../../src/scripts/_lib/trigger_eval_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAqB,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;AAErF,qFAAqF;AACrF,MAAM,CAAC,MAAM,aAAa,GAA+C;IACrE,kBAAkB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE;IAC1D,WAAW,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;IAClD,gBAAgB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;CAC1D,CAAC;AAEF,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,KAAgC;IACtD,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC;AAC5F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqB,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC"}
@@ -31,11 +31,18 @@ import * as os from 'node:os';
31
31
  import * as path from 'node:path';
32
32
  import { fileURLToPath, pathToFileURL } from 'node:url';
33
33
  import * as YAML from 'yaml';
34
- import { artefact_roots as _agent_src_artefact_roots, iter_all_sources as _agent_src_iter_all_sources, resolve_logical as _agent_src_resolve_logical, strip_source_prefix, } from './_lib/agent_src.js';
34
+ import { _domains_command_logical, artefact_roots as _agent_src_artefact_roots, iter_all_sources as _agent_src_iter_all_sources, resolve_logical as _agent_src_resolve_logical, strip_source_prefix, } from './_lib/agent_src.js';
35
+ // Import-safety note: `project_thin_rules` guards its CLI entry
36
+ // (`_isCliEntry()` before `process.exit(main())`), so importing it here is
37
+ // side-effect-free. condense.ts is bundled into the installer, where a bare
38
+ // top-level `process.exit` would fire at consumer runtime — the documented
39
+ // bundled-CLI-entry-guard landmine. Verified before wiring, not assumed.
40
+ import { build_thin } from './project_thin_rules.js';
35
41
  import { build_claude_hook_matrix } from './_lib/claude_settings_hooks.js';
36
42
  import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
37
43
  import { project_settings_path, load_agent_settings } from './_lib/agent_settings.js';
38
44
  import { rule_is_compile_enabled } from './_lib/compile_time_toggles.js';
45
+ import { resolve_rule_pack_scope } from './_lib/scoped_projection.js';
39
46
  import { info, success, flush_summary, resolve_level } from './_lib/script_output.js';
40
47
  import { TIER_TO_CLAUDE_MODEL as _TIER_TO_CLAUDE_MODEL, MODEL_TIER_RE as _MODEL_TIER_RE, } from './_lib/model_tier.js';
41
48
  // The Python module imports `_SLUG_PREFIX_RE` from `_lib.agent_src`. The TS
@@ -885,12 +892,15 @@ export { _HRR_BANNER_MARKER };
885
892
  // the kernel is unconditional and workspace-independent by definition
886
893
  // (rule-router contract § Schema v2). Untagged rules fail safe: they ship.
887
894
  // ADR-040: projection-time filtering only, no runtime resolver.
888
- function _read_projection_list(key) {
895
+ function _read_projection_raw(key) {
889
896
  const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
890
897
  const proj = data['projection'];
891
- const value = typeof proj === 'object' && proj !== null && !Array.isArray(proj)
898
+ return typeof proj === 'object' && proj !== null && !Array.isArray(proj)
892
899
  ? proj[key]
893
900
  : null;
901
+ }
902
+ function _read_projection_list(key) {
903
+ const value = _read_projection_raw(key);
894
904
  if (Array.isArray(value) && value.length > 0) {
895
905
  return value.map((v) => String(v));
896
906
  }
@@ -899,8 +909,22 @@ function _read_projection_list(key) {
899
909
  function _read_rule_workspaces() {
900
910
  return _read_projection_list('rule_workspaces');
901
911
  }
912
+ /** `runtime.active_packs` overlay, empty when unset (fresh-install default). */
913
+ function _read_runtime_active_packs() {
914
+ const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
915
+ const rt = data['runtime'];
916
+ const value = typeof rt === 'object' && rt !== null && !Array.isArray(rt)
917
+ ? rt['active_packs']
918
+ : null;
919
+ return Array.isArray(value) ? value.map((v) => String(v)) : [];
920
+ }
921
+ /**
922
+ * Pack scope for the rule layer. `rule_packs: auto` derives the active-pack
923
+ * set (the same one the skill/command prune uses) instead of a hand-typed id
924
+ * list; anything else keeps the historical list-or-inactive semantics.
925
+ */
902
926
  function _read_rule_packs() {
903
- return _read_projection_list('rule_packs');
927
+ return resolve_rule_pack_scope(_read_projection_raw('rule_packs'), MODULE_STATE.PROJECT_ROOT, _read_runtime_active_packs());
904
928
  }
905
929
  /**
906
930
  * Whether a rule source file projects under the given workspace + pack +
@@ -936,10 +960,18 @@ export function generate_rule_symlinks() {
936
960
  const tool_dirs = _filter_tool_dirs(TOOL_DIRS);
937
961
  let thin_files = null;
938
962
  if (_lean_projection_mode() === 'thin') {
939
- // The `project_thin_rules` twin is not ported (out of scope — thin mode
940
- // is opt-in and not exercised by golden parity). Throw a clear error if
941
- // a consumer actually enables it, mirroring an unmet import.
942
- throw new Error('lean_projection.mode=thin requires project_thin_rules (not ported in condense.ts)');
963
+ // DEAD-SWITCH REPAIR (road-to-renewal-foundation Phase 2). This branch
964
+ // used to THROW: the port was skipped as "out of scope, not exercised by
965
+ // golden parity", which left a documented, settings-selectable mode that
966
+ // could only ever crash. `build_thin` was ported and has been present the
967
+ // whole time — the wiring was the only thing missing.
968
+ //
969
+ // Scope note: this repairs the SWITCH only. The default stays
970
+ // `eager-all`. Flipping it is parked behind the thin-projection honest
971
+ // null (thin win-rate 36.2% < the 48% pre-registered threshold), and
972
+ // nothing here disturbs that verdict — but a mode that throws cannot
973
+ // even be re-measured, which is why the repair earns its place alone.
974
+ thin_files = Object.fromEntries(build_thin(MODULE_STATE.RULES_SOURCE, _read_rule_workspaces()));
943
975
  }
944
976
  const dedup_on = _read_projection_scope_dedup();
945
977
  const user_home = process.env['HOME'] ?? os.homedir();
@@ -1026,6 +1058,9 @@ function _WINDSURF_WORKFLOWS_DIR() {
1026
1058
  function _CURSOR_COMMANDS_DIR() {
1027
1059
  return path.join(MODULE_STATE.PROJECT_ROOT, '.cursor', 'commands');
1028
1060
  }
1061
+ function _CLAUDE_COMMANDS_DIR() {
1062
+ return path.join(MODULE_STATE.PROJECT_ROOT, '.claude', 'commands');
1063
+ }
1029
1064
  function _parse_frontmatter(content) {
1030
1065
  if (!content.startsWith('---')) {
1031
1066
  return [{}, content];
@@ -1412,6 +1447,86 @@ export function extract_description_from_md(content) {
1412
1447
  }
1413
1448
  return '';
1414
1449
  }
1450
+ /**
1451
+ * The `commands/<sub>` path of a command source file, or `null` when it is a
1452
+ * FLAT command (`commands/<name>.md`).
1453
+ *
1454
+ * A nested path is what Claude Code renders as `/cluster:sub`. Flat command
1455
+ * FILES are not registered by Claude Code (probed ≤ 2.1.204 — see the
1456
+ * flat-command mitigation in `install.ts`), which is why flat commands keep a
1457
+ * skill wrapper and nested ones do not need one.
1458
+ */
1459
+ function _nested_command_subpath(source_file) {
1460
+ const rel = _relativeToPosix(source_file, MODULE_STATE.PROJECT_ROOT);
1461
+ const logical = _domains_command_logical(rel);
1462
+ if (logical === null || !logical.startsWith('commands/')) {
1463
+ return null;
1464
+ }
1465
+ const sub = logical.slice('commands/'.length).replace(/\.md$/, '');
1466
+ return sub.includes('/') ? sub : null;
1467
+ }
1468
+ /**
1469
+ * Project-scope `.claude/commands/<cluster>/<sub>.md` — the colon form.
1470
+ *
1471
+ * Before this, the package repo's own `.claude/` carried NO commands
1472
+ * directory: every command reached Claude Code as a hyphen-named skill
1473
+ * wrapper in `.claude/skills/`, while the colon form existed only in the
1474
+ * user-global tree written by `install.ts`. Every clustered command was
1475
+ * therefore listed TWICE for anyone with a global install
1476
+ * (`roadmap-process-full` AND `roadmap:process-full`), costing 4,214 GPT tok
1477
+ * of always-loaded catalog for zero added reach — measured 2026-08-02.
1478
+ *
1479
+ * Emitting the nested form here lets `generate_claude_commands` stop wrapping
1480
+ * the clustered commands: one listing, same reachability, and reachability no
1481
+ * longer depends on a global deploy having run. Claude Code dedupes project
1482
+ * and user scope by name, so the two copies of `/cluster:sub` collapse.
1483
+ *
1484
+ * ADR-003 (colon canonical for clusters) and ADR-044 (flat commands stay
1485
+ * hyphenated) both hold: flat commands are untouched and keep their wrapper.
1486
+ */
1487
+ export function generate_claude_project_commands(active_command_slugs = null) {
1488
+ if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
1489
+ return 0;
1490
+ }
1491
+ const nested = [];
1492
+ for (const [source_file, slug] of iterCommands()) {
1493
+ if (active_command_slugs !== null && !active_command_slugs.has(slug)) {
1494
+ continue;
1495
+ }
1496
+ const sub = _nested_command_subpath(source_file);
1497
+ if (sub !== null) {
1498
+ nested.push([source_file, sub]);
1499
+ }
1500
+ }
1501
+ const target_root = _CLAUDE_COMMANDS_DIR();
1502
+ const valid = new Set(nested.map(([, sub]) => `${sub}.md`));
1503
+ // Sweep stale links first: a renamed or deleted command must not linger as
1504
+ // a dangling `/cluster:sub`.
1505
+ if (_exists(target_root)) {
1506
+ for (const item of _rglobSorted(target_root, '*.md')) {
1507
+ const rel = _relativeToPosix(item, target_root);
1508
+ if (!valid.has(rel)) {
1509
+ fs.unlinkSync(item);
1510
+ }
1511
+ }
1512
+ }
1513
+ let count = 0;
1514
+ for (const [source_file, sub] of nested) {
1515
+ const link = path.join(target_root, `${sub}.md`);
1516
+ _mkdirp(path.dirname(link));
1517
+ if (_existsOrSymlink(link)) {
1518
+ fs.unlinkSync(link);
1519
+ }
1520
+ // path.relative, not a hand-counted `../` run: the nesting depth
1521
+ // varies (2 and 3 segments both occur) and an off-by-one here writes
1522
+ // a dangling link that still LOOKS right in `ls -l`.
1523
+ const rel_target = path.relative(path.dirname(link), source_file);
1524
+ fs.symlinkSync(rel_target, link);
1525
+ count += 1;
1526
+ }
1527
+ info(` ✅ Linked ${count} \`.claude/commands/**/*.md\` files (colon form)`);
1528
+ return count;
1529
+ }
1415
1530
  export function generate_claude_commands(active_command_slugs = null) {
1416
1531
  if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
1417
1532
  process.stderr.write(' ⚠️ src/domains/ not found — skipping commands\n');
@@ -1438,6 +1553,15 @@ export function generate_claude_commands(active_command_slugs = null) {
1438
1553
  skipped += 1;
1439
1554
  continue;
1440
1555
  }
1556
+ // A clustered command already reaches Claude Code as `/cluster:sub`
1557
+ // from `.claude/commands/` (generate_claude_project_commands). A
1558
+ // hyphen wrapper on top would be a second listing of the same command
1559
+ // — the double-listing this de-duplicates. Flat commands still need
1560
+ // the wrapper: Claude Code does not register flat command FILES.
1561
+ if (_nested_command_subpath(source_file) !== null) {
1562
+ skipped += 1;
1563
+ continue;
1564
+ }
1441
1565
  // Never claim a `/name` that is a Claude Code built-in command or
1442
1566
  // bundled skill — a same-name entry shadows the built-in (e.g. a
1443
1567
  // `review` entry hides Claude Code's own /review). Nested
@@ -1937,6 +2061,11 @@ function _generate_tools_inner(cmd_slugs, skill_names) {
1937
2061
  generate_gemini_md();
1938
2062
  }
1939
2063
  const skills = _tool_active('claude-code') ? generate_claude_skills(skill_names) : 0;
2064
+ // Colon form first: `generate_claude_commands` skips every command this
2065
+ // one emitted, so the ordering is what keeps the two from double-listing.
2066
+ const claude_cmds = _tool_active('claude-code')
2067
+ ? generate_claude_project_commands(cmd_slugs)
2068
+ : 0;
1940
2069
  const commands = _tool_active('claude-code') ? generate_claude_commands(cmd_slugs) : 0;
1941
2070
  const subagents = _tool_active('claude-code') ? generate_claude_subagents() : 0;
1942
2071
  const subagent_contexts = generate_subagent_host_contexts();
@@ -1949,7 +2078,8 @@ function _generate_tools_inner(cmd_slugs, skill_names) {
1949
2078
  const cursor_cmds = _tool_active('cursor') ? generate_cursor_commands(cmd_slugs) : 0;
1950
2079
  const windsurf_wf = _tool_active('windsurf') ? generate_windsurf_workflows(cmd_slugs) : 0;
1951
2080
  const summary = `✅ generate-tools — rules=${rules} skills=${skills} ` +
1952
- `commands=${commands} subagents=${subagents} subagent_contexts=${subagent_contexts} plugin_cmd_skills=${plugin_cmd_skills} ` +
2081
+ `claude_commands=${claude_cmds} command_skills=${commands} ` +
2082
+ `subagents=${subagents} subagent_contexts=${subagent_contexts} plugin_cmd_skills=${plugin_cmd_skills} ` +
1953
2083
  `plugin_hooks=${plugin_hooks} ` +
1954
2084
  `personas=${personas} user_types=${user_types} ` +
1955
2085
  `cursor_mdc=${cursor_mdc} windsurf_rules=${windsurf_modern} ` +