@event4u/agent-config 12.0.0 → 13.0.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 +273 -0
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +46 -3
- package/dist/agent-src/commands/cost/report.md +23 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +148 -33
- package/dist/agent-src/contexts/model-recommendations.md +6 -4
- package/dist/agent-src/contexts/subagent-configuration.md +69 -7
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/design-review-after-ui-write.md +10 -5
- package/dist/agent-src/rules/evaluator-independence.md +27 -5
- package/dist/agent-src/rules/git-history-discipline.md +5 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/missing-skill-recovery.md +89 -0
- package/dist/agent-src/rules/ui-audit-gate.md +9 -4
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
- package/dist/agent-src/scripts/roadmap_gates.ts +30 -2
- package/dist/agent-src/scripts/update_roadmap_progress.ts +47 -1
- package/dist/agent-src/skills/authz-review/SKILL.md +4 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +4 -0
- package/dist/agent-src/skills/design-system-capture/references/snapshot-preference-order.md +77 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +4 -0
- package/dist/agent-src/skills/prompt-optimizer/SKILL.md +17 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +11 -11
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +4 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +3 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +41 -3
- package/dist/cli/registry.js +1 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-NN4KW4HZ.js → chunk-3B72LSZL.js} +123 -2338
- package/dist/cli-delegate/{chunk-55WZN5VF.js → chunk-EVTY7ISR.js} +2 -2
- package/dist/cli-delegate/chunk-N7FEST6D.js +3895 -0
- package/dist/cli-delegate/{chunk-L565YFXH.js → chunk-XURJ4AQC.js} +566 -298
- package/dist/cli-delegate/cmd_conformance.js +4 -4
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +44 -23
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +10625 -8541
- package/dist/install/install.mjs +754 -484
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1302 -167
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/model_tier.js +9 -0
- package/dist/scripts/_lib/model_tier.js.map +1 -1
- package/dist/scripts/condense.js +50 -0
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +2 -2
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/MIGRATION.md +20 -1
- package/docs/guidelines/design-fidelity-mechanics.md +21 -0
- package/docs/guidelines/design-handover-extraction.md +87 -0
- package/docs/guidelines/prompt-templates.md +24 -1
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
- package/src/agent-src/scripts/roadmap_gates.ts +30 -2
- package/src/agent-src/scripts/update_roadmap_progress.ts +47 -1
- package/src/config/evaluator-budgets.json +9 -8
- package/src/config/gate-coverage.yml +63 -11
- package/src/config/gate-violation-baselines.json +12 -0
- package/src/config/hook-token-budget.json +15 -2
- package/src/config/preamble-payload-budget.json +28 -0
- package/src/scripts/_dispatch.bash +10 -0
- package/src/scripts/_lib/bench_ab_complexity.ts +439 -0
- package/src/scripts/_lib/bench_ab_safety_tier.ts +142 -0
- package/src/scripts/_lib/bench_ab_scoring_v2.ts +28 -3
- package/src/scripts/_lib/bench_ab_search_adherence.ts +423 -0
- package/src/scripts/_lib/bench_ab_size_claim.ts +206 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +111 -0
- package/src/scripts/_lib/git_common_dir.ts +173 -0
- package/src/scripts/_lib/model_tier.ts +9 -0
- package/src/scripts/_lib/release_highlights.ts +108 -7
- package/src/scripts/_lib/skill_catalogue.ts +1115 -0
- package/src/scripts/_lib/tier_budget_routing.ts +31 -331
- package/src/scripts/ai_council/clients.ts +197 -18
- package/src/scripts/ai_council/config.ts +16 -1
- package/src/scripts/ai_council/low_impact.ts +14 -1
- package/src/scripts/ai_council/orchestrator.ts +14 -1
- package/src/scripts/ai_council/transport_resolver.ts +32 -2
- package/src/scripts/bench_ab_v2_complexity.ts +252 -0
- package/src/scripts/bench_ab_v2_run.ts +3 -42
- package/src/scripts/bench_ab_v2_safety.ts +296 -0
- package/src/scripts/bench_ab_v2_search.ts +343 -0
- package/src/scripts/bench_ab_v2_stats.ts +191 -0
- package/src/scripts/build_archive_index.ts +383 -0
- package/src/scripts/capture_skill_catalogue.ts +279 -317
- package/src/scripts/check_branch_freshness.ts +7 -1
- package/src/scripts/check_release_published.ts +6 -2
- package/src/scripts/check_release_trunk_sync.ts +18 -2
- package/src/scripts/check_source_size_budget.ts +428 -0
- package/src/scripts/check_suppression_hygiene.ts +5 -1
- package/src/scripts/condense.ts +50 -1
- package/src/scripts/cost/backfill_rates.mjs +298 -0
- package/src/scripts/cost/budget.mjs +12 -32
- package/src/scripts/cost_summary.ts +25 -0
- package/src/scripts/dispatch_r2_reviewer.ts +15 -5
- package/src/scripts/evidence_report.ts +15 -4
- package/src/scripts/external_sources_denylist.json +1 -0
- package/src/scripts/hook_manifest.yaml +75 -15
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +21 -0
- package/src/scripts/hooks/skill_route_hook.ts +226 -0
- package/src/scripts/hooks/tool_result_bytes_hook.ts +219 -0
- package/src/scripts/hooks/ui_route_nudge_hook.ts +6 -3
- package/src/scripts/hot_context_hook.ts +13 -1
- package/src/scripts/install.ts +129 -0
- package/src/scripts/janitor.ts +77 -2
- package/src/scripts/lint_design_antipattern_parity.ts +40 -6
- package/src/scripts/lint_harvest_provenance.ts +35 -1
- package/src/scripts/lint_plan_risk_register.ts +22 -9
- package/src/scripts/lint_roadmap_blockers.ts +109 -6
- package/src/scripts/lint_rule_skill_pack_reach.ts +43 -0
- package/src/scripts/lint_scheduled_deprecations.ts +738 -0
- package/src/scripts/lint_skill_router_head.ts +21 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +26 -3
- package/src/scripts/mcp_server/tool_catalog_source.ts +6 -24
- package/src/scripts/mcp_server/tools.ts +87 -0
- package/src/scripts/migration_status.ts +17 -1
- package/src/scripts/probe_review_binding_drift.ts +731 -0
- package/src/scripts/release.ts +100 -6
- package/src/scripts/routing_doctor.ts +50 -13
- package/src/scripts/schemas/command.schema.json +3 -3
- package/src/scripts/schemas/skill.schema.json +20 -2
- package/src/scripts/schemas/subagent.schema.json +2 -2
- package/src/scripts/session_eol_report.ts +81 -0
- package/src/scripts/trigger_coverage.ts +224 -3
- package/src/scripts/workspace_doctor.ts +464 -0
- package/src/scripts/worktree_cleanup_check.ts +2 -1
- package/src/server/schemas/settings.ts +2 -2
- package/dist/cli-delegate/chunk-AYKQGIBG.js +0 -1594
- package/src/config/budget-routing.json +0 -7
|
@@ -38,6 +38,7 @@ import * as fs from 'node:fs';
|
|
|
38
38
|
import * as path from 'node:path';
|
|
39
39
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
40
40
|
|
|
41
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
41
42
|
import { assertWatchlistResolves, DeadScopeError } from './_lib/scan_scope.js';
|
|
42
43
|
|
|
43
44
|
const _FILE = fileURLToPath(import.meta.url);
|
|
@@ -204,6 +205,26 @@ export function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
204
205
|
const heads = collectSkillHeads(path.join(REPO, SKILLS_REL));
|
|
205
206
|
const { findings, staleAllowlist } = evaluate(heads);
|
|
206
207
|
|
|
208
|
+
// Per-target completeness accounting. The interesting outcome here is the
|
|
209
|
+
// SKIP: a grandfathered head is over the cap and deliberately unchecked, so
|
|
210
|
+
// without a ledger it was indistinguishable from a head that passed. The
|
|
211
|
+
// allowlist size is already printed, but only the ledger ties each skipped
|
|
212
|
+
// name to the reason it went unchecked.
|
|
213
|
+
const ledger = new GateLedger('lint_skill_router_head');
|
|
214
|
+
ledger.plan(heads.map((h) => h.name));
|
|
215
|
+
const failed = new Set(findings.map((f) => f.skill));
|
|
216
|
+
const allow = new Set(GRANDFATHERED);
|
|
217
|
+
for (const h of heads) {
|
|
218
|
+
if (failed.has(h.name)) {
|
|
219
|
+
ledger.fail(h.name, `${String(h.lines)} lines over the ${String(MAX_HEAD_LINES)}-line cap with no mode bodies`);
|
|
220
|
+
} else if (h.lines > MAX_HEAD_LINES && allow.has(h.name)) {
|
|
221
|
+
ledger.skip(h.name, 'declared_exemption');
|
|
222
|
+
} else {
|
|
223
|
+
ledger.complete(h.name);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
ledger.report();
|
|
227
|
+
|
|
207
228
|
for (const s of staleAllowlist) {
|
|
208
229
|
process.stderr.write(
|
|
209
230
|
`⚠️ lint_skill_router_head: '${s}' is grandfathered but no longer over the cap — remove it from GRANDFATHERED so the ratchet keeps its teeth\n`,
|
|
@@ -544,10 +544,33 @@
|
|
|
544
544
|
},
|
|
545
545
|
{
|
|
546
546
|
"name": "suggest_skill_for_task",
|
|
547
|
-
"description": "
|
|
547
|
+
"description": "Match a free-form task description to the most relevant skills, ranked by a deterministic keyword scorer over SKILL.md frontmatter. Use when a skill you need is not in the catalogue the host delivered — a measured host dropped 402 entries from its model-visible list — so asking by name is impossible while asking by task is not. Read-only: no shell, no writes, and no skill bodies are returned, only names, scores and declared personas.",
|
|
548
548
|
"side_effect": "ro",
|
|
549
|
-
"implemented_on": [
|
|
550
|
-
|
|
549
|
+
"implemented_on": [
|
|
550
|
+
"stdio"
|
|
551
|
+
],
|
|
552
|
+
"input_schema": {
|
|
553
|
+
"type": "object",
|
|
554
|
+
"required": [
|
|
555
|
+
"task"
|
|
556
|
+
],
|
|
557
|
+
"properties": {
|
|
558
|
+
"task": {
|
|
559
|
+
"type": "string",
|
|
560
|
+
"description": "Free-form description of the task to match skills against."
|
|
561
|
+
},
|
|
562
|
+
"limit": {
|
|
563
|
+
"type": "integer",
|
|
564
|
+
"minimum": 1,
|
|
565
|
+
"default": 5,
|
|
566
|
+
"description": "Maximum number of skills to return. Defaults to 5."
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
"additionalProperties": false
|
|
570
|
+
},
|
|
571
|
+
"annotations": {
|
|
572
|
+
"readOnlyHint": true
|
|
573
|
+
}
|
|
551
574
|
},
|
|
552
575
|
{
|
|
553
576
|
"name": "sync_agent_settings",
|
|
@@ -96,30 +96,12 @@ export const STUB_TOOLS: readonly StubToolSource[] = [
|
|
|
96
96
|
additionalProperties: false,
|
|
97
97
|
},
|
|
98
98
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
'Returns a ranked list of skills with name, description, and ' +
|
|
106
|
-
'match reason.',
|
|
107
|
-
side_effect: 'ro',
|
|
108
|
-
input_schema: {
|
|
109
|
-
type: 'object',
|
|
110
|
-
properties: {
|
|
111
|
-
task: { type: 'string', description: 'Free-form description of the task to find a skill for.' },
|
|
112
|
-
limit: {
|
|
113
|
-
type: 'integer',
|
|
114
|
-
minimum: 1,
|
|
115
|
-
default: 5,
|
|
116
|
-
description: 'Maximum number of skills to return. Defaults to 5.',
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
required: ['task'],
|
|
120
|
-
additionalProperties: false,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
99
|
+
// `suggest_skill_for_task` moved to ALLOWLIST in mcp_server/tools.ts
|
|
100
|
+
// (road-to-inbox-harvest-2026-08-d-runtime-skill-routing 4.1) — it is
|
|
101
|
+
// implemented now, and `build_mcp_catalog` refuses a name registered in
|
|
102
|
+
// both places. Its published input schema (`task` + `limit`) was carried
|
|
103
|
+
// over verbatim rather than re-designed: the stub is a contract consumers
|
|
104
|
+
// may already have read.
|
|
123
105
|
{
|
|
124
106
|
name: 'mine_session',
|
|
125
107
|
description:
|
|
@@ -1210,7 +1210,94 @@ async function _readResourceBodyHandler(
|
|
|
1210
1210
|
// unlisted tool. Boot-time stderr log enumerates the registered set.
|
|
1211
1211
|
// ---------------------------------------------------------------------
|
|
1212
1212
|
|
|
1213
|
+
/**
|
|
1214
|
+
* `suggest_skill_for_task` — the recovery path for a truncated catalogue.
|
|
1215
|
+
*
|
|
1216
|
+
* Promoted from a discovery stub because the defect it answers is measured, not
|
|
1217
|
+
* hypothetical: on the one host that publishes its own truncation, a default
|
|
1218
|
+
* install had 402 entries dropped from the model-visible skills list — the
|
|
1219
|
+
* host's own count against its own denominator, not a subtraction over ours
|
|
1220
|
+
* (`agents/evidence/analysis/scoped-projection-host-delivery.md`). An agent
|
|
1221
|
+
* that cannot see a skill also cannot ask for it by name, so the only reachable
|
|
1222
|
+
* question is "what fits this task" — which is what the deterministic ranker
|
|
1223
|
+
* answers, over the TREE rather than over the host's catalogue.
|
|
1224
|
+
*
|
|
1225
|
+
* Read-only and shell-free by construction: it reads SKILL.md frontmatter and
|
|
1226
|
+
* returns names, scores and declared personas. No skill BODY is returned — the
|
|
1227
|
+
* caller opens what it picked, so a wrong rank costs one read rather than a
|
|
1228
|
+
* context payload.
|
|
1229
|
+
*/
|
|
1230
|
+
async function _suggestSkillForTaskHandler(
|
|
1231
|
+
args: Record<string, unknown>,
|
|
1232
|
+
consumerRoot: string,
|
|
1233
|
+
): Promise<Record<string, unknown>> {
|
|
1234
|
+
const task = typeof args['task'] === 'string' ? args['task'] : '';
|
|
1235
|
+
if (task.trim() === '') {
|
|
1236
|
+
return { status: 'error', error: 'task must be a non-empty string', suggestions: [] };
|
|
1237
|
+
}
|
|
1238
|
+
// `limit`, not `top` — the stub published `limit` and a consumer may have
|
|
1239
|
+
// read that contract already. Renaming it on promotion would break a
|
|
1240
|
+
// caller for cosmetic reasons.
|
|
1241
|
+
const limitRaw = args['limit'];
|
|
1242
|
+
const limit =
|
|
1243
|
+
typeof limitRaw === 'number' && Number.isFinite(limitRaw) ? Math.floor(limitRaw) : 5;
|
|
1244
|
+
|
|
1245
|
+
const catalogue = await import('../_lib/skill_catalogue.js');
|
|
1246
|
+
const skillsDir = catalogue.resolveSkillsRoot(consumerRoot);
|
|
1247
|
+
if (skillsDir === null) {
|
|
1248
|
+
// A missing catalogue is UNKNOWN, never "no skill fits this task". The
|
|
1249
|
+
// second reads as a ranked answer and would be a confident empty list —
|
|
1250
|
+
// the same zero-from-silence failure `capture_skill_catalogue` refuses.
|
|
1251
|
+
return {
|
|
1252
|
+
status: 'no_catalogue',
|
|
1253
|
+
searched: [...catalogue.DEFAULT_CATALOGUE_ROOTS],
|
|
1254
|
+
consumer_root: consumerRoot,
|
|
1255
|
+
suggestions: [],
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
const { rank } = await import('../skill_tools/score_skill_relevance.js');
|
|
1260
|
+
const rows = rank(task, skillsDir).slice(0, Math.max(1, limit));
|
|
1261
|
+
return {
|
|
1262
|
+
status: 'ok',
|
|
1263
|
+
skills_root: skillsDir,
|
|
1264
|
+
suggestions: rows.map(([name, score, personas]) => ({ skill: name, score, personas })),
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1213
1268
|
export const ALLOWLIST: Record<string, BuiltinTool> = {
|
|
1269
|
+
suggest_skill_for_task: {
|
|
1270
|
+
name: 'suggest_skill_for_task',
|
|
1271
|
+
side_effect: 'ro',
|
|
1272
|
+
description:
|
|
1273
|
+
'Match a free-form task description to the most relevant skills, ' +
|
|
1274
|
+
'ranked by a deterministic keyword scorer over SKILL.md ' +
|
|
1275
|
+
'frontmatter. Use when a skill you need is not in the catalogue ' +
|
|
1276
|
+
'the host delivered — a measured host dropped 402 entries from ' +
|
|
1277
|
+
'its model-visible list — so asking by name is impossible while ' +
|
|
1278
|
+
'asking by task is not. ' +
|
|
1279
|
+
'Read-only: no shell, no writes, and no skill bodies are returned, ' +
|
|
1280
|
+
'only names, scores and declared personas.',
|
|
1281
|
+
input_schema: {
|
|
1282
|
+
type: 'object',
|
|
1283
|
+
required: ['task'],
|
|
1284
|
+
properties: {
|
|
1285
|
+
task: {
|
|
1286
|
+
type: 'string',
|
|
1287
|
+
description:
|
|
1288
|
+
'Free-form description of the task to match skills against.',
|
|
1289
|
+
},
|
|
1290
|
+
limit: {
|
|
1291
|
+
type: 'integer',
|
|
1292
|
+
minimum: 1,
|
|
1293
|
+
default: 5,
|
|
1294
|
+
description: 'Maximum number of skills to return. Defaults to 5.',
|
|
1295
|
+
},
|
|
1296
|
+
},
|
|
1297
|
+
additionalProperties: false,
|
|
1298
|
+
},
|
|
1299
|
+
handler: _suggestSkillForTaskHandler,
|
|
1300
|
+
},
|
|
1214
1301
|
lint_skills: {
|
|
1215
1302
|
name: 'lint_skills',
|
|
1216
1303
|
side_effect: 'ro',
|
|
@@ -21,6 +21,8 @@ import { dirname, resolve } from 'node:path';
|
|
|
21
21
|
import process from 'node:process';
|
|
22
22
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
23
23
|
|
|
24
|
+
import { workspaceIdentity } from './_lib/git_common_dir.js';
|
|
25
|
+
|
|
24
26
|
// ---------------------------------------------------------------------------
|
|
25
27
|
// Categories and phase mapping
|
|
26
28
|
// ---------------------------------------------------------------------------
|
|
@@ -157,8 +159,22 @@ function git(args: readonly string[], cwd: string): string {
|
|
|
157
159
|
return execFileSync('git', [...args], { cwd, encoding: 'utf-8' }).trim();
|
|
158
160
|
}
|
|
159
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Census row R8 — the tree's only exported `repoRoot()`, which is why nothing
|
|
164
|
+
* imports it: it lives in a report script.
|
|
165
|
+
*
|
|
166
|
+
* It used to spawn `rev-parse --show-toplevel` with no env scrub, so an
|
|
167
|
+
* inherited `GIT_DIR` answered about the hook's repository, and it threw an
|
|
168
|
+
* `execFileSync` error outside a repo. The throw is preserved deliberately —
|
|
169
|
+
* every caller here treats a missing root as fatal — but it is now a message
|
|
170
|
+
* that names the reason instead of a git subprocess failure.
|
|
171
|
+
*/
|
|
160
172
|
export function repoRoot(): string {
|
|
161
|
-
|
|
173
|
+
const root = workspaceIdentity(process.cwd()).repoRoot;
|
|
174
|
+
if (!root.resolved) {
|
|
175
|
+
throw new Error(`cannot resolve repo root: ${root.reason}`);
|
|
176
|
+
}
|
|
177
|
+
return root.value;
|
|
162
178
|
}
|
|
163
179
|
|
|
164
180
|
export function trackedPythonFiles(root: string): string[] {
|