@event4u/agent-config 9.13.0 → 9.15.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/CHANGELOG.md +113 -67
- package/README.md +9 -1
- package/dist/agent-src/commands/agents/audit.md +7 -7
- package/dist/agent-src/commands/agents/optimize.md +1 -1
- package/dist/agent-src/commands/analyze/reference-repo.md +1 -1
- package/dist/agent-src/commands/chat-history.md +1 -0
- package/dist/agent-src/commands/context.md +1 -0
- package/dist/agent-src/commands/council.md +1 -1
- package/dist/agent-src/commands/ghostwriter.md +1 -1
- package/dist/agent-src/commands/memory.md +2 -1
- package/dist/agent-src/commands/module.md +1 -0
- package/dist/agent-src/commands/optimize/agents-dir.md +1 -1
- package/dist/agent-src/commands/optimize/deep.md +150 -0
- package/dist/agent-src/commands/optimize/skills.md +5 -5
- package/dist/agent-src/commands/optimize.md +12 -6
- package/dist/agent-src/commands/override.md +1 -0
- package/dist/agent-src/commands/prediction-pool.md +4 -4
- package/dist/agent-src/commands/research/deep.md +1 -1
- package/dist/agent-src/commands/roadmap.md +2 -1
- package/dist/agent-src/commands/rule-compliance-audit.md +1 -1
- package/dist/agent-src/commands/tdd.md +1 -0
- package/dist/agent-src/commands/tests.md +1 -0
- package/dist/agent-src/commands/upstream-contribute.md +5 -5
- package/dist/agent-src/commands/video/from-script.md +1 -1
- package/dist/agent-src/commands/video/from-song.md +1 -1
- package/dist/agent-src/commands/video/scene.md +1 -1
- package/dist/agent-src/commands/video/stitch.md +1 -1
- package/dist/agent-src/commands/video/storyboard.md +1 -1
- package/dist/agent-src/commands/worktree/create.md +2 -1
- package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
- package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +5 -5
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -3
- package/dist/agent-src/contexts/contracts/emergency-triage-block.md +2 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +4 -3
- package/dist/agent-src/contexts/execution/subagent-routing.md +19 -0
- package/dist/agent-src/contexts/override-system.md +1 -1
- package/dist/agent-src/ghostwriter/fictional-fixture-v1.md +1 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +2 -1
- package/dist/agent-src/rules/brand-consistency.md +1 -0
- package/dist/agent-src/rules/brand-source-of-truth.md +1 -0
- package/dist/agent-src/rules/code-comment-discipline.md +2 -0
- package/dist/agent-src/rules/communication-through-line.md +1 -0
- package/dist/agent-src/rules/content-quoting-floor.md +1 -0
- package/dist/agent-src/rules/cross-source-consistency.md +0 -1
- package/dist/agent-src/rules/downstream-changes.md +1 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +1 -0
- package/dist/agent-src/rules/external-reference-deep-dive.md +1 -0
- package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
- package/dist/agent-src/rules/finance-safety-floor.md +0 -1
- package/dist/agent-src/rules/icon-consistency.md +1 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
- package/dist/agent-src/rules/improve-before-implement.md +1 -1
- package/dist/agent-src/rules/invite-challenge.md +1 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +1 -0
- package/dist/agent-src/rules/media-governance-routing.md +4 -3
- package/dist/agent-src/rules/media-sync-ground-truth.md +1 -0
- package/dist/agent-src/rules/no-attribution-footers.md +1 -0
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +1 -0
- package/dist/agent-src/rules/no-pr-progress-comments.md +1 -0
- package/dist/agent-src/rules/onboarding-gate.md +1 -0
- package/dist/agent-src/rules/output-discipline.md +1 -0
- package/dist/agent-src/rules/prefer-enums-over-literals.md +1 -0
- package/dist/agent-src/rules/preservation-guard.md +1 -0
- package/dist/agent-src/rules/question-not-instruction.md +1 -0
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +1 -0
- package/dist/agent-src/rules/role-mode-adherence.md +1 -0
- package/dist/agent-src/rules/runtime-safety.md +1 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +1 -0
- package/dist/agent-src/rules/session-canary.md +9 -2
- package/dist/agent-src/rules/source-confidentiality.md +1 -0
- package/dist/agent-src/rules/source-of-truth.md +1 -0
- package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -0
- package/dist/agent-src/rules/think-before-action.md +1 -0
- package/dist/agent-src/rules/token-budget-discipline.md +1 -0
- package/dist/agent-src/rules/token-efficiency.md +1 -0
- package/dist/agent-src/rules/token-optimizer-maintenance.md +5 -5
- package/dist/agent-src/rules/tool-safety.md +1 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +2 -0
- package/dist/agent-src/rules/user-interaction.md +1 -0
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +1 -1
- package/dist/agent-src/skills/check-refs/SKILL.md +1 -1
- package/dist/agent-src/skills/competitive-positioning/SKILL.md +1 -1
- package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +1 -1
- package/dist/agent-src/skills/description-assist/SKILL.md +1 -1
- package/dist/agent-src/skills/github-ci/SKILL.md +1 -0
- package/dist/agent-src/skills/guideline-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/lint-skills/SKILL.md +1 -1
- package/dist/agent-src/skills/readme-reviewer/SKILL.md +1 -1
- package/dist/agent-src/skills/roadmap-management/SKILL.md +8 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/SKILL.md +4 -4
- package/dist/agent-src/skills/token-optimizer/SKILL.md +4 -4
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +6 -6
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +25 -0
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/command.md +1 -1
- package/dist/agent-src/templates/copilot-instructions.md +3 -3
- package/dist/agent-src/templates/rule.md +2 -2
- package/dist/agent-src/templates/scripts/work_engine/orchestration.ts +1 -1
- package/dist/agent-src/templates/skill-archive-note.md +5 -5
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/agent-config.js +66 -19
- package/dist/cli/agent-config.js.map +1 -1
- package/dist/cli/main.js +9 -4
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/python/workspace_drive.js +2 -0
- package/dist/cli/python/workspace_drive.js.map +1 -1
- package/dist/cli/python/workspace_drive_health.js +2 -0
- package/dist/cli/python/workspace_drive_health.js.map +1 -1
- package/dist/cli/python/workspace_hosts.js +2 -0
- package/dist/cli/python/workspace_hosts.js.map +1 -1
- package/dist/cli/python/workspace_sessions.js +2 -0
- package/dist/cli/python/workspace_sessions.js.map +1 -1
- package/dist/cli/registry.js +1 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-A3HJ6NTI.js → chunk-63WSP6YZ.js} +2 -1
- package/dist/cli-delegate/{chunk-EJYIGZ3T.js → chunk-BKO2AZ7Z.js} +1 -1
- package/dist/cli-delegate/{chunk-QFKQLQ7X.js → chunk-H574KOUH.js} +340 -462
- package/dist/cli-delegate/chunk-NXFWFAYV.js +339 -0
- package/dist/cli-delegate/{chunk-TEGJU2JX.js → chunk-ZXXJLL5K.js} +2 -2
- package/dist/cli-delegate/cmd_conformance.js +29 -23
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +163 -103
- 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 +6 -5
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +729 -430
- package/dist/install/install.mjs +700 -625
- package/dist/install/rule_scope.js +18 -2
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +564 -424
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/claude_settings_hooks.js +30 -5
- package/dist/scripts/_lib/claude_settings_hooks.js.map +1 -1
- package/dist/scripts/_lib/scoped_projection.js +223 -0
- package/dist/scripts/_lib/scoped_projection.js.map +1 -0
- package/dist/scripts/_lib/surface_tiers.js +125 -0
- package/dist/scripts/_lib/surface_tiers.js.map +1 -0
- package/dist/scripts/_lib/token_count.js +166 -0
- package/dist/scripts/_lib/token_count.js.map +1 -0
- package/dist/scripts/_lib/trigger_eval_floors.js +8 -0
- package/dist/scripts/_lib/trigger_eval_floors.js.map +1 -1
- package/dist/scripts/condense.js +139 -9
- package/dist/scripts/condense.js.map +1 -1
- package/dist/scripts/project_thin_rules.js +450 -0
- package/dist/scripts/project_thin_rules.js.map +1 -0
- package/dist/server/routes/workspace.js +2 -0
- package/dist/server/routes/workspace.js.map +1 -1
- package/dist/server/schemas/settings.js +9 -3
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/ui/assets/index-DJY_vQVn.js +40 -0
- package/dist/ui/assets/index-DJY_vQVn.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/package.json +11 -11
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/work_engine/orchestration.ts +1 -1
- package/src/config/agent-settings.template.yml +59 -11
- package/src/config/ci-local-parity.yml +8 -0
- package/src/config/discovery/unassigned-artefacts.yml +23 -25
- package/src/config/evaluator-budgets.json +35 -5
- package/src/config/gate-coverage.yml +147 -0
- package/src/config/gate-violation-baselines.json +25 -0
- package/src/install/rule_scope.ts +27 -2
- package/src/scripts/_cli/cmd_conformance.ts +13 -24
- package/src/scripts/_dispatch.bash +10 -0
- package/src/scripts/_lib/claude_settings_hooks.ts +30 -4
- package/src/scripts/_lib/exec_evidence.ts +5 -0
- package/src/scripts/_lib/gate_baseline.ts +213 -0
- package/src/scripts/_lib/scoped_projection.ts +262 -0
- package/src/scripts/_lib/tier_budget_routing.ts +234 -0
- package/src/scripts/_lib/tool_adapter_registry.ts +8 -1
- package/src/scripts/_lib/trigger_eval_floors.ts +9 -0
- package/src/scripts/_lib/trigger_routers.ts +17 -5
- package/src/scripts/adr/regenerate_index.ts +4 -3
- package/src/scripts/ai-video/lib/parse-blueprint.sh +1 -1
- package/src/scripts/ai_council/compile_corpus.ts +1 -1
- package/src/scripts/audit_cloud_compatibility.ts +37 -2
- package/src/scripts/audit_initial_context.ts +53 -19
- package/src/scripts/audit_likelihood.ts +31 -2
- package/src/scripts/audit_user_type_axis.ts +58 -11
- package/src/scripts/bench_hook_latency.ts +172 -41
- package/src/scripts/build_mcp_catalog.ts +12 -1
- package/src/scripts/check_always_budget.ts +122 -11
- package/src/scripts/check_artefact_count_messaging.ts +128 -15
- package/src/scripts/check_augment_description_cap.ts +24 -3
- package/src/scripts/check_ci_strict_superset.ts +150 -0
- package/src/scripts/check_cluster_patterns.ts +100 -0
- package/src/scripts/check_consumer_scope_flip.ts +26 -4
- package/src/scripts/check_evaluator_budgets.ts +198 -19
- package/src/scripts/check_gate_coverage.ts +337 -1
- package/src/scripts/check_generator_output_coverage.ts +2 -1
- package/src/scripts/check_iron_law_prominence.ts +1 -1
- package/src/scripts/check_kernel_rule_bundle.ts +1 -1
- package/src/scripts/check_no_new_legacy_path.ts +167 -3
- package/src/scripts/check_pack_size.ts +18 -4
- package/src/scripts/check_portability.ts +37 -7
- package/src/scripts/check_references.ts +19 -3
- package/src/scripts/check_release_pr_shape.ts +13 -0
- package/src/scripts/check_token_regression.ts +9 -2
- package/src/scripts/condense.ts +155 -12
- package/src/scripts/cost/budget.mjs +63 -2
- package/src/scripts/count_scoped_projection.ts +104 -0
- package/src/scripts/evaluator_umbrella.sh +34 -1
- package/src/scripts/generate_capability_matrix.ts +8 -0
- package/src/scripts/generate_router_coverage_from_matrix.ts +155 -0
- package/src/scripts/hook_manifest.yaml +17 -3
- package/src/scripts/hooks/block_config_weakening.ts +337 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/probe_throttle.ts +75 -0
- package/src/scripts/install-hooks.sh +24 -2
- package/src/scripts/install.ts +15 -92
- package/src/scripts/lint_agents_md.ts +9 -3
- package/src/scripts/lint_archived_skills.ts +1 -1
- package/src/scripts/lint_artefact_frontmatter.ts +185 -37
- package/src/scripts/lint_command_routing.ts +21 -52
- package/src/scripts/lint_command_verbs.ts +47 -28
- package/src/scripts/lint_context_spine_usage.ts +38 -12
- package/src/scripts/lint_framework_leakage.ts +25 -6
- package/src/scripts/lint_handoffs.ts +49 -2
- package/src/scripts/lint_media_policy_linkage.ts +62 -30
- package/src/scripts/lint_namespace.ts +92 -7
- package/src/scripts/lint_new_skill_gate.ts +39 -31
- package/src/scripts/lint_originality_shingles.ts +7 -1
- package/src/scripts/lint_override_kernel_guard.ts +21 -3
- package/src/scripts/lint_pack_boundaries.ts +461 -91
- package/src/scripts/lint_pack_dependencies.ts +24 -57
- package/src/scripts/lint_persona_governance.ts +1 -1
- package/src/scripts/lint_role_experiences.ts +34 -5
- package/src/scripts/lint_trigger_precision.ts +142 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +12 -201
- package/src/scripts/mcp_server/tools.ts +1 -1
- package/src/scripts/prepack-check.mjs +40 -1
- package/src/scripts/prepack_router_targets.d.mts +7 -0
- package/src/scripts/prepack_router_targets.mjs +93 -0
- package/src/scripts/print_required_checks.ts +72 -18
- package/src/scripts/profile_staleness_hook.ts +12 -0
- package/src/scripts/record_evaluator_measurements.mjs +105 -0
- package/src/scripts/recruit_preflight.sh +1 -1
- package/src/scripts/release.ts +105 -1
- package/src/scripts/router_target_paths.d.mts +4 -0
- package/src/scripts/router_target_paths.mjs +69 -0
- package/src/scripts/router_telemetry.ts +52 -1
- package/src/scripts/routing_doctor.ts +485 -0
- package/src/scripts/rule_trigger_eval.ts +403 -0
- package/src/scripts/schemas/rule.schema.json +5 -1
- package/src/scripts/session_canary_hook.ts +96 -5
- package/src/scripts/skill_linter.ts +90 -42
- package/src/scripts/smoke/skills.sh +1 -1
- package/src/scripts/sweep_dead_scan_roots.ts +356 -10
- package/src/scripts/trigger_coverage.ts +13 -2
- package/src/scripts/update_counts.ts +91 -12
- package/src/scripts/validate_telegraph_carveouts.ts +1 -1
- package/src/scripts/wrapper_freshness_hook.ts +14 -0
- package/src/server/schemas/settings.ts +19 -5
- package/dist/cli-delegate/chunk-TJIAM5FW.js +0 -133
- package/dist/ui/assets/index-BpSQt5vm.js +0 -40
- package/dist/ui/assets/index-BpSQt5vm.js.map +0 -1
|
@@ -39,6 +39,8 @@ import process from 'node:process';
|
|
|
39
39
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
40
40
|
import { parse as parseYaml } from 'yaml';
|
|
41
41
|
|
|
42
|
+
import { keyword_matches_anchored } from './router_telemetry.js';
|
|
43
|
+
|
|
42
44
|
const _HERE = fileURLToPath(import.meta.url);
|
|
43
45
|
|
|
44
46
|
// src/scripts/trigger_coverage.ts → parents[2] of the .py file is repo root.
|
|
@@ -76,8 +78,17 @@ export function fired_rules(prompt: string, router: Router): Set<string> {
|
|
|
76
78
|
for (const tier of ['tier_1', 'tier_2'] as const) {
|
|
77
79
|
for (const entry of router[tier] ?? []) {
|
|
78
80
|
for (const trig of entry.triggers ?? []) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
// Single matcher source of truth (road-to-tested-routing
|
|
82
|
+
// Phase 3): `keyword` is word-boundary anchored via the
|
|
83
|
+
// shared helper; `phrase` stays unanchored substring.
|
|
84
|
+
if ('keyword' in trig) {
|
|
85
|
+
const needle = String(trig['keyword']).toLowerCase();
|
|
86
|
+
if (needle !== '' && keyword_matches_anchored(low, needle)) {
|
|
87
|
+
fired.add(entry.id);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
} else if ('phrase' in trig) {
|
|
91
|
+
const needle = String(trig['phrase']).toLowerCase();
|
|
81
92
|
if (needle !== '' && low.includes(needle)) {
|
|
82
93
|
fired.add(entry.id);
|
|
83
94
|
break;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Historical quirks are preserved deliberately — tests and downstream consumers pin the exact behaviour.
|
|
17
17
|
*
|
|
18
|
-
* Source of truth:
|
|
18
|
+
* Source of truth: `src/`.
|
|
19
19
|
*
|
|
20
20
|
* Target files have explicit regex patterns for each count mention — no fuzzy
|
|
21
21
|
* matching, no risk of touching unrelated numbers.
|
|
@@ -26,6 +26,8 @@ import process from 'node:process';
|
|
|
26
26
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
27
27
|
|
|
28
28
|
import { artefact_roots, iter_commands } from './_lib/agent_src.js';
|
|
29
|
+
import { scoped_projection_stats } from './_lib/scoped_projection.js';
|
|
30
|
+
import { canonical_counts } from './check_command_count_messaging.js';
|
|
29
31
|
|
|
30
32
|
const _HERE = fileURLToPath(import.meta.url);
|
|
31
33
|
// _HERE === <repo>/src/scripts/update_counts.ts ; the retired Python implementation derives
|
|
@@ -77,7 +79,48 @@ function _exists(p: string): boolean {
|
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Every `SKILL.md` the canonical `count('skills')` counts, as absolute paths.
|
|
84
|
+
*
|
|
85
|
+
* Exported so `count_scoped_projection.ts` partitions the SAME file set the
|
|
86
|
+
* ledger's total is derived from. That is what makes the published pair
|
|
87
|
+
* ("N of M skills") coherent by construction: `projected + pruned === M`
|
|
88
|
+
* cannot drift, because there is one walk, not two.
|
|
89
|
+
*/
|
|
90
|
+
export function* iter_skills(): Generator<string> {
|
|
91
|
+
const seen = new Set<string>();
|
|
92
|
+
for (const root of artefact_roots()) {
|
|
93
|
+
const subdir = path.join(root, 'skills');
|
|
94
|
+
if (!_exists(subdir)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
for (const f of _rglob(subdir, (n) => n === 'SKILL.md')) {
|
|
98
|
+
const rel = path.relative(root, f).split(path.sep).join('/');
|
|
99
|
+
if (seen.has(rel)) continue;
|
|
100
|
+
seen.add(rel);
|
|
101
|
+
yield f;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
80
106
|
export function count(kind: string): number {
|
|
107
|
+
if (kind === 'commands_active') {
|
|
108
|
+
// Commands MINUS deprecation shims — the number the hero badge and the
|
|
109
|
+
// "Browse all N active commands" line carry, and the one prose
|
|
110
|
+
// mentions resolve to. Distinct from `commands` (raw file count):
|
|
111
|
+
// they are equal only while the shim set is empty, so anchoring an
|
|
112
|
+
// active-count position to `commands` would rewrite it to the wrong
|
|
113
|
+
// number the moment a command is superseded.
|
|
114
|
+
const [, , active] = canonical_counts();
|
|
115
|
+
return active;
|
|
116
|
+
}
|
|
117
|
+
if (kind === 'skills_scoped') {
|
|
118
|
+
// Skills a DEFAULT `projection.mode: scoped` install deploys. Derived
|
|
119
|
+
// by the installer's own prune predicate over the same walk the
|
|
120
|
+
// canonical `skills` total uses, so the published pair
|
|
121
|
+
// ("N of M skills") cannot drift apart. See count_scoped_projection.ts.
|
|
122
|
+
return scoped_projection_stats(REPO_ROOT, iter_skills()).projected;
|
|
123
|
+
}
|
|
81
124
|
if (kind === 'router_rules') {
|
|
82
125
|
// Routed rule entries in the compiled router (kernel + tier_1 +
|
|
83
126
|
// tier_2). Read from dist/router.json — the artifact hosts consume —
|
|
@@ -119,19 +162,19 @@ export function count(kind: string): number {
|
|
|
119
162
|
}
|
|
120
163
|
return total;
|
|
121
164
|
}
|
|
165
|
+
if (kind === 'skills') {
|
|
166
|
+
// Single walk, shared with count_scoped_projection.ts — see iter_skills.
|
|
167
|
+
for (const _ of iter_skills()) {
|
|
168
|
+
total += 1;
|
|
169
|
+
}
|
|
170
|
+
return total;
|
|
171
|
+
}
|
|
122
172
|
for (const root of artefact_roots()) {
|
|
123
173
|
const subdir = path.join(root, kind);
|
|
124
174
|
if (!_exists(subdir)) {
|
|
125
175
|
continue;
|
|
126
176
|
}
|
|
127
|
-
if (kind === '
|
|
128
|
-
for (const f of _rglob(subdir, (n) => n === 'SKILL.md')) {
|
|
129
|
-
const rel = path.relative(root, f).split(path.sep).join('/');
|
|
130
|
-
if (seen.has(rel)) continue;
|
|
131
|
-
seen.add(rel);
|
|
132
|
-
total += 1;
|
|
133
|
-
}
|
|
134
|
-
} else if (kind === 'personas') {
|
|
177
|
+
if (kind === 'personas') {
|
|
135
178
|
// personas live as flat .md files, README excluded
|
|
136
179
|
for (const f of _glob(subdir, (n) => n.endsWith('.md'))) {
|
|
137
180
|
if (path.basename(f) === 'README.md') continue;
|
|
@@ -164,6 +207,12 @@ export const TARGETS: ReadonlyArray<[string, ReadonlyArray<[string, string]>]> =
|
|
|
164
207
|
// badge is owned by check_command_count_messaging.
|
|
165
208
|
['(/badge/Skills-)(\\d+)(-)', 'skills'],
|
|
166
209
|
['(/badge/Rules-)(\\d+)(-)', 'rules'],
|
|
210
|
+
// The Commands badge WAS left to check_command_count_messaging
|
|
211
|
+
// alone ("avoids double-ownership"). Nothing generated it, so it
|
|
212
|
+
// drifted to 191 against a canonical 192 and only the checker
|
|
213
|
+
// noticed — the exact gap this roadmap closes. Generator writes,
|
|
214
|
+
// checker verifies: that IS the ownership split, not a conflict.
|
|
215
|
+
['(/badge/Commands-)(\\d+)(-)', 'commands_active'],
|
|
167
216
|
['(/badge/Guidelines-)(\\d+)(-)', 'guidelines'],
|
|
168
217
|
['(/badge/Personas-)(\\d+)(-)', 'personas'],
|
|
169
218
|
],
|
|
@@ -177,8 +226,22 @@ export const TARGETS: ReadonlyArray<[string, ReadonlyArray<[string, string]>]> =
|
|
|
177
226
|
['(- claim: )(\\d+)( skills\\.)', 'skills'],
|
|
178
227
|
['(- claim: )(\\d+)( commands\\.)', 'commands'],
|
|
179
228
|
['(- claim: )(\\d+)( governed rules\\.)', 'rules'],
|
|
229
|
+
// The scoped-projection claim: BOTH halves of "N of M skills".
|
|
230
|
+
// `M` was scanner-checked but generator-blind (a maintainer
|
|
231
|
+
// hand-edited it on every skill addition); `N` was guarded by
|
|
232
|
+
// nothing at all and had drifted 2 from the benchmark doc the
|
|
233
|
+
// claim names as its own method.
|
|
234
|
+
['(installs ships )(\\d+)( of )', 'skills_scoped'],
|
|
235
|
+
['( of )(\\d+)( skills \\(untagged core)', 'skills'],
|
|
236
|
+
// "14 of 111 governed rules" — the total was scanner-checked and
|
|
237
|
+
// generator-blind for the same reason.
|
|
238
|
+
['( of )(\\d+)( governed rules \\()', 'rules'],
|
|
180
239
|
],
|
|
181
240
|
],
|
|
241
|
+
[
|
|
242
|
+
'docs/command-flows.md',
|
|
243
|
+
[['(\\*\\*)(\\d+)( commands\\*\\*)', 'commands_active']],
|
|
244
|
+
],
|
|
182
245
|
[
|
|
183
246
|
'docs/getting-started-by-role.md',
|
|
184
247
|
[
|
|
@@ -206,6 +269,11 @@ export const TARGETS: ReadonlyArray<[string, ReadonlyArray<[string, string]>]> =
|
|
|
206
269
|
'docs/getting-started.md',
|
|
207
270
|
[
|
|
208
271
|
['(automatically by )(\\d+)( rules)', 'rules'],
|
|
272
|
+
// Was deliberately unsynced to avoid double-ownership with
|
|
273
|
+
// check_command_count_messaging; it drifted to 191 as a result.
|
|
274
|
+
// Now generated from `commands_active` — the SAME canonical the
|
|
275
|
+
// checker compares against, so the two cannot disagree.
|
|
276
|
+
['(Browse all )(\\d+)( active commands)', 'commands_active'],
|
|
209
277
|
// NOTE: the "Browse all N active commands" line here carries the
|
|
210
278
|
// *active* command count and is owned by
|
|
211
279
|
// check_command_count_messaging.py — intentionally not synced
|
|
@@ -254,7 +322,16 @@ export function apply_to_text(
|
|
|
254
322
|
return [new_text, drifts];
|
|
255
323
|
}
|
|
256
324
|
|
|
257
|
-
const KINDS = [
|
|
325
|
+
const KINDS = [
|
|
326
|
+
'skills',
|
|
327
|
+
'skills_scoped',
|
|
328
|
+
'rules',
|
|
329
|
+
'commands',
|
|
330
|
+
'commands_active',
|
|
331
|
+
'guidelines',
|
|
332
|
+
'personas',
|
|
333
|
+
'router_rules',
|
|
334
|
+
] as const;
|
|
258
335
|
|
|
259
336
|
function parse_args(argv: readonly string[]): { check: boolean } {
|
|
260
337
|
const args = { check: false };
|
|
@@ -282,8 +359,10 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
|
282
359
|
counts[k] = count(k);
|
|
283
360
|
}
|
|
284
361
|
process.stdout.write(
|
|
285
|
-
`📊 Truth: skills=${counts['skills']}
|
|
286
|
-
`
|
|
362
|
+
`📊 Truth: skills=${counts['skills']} skills_scoped=${counts['skills_scoped']} ` +
|
|
363
|
+
`rules=${counts['rules']} commands=${counts['commands']} ` +
|
|
364
|
+
`commands_active=${counts['commands_active']} ` +
|
|
365
|
+
`guidelines=${counts['guidelines']} ` +
|
|
287
366
|
`personas=${counts['personas']} router_rules=${counts['router_rules']}\n`,
|
|
288
367
|
);
|
|
289
368
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* changes — historical quirks preserved (consumers pin the exact behaviour).
|
|
11
11
|
*
|
|
12
12
|
* Given a pre-condensation reply and a post-condensation reply, assert that
|
|
13
|
-
* every carve-out region from
|
|
13
|
+
* every carve-out region from `src/rules/telegraph-speak.md`
|
|
14
14
|
* § Carve-outs survived byte-for-byte:
|
|
15
15
|
*
|
|
16
16
|
* 1. Triple-backtick code blocks (any language).
|
|
@@ -39,6 +39,9 @@ import {
|
|
|
39
39
|
needs_refresh,
|
|
40
40
|
} from "./_lib/cli_wrapper.js";
|
|
41
41
|
import { readHookStdin } from "./hooks/hook_stdin.js";
|
|
42
|
+
import { probeRanToday, stampProbeRun } from "./hooks/probe_throttle.js";
|
|
43
|
+
|
|
44
|
+
const THROTTLE_CONCERN = "wrapper-freshness";
|
|
42
45
|
|
|
43
46
|
export const EXIT_ALLOW = 0;
|
|
44
47
|
|
|
@@ -202,6 +205,17 @@ export function main(argv?: string[]): number {
|
|
|
202
205
|
_readStdinIfNotTty();
|
|
203
206
|
|
|
204
207
|
const root = rootArg !== null ? rootArg : _project_root();
|
|
208
|
+
|
|
209
|
+
// Daily throttle (road-to-hook-latency-repair): a wrapper or pre-commit
|
|
210
|
+
// hook that was fresh this morning is still fresh this afternoon — one
|
|
211
|
+
// self-heal attempt per local calendar day. Skipped probe re-runs
|
|
212
|
+
// tomorrow; `agent-config upgrade` / `refresh --project` remain the
|
|
213
|
+
// immediate recovery paths.
|
|
214
|
+
if (probeRanToday(root, THROTTLE_CONCERN)) {
|
|
215
|
+
return EXIT_ALLOW;
|
|
216
|
+
}
|
|
217
|
+
stampProbeRun(root, THROTTLE_CONCERN);
|
|
218
|
+
|
|
205
219
|
let wrapper: string | null;
|
|
206
220
|
try {
|
|
207
221
|
if (_is_source_repo(root)) {
|
|
@@ -53,8 +53,8 @@ export const settingsSchema = z.object({
|
|
|
53
53
|
rule_workspaces: z.array(z.string()).default([]).describe(
|
|
54
54
|
'Workspace scope for the RULE layer only (road-to-request-scoped-rule-load P1/P1b, opt-in). Absent or empty = legacy-all: every rule projects AND installs. Non-empty = only rules whose workspaces frontmatter intersects this list are projected (condense) and installed (install.sh + global wizard payload). Kernel rules always ship; untagged rules fail safe. The default flip to a scoped value is a HUMAN release gate — do not set this from automation.',
|
|
55
55
|
),
|
|
56
|
-
rule_packs: z.array(z.string()).default([]).describe(
|
|
57
|
-
'Optional second scoping axis for the RULE layer, per pack ids (src/config/discovery/packs.yml). When set, a non-kernel rule also needs a packs frontmatter intersection to ship — e.g. deselecting frontend-design drops ui-audit-gate + design-fidelity. Same opt-in / human-gate semantics as rule_workspaces.',
|
|
56
|
+
rule_packs: z.union([z.literal('auto'), z.array(z.string())]).default([]).describe(
|
|
57
|
+
'Optional second scoping axis for the RULE layer, per pack ids (src/config/discovery/packs.yml). When set, a non-kernel rule also needs a packs frontmatter intersection to ship — e.g. deselecting frontend-design drops ui-audit-gate + design-fidelity. Same opt-in / human-gate semantics as rule_workspaces. The literal "auto" derives the id list from the active-pack set (the same set the skill/command prune uses), so a domain safety floor stops shipping into installs that do not have the pack it guards; an explicit list stays supported and wins over the derivation.',
|
|
58
58
|
),
|
|
59
59
|
}).default({ mode: 'legacy-all' }),
|
|
60
60
|
rule_loading_tier: ruleLoadingTier.default('balanced').describe(
|
|
@@ -79,6 +79,17 @@ export const settingsSchema = z.object({
|
|
|
79
79
|
monthly: z.number().min(0).default(0).describe(
|
|
80
80
|
'Calendar-month USD ceiling. Pairs with cost.enforcement = hard-stop for a hard cap on agent spend before the next billing cycle. Set 0 to disable.',
|
|
81
81
|
),
|
|
82
|
+
per_tier: z.object({
|
|
83
|
+
cheap: z.number().min(0).nullable().default(null).describe(
|
|
84
|
+
'USD ceiling for the cheap model tier under budget-aware delegation (docs/contracts/budget-routing.md). null = no separate tier cap; global ceilings still apply.',
|
|
85
|
+
),
|
|
86
|
+
medium: z.number().min(0).nullable().default(null).describe(
|
|
87
|
+
'USD ceiling for the medium model tier. null = no separate tier cap.',
|
|
88
|
+
),
|
|
89
|
+
strong: z.number().min(0).nullable().default(null).describe(
|
|
90
|
+
'USD ceiling for the strong model tier. null = no separate tier cap — with cheap exhausted and strong funded, budget routing uses the strong tier rather than blocking work.',
|
|
91
|
+
),
|
|
92
|
+
}).default({ cheap: null, medium: null, strong: null }),
|
|
82
93
|
}),
|
|
83
94
|
enforcement: enforcementMode.default('advisory').describe(
|
|
84
95
|
'What happens when a budget hits 100%. advisory = show a banner, keep working (default — never blocks an active task). hard-stop = refuse further model calls until the budget resets or you raise the ceiling.',
|
|
@@ -103,7 +114,7 @@ export const settingsSchema = z.object({
|
|
|
103
114
|
'Prefer short bullets and tables (true, default) vs verbose prose with rationale (false). Affects every chat reply; flip to false during debugging when you want the agent to think out loud.',
|
|
104
115
|
),
|
|
105
116
|
canary_name: z.string().default('').describe(
|
|
106
|
-
'Session canary — the name the agent addresses you with at the start of every new task (e.g. "Alex"). When the greeting silently disappears, the context window is degrading: start a fresh conversation. Also keeps the reply-close markers (end-summary, PR URL as literal last line) alive. Empty = off. See rules/session-canary.md.',
|
|
117
|
+
'Session canary — the name the agent addresses you with at the start of every new task (e.g. "Alex"). When the greeting silently disappears, the context window is degrading: start a fresh conversation. Also keeps the reply-close markers (end-summary, PR URL as literal last line) alive. Empty = fall back to the user-global canary_name, then to identity.name from the setup wizard; no name anywhere = off. See rules/session-canary.md.',
|
|
107
118
|
),
|
|
108
119
|
play_by_play: z.boolean().default(false).describe(
|
|
109
120
|
'Narrate intermediate findings between tool calls ("Found it.", "Let me check Y."). Off by default — most users find it noisy. Turn on when you want to follow the agent\'s reasoning step by step.',
|
|
@@ -187,8 +198,8 @@ export const settingsSchema = z.object({
|
|
|
187
198
|
quality_cadence: qualityCadence.default('end_of_roadmap').describe(
|
|
188
199
|
'When the agent runs the full quality / test suite during /roadmap:process-* runs. end_of_roadmap = once, after the last step (fastest, default). per_phase = after each phase boundary. per_step = after every single step (slowest, highest confidence).',
|
|
189
200
|
),
|
|
190
|
-
dashboard_regen_cadence: regenCadence.default('
|
|
191
|
-
'How often the agent regenerates agents/roadmaps/dashboard.md during a roadmap run. per_step = after every step (
|
|
201
|
+
dashboard_regen_cadence: regenCadence.default('every_5_steps').describe(
|
|
202
|
+
'How often the agent regenerates agents/roadmaps/dashboard.md during a roadmap run. every_5_steps = batch the regen (default). per_step = after every step (freshest dashboard, highest subprocess overhead). phase_boundary = only at phase edges. A rename, phase add, or archive always regenerates immediately regardless.',
|
|
192
203
|
),
|
|
193
204
|
horizon_weeks: z.number().int().min(0).default(0).describe(
|
|
194
205
|
'Optional planning horizon (weeks) the agent shows in roadmap framing ("next 4 weeks"). Set 0 to omit the horizon — most teams prefer to ship without a hardcoded window.',
|
|
@@ -288,6 +299,9 @@ export const settingsSchema = z.object({
|
|
|
288
299
|
downshift: z.boolean().default(true).describe(
|
|
289
300
|
'Route delegable sub-tasks to the lowest-capable model tier (cost + speed via model downshift). false = every subagent runs on the session tier.',
|
|
290
301
|
),
|
|
302
|
+
budget_routing: z.enum(['ask', 'auto', 'off']).default('ask').describe(
|
|
303
|
+
'Budget-aware cheap-request delegation (docs/contracts/budget-routing.md): pick the cheapest classifier-adequate tier WITH available budget (cost.budgets.per_tier); cheap exhausted but strong funded → strong tier; all exhausted → session model + notice. Work is never blocked to save money; the session model is never switched (delegation with a model override). ask = confirm the first budget-motivated downshift per session (default). auto = apply silently with telemetry. off = today\'s behavior (single-flip rollback). Distinct from downshift: that is the quality/cost knob, this is the resource-availability gate.',
|
|
304
|
+
),
|
|
291
305
|
quota_arbitrage: z.boolean().default(true).describe(
|
|
292
306
|
'Prefer a separate quota-pool model for delegable sub-tasks where the host manifest reports one. Optional bonus only — identical behaviour (minus the quota win) where unsupported. Never load-bearing.',
|
|
293
307
|
),
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
require_dist
|
|
4
|
-
} from "./chunk-OY53J6II.js";
|
|
5
|
-
import {
|
|
6
|
-
__toESM
|
|
7
|
-
} from "./chunk-J55WI3RR.js";
|
|
8
|
-
|
|
9
|
-
// src/install/rule_scope.ts
|
|
10
|
-
import * as fs2 from "node:fs";
|
|
11
|
-
import * as path from "node:path";
|
|
12
|
-
|
|
13
|
-
// src/install/ruleInScope.ts
|
|
14
|
-
var YAML = __toESM(require_dist(), 1);
|
|
15
|
-
import * as fs from "node:fs";
|
|
16
|
-
function parseYaml(text) {
|
|
17
|
-
try {
|
|
18
|
-
const data = YAML.parse(text, { version: "1.1" });
|
|
19
|
-
return data === void 0 ? null : data;
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function strip(s) {
|
|
25
|
-
return s.replace(/^\s+/u, "").replace(/\s+$/u, "");
|
|
26
|
-
}
|
|
27
|
-
function lstripNewlines(s) {
|
|
28
|
-
return s.replace(/^\n+/, "");
|
|
29
|
-
}
|
|
30
|
-
function parseFrontmatter(content) {
|
|
31
|
-
if (!content.startsWith("---")) {
|
|
32
|
-
return [{}, content];
|
|
33
|
-
}
|
|
34
|
-
const end = content.indexOf("\n---", 3);
|
|
35
|
-
if (end === -1) {
|
|
36
|
-
return [{}, content];
|
|
37
|
-
}
|
|
38
|
-
const raw = strip(content.slice(3, end));
|
|
39
|
-
const body = lstripNewlines(content.slice(end + 4));
|
|
40
|
-
let meta = parseYaml(raw);
|
|
41
|
-
if (meta === null || meta === void 0) {
|
|
42
|
-
meta = {};
|
|
43
|
-
}
|
|
44
|
-
if (typeof meta === "object" && meta !== null && !Array.isArray(meta)) {
|
|
45
|
-
return [meta, body];
|
|
46
|
-
}
|
|
47
|
-
return [{}, body];
|
|
48
|
-
}
|
|
49
|
-
function rule_in_scope(source_path, scope, pack_scope = null, role_scope = null) {
|
|
50
|
-
if (scope === null && pack_scope === null && role_scope === null) {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
const [meta] = parseFrontmatter(fs.readFileSync(source_path, "utf-8"));
|
|
54
|
-
if (meta["type"] === "always" || meta["alwaysApply"] === true) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
const axis = (key, configured) => {
|
|
58
|
-
if (configured === null) {
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
const values = Array.isArray(meta[key]) ? meta[key].map((w) => String(w)) : [];
|
|
62
|
-
if (values.length === 0) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
return values.some((v) => configured.includes(v));
|
|
66
|
-
};
|
|
67
|
-
return axis("workspaces", scope) && axis("packs", pack_scope) && axis("roles", role_scope);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// src/install/rule_scope.ts
|
|
71
|
-
var COMPAT_ALWAYS_EXCLUDED = ["source-of-truth.md"];
|
|
72
|
-
var LEGACY_ALL = { workspaces: null, packs: null };
|
|
73
|
-
function _list(value) {
|
|
74
|
-
if (Array.isArray(value) && value.length > 0) {
|
|
75
|
-
return value.map((v) => String(v));
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
function ruleScopeFromSettings(settings) {
|
|
80
|
-
const proj = settings["projection"];
|
|
81
|
-
if (typeof proj !== "object" || proj === null || Array.isArray(proj)) {
|
|
82
|
-
return LEGACY_ALL;
|
|
83
|
-
}
|
|
84
|
-
const p = proj;
|
|
85
|
-
return {
|
|
86
|
-
workspaces: _list(p["rule_workspaces"]),
|
|
87
|
-
packs: _list(p["rule_packs"]),
|
|
88
|
-
roles: _list(p["rule_roles"])
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function ruleFileArrives(sourcePath, scope) {
|
|
92
|
-
if (!sourcePath.endsWith(".md")) {
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
const basename2 = path.basename(sourcePath);
|
|
96
|
-
if (COMPAT_ALWAYS_EXCLUDED.includes(basename2)) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
return rule_in_scope(sourcePath, scope.workspaces, scope.packs, scope.roles ?? null);
|
|
100
|
-
}
|
|
101
|
-
function excludedRuleBasenames(rulesDir, scope) {
|
|
102
|
-
let entries;
|
|
103
|
-
try {
|
|
104
|
-
entries = fs2.readdirSync(rulesDir).sort();
|
|
105
|
-
} catch {
|
|
106
|
-
return [];
|
|
107
|
-
}
|
|
108
|
-
const out = [];
|
|
109
|
-
for (const name of entries) {
|
|
110
|
-
if (!name.endsWith(".md")) {
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
const full = path.join(rulesDir, name);
|
|
114
|
-
try {
|
|
115
|
-
if (!fs2.statSync(full).isFile()) {
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
} catch {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (!ruleFileArrives(full, scope)) {
|
|
122
|
-
out.push(name);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return out;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export {
|
|
129
|
-
LEGACY_ALL,
|
|
130
|
-
ruleScopeFromSettings,
|
|
131
|
-
ruleFileArrives,
|
|
132
|
-
excludedRuleBasenames
|
|
133
|
-
};
|