@event4u/agent-config 9.24.0 → 9.25.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 (47) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +49 -0
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/conformance.md +182 -0
  5. package/dist/agent-src/commands/analyze/inbox.md +33 -2
  6. package/dist/agent-src/rules/decision-revisit-gate.md +2 -0
  7. package/dist/agent-src/rules/evaluator-independence.md +105 -0
  8. package/dist/agent-src/rules/session-canary.md +13 -1
  9. package/dist/agent-src/rules/user-interaction.md +22 -0
  10. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +1 -1
  11. package/dist/agent-src/skills/rule-writing/SKILL.md +45 -0
  12. package/dist/agent-src/skills/skill-writing/SKILL.md +114 -0
  13. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  14. package/dist/cli/registry.js +1 -0
  15. package/dist/cli/registry.js.map +1 -1
  16. package/dist/discovery/deprecation-report.md +1 -1
  17. package/dist/discovery/discovery-manifest.json +65 -18
  18. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  19. package/dist/discovery/discovery-manifest.summary.md +4 -4
  20. package/dist/discovery/orphan-report.md +1 -1
  21. package/dist/discovery/packs.json +10 -8
  22. package/dist/discovery/trust-report.md +3 -3
  23. package/dist/discovery/workspaces.json +8 -6
  24. package/dist/hooks/dispatch.js +1026 -328
  25. package/dist/mcp/registry-manifest.json +2 -2
  26. package/dist/mcp/server.json +2 -2
  27. package/dist/router.json +1 -1
  28. package/package.json +1 -1
  29. package/src/config/evaluator-budgets.json +68 -68
  30. package/src/config/gate-coverage.yml +103 -5
  31. package/src/config/gate-violation-baselines.json +11 -6
  32. package/src/scripts/_dispatch.bash +12 -0
  33. package/src/scripts/before_complete_hook.ts +127 -5
  34. package/src/scripts/check_depth_budget.ts +295 -0
  35. package/src/scripts/conformance_scan.ts +392 -0
  36. package/src/scripts/git_authorization_hook.ts +263 -0
  37. package/src/scripts/hook_manifest.yaml +50 -9
  38. package/src/scripts/hooks/block_unauthorized_git.ts +254 -0
  39. package/src/scripts/hooks/concern_registry.ts +8 -0
  40. package/src/scripts/hooks/evidence_independence.ts +334 -0
  41. package/src/scripts/language_mirror_hook.ts +267 -0
  42. package/src/scripts/lint_decision_impact.ts +246 -0
  43. package/src/scripts/lint_example_fences.ts +609 -0
  44. package/src/scripts/lint_rule_interactions.ts +90 -0
  45. package/src/scripts/lint_rule_migration_ledger.ts +480 -0
  46. package/src/scripts/lint_skill_descriptions.ts +86 -2
  47. package/src/scripts/schemas/rule.schema.json +10 -0
@@ -44,6 +44,17 @@
44
44
  * construction and wake up exactly when a new skill lands close to an existing
45
45
  * one. That is the point.
46
46
  *
47
+ * A seventh check runs on EVERY skill and is neither absence nor presence — it
48
+ * is a prohibition:
49
+ *
50
+ * (g) preemption-phrase — the description claims priority over a sibling, or
51
+ * instructs activation regardless of the request.
52
+ * Unlike (a)-(f), this defect harms OTHER skills: it
53
+ * wins turns that belonged to them, and the loss is
54
+ * invisible at the source. See PREEMPTION_PATTERNS
55
+ * for why every pattern is anchored on the directive
56
+ * rather than on a vocabulary word.
57
+ *
47
58
  * Deterministic, static-config only. Allowlist mirrors lint_skill_originality:
48
59
  * `lint_skill_descriptions_allowlist.json`, capped at 20 (autonomous-execution
49
60
  * allowlist-growth antipattern — over-cap means the linter is wrong).
@@ -78,6 +89,62 @@ const CONDITION_RE =
78
89
  const IMPERATIVE_LEAD_RE =
79
90
  /^["'`]*\s*(write|author|convert|review|run|add|build|generate|create|fix|wire|detect|analy[sz]e|optimi[sz]e|draft|extract|route|turn|produce|score|consolidate|rate|model|estimate|plan|check|audit|ship|emit|render|guide|poll|capture|explain|map|prepare|handle|manage|track|compare|validate|verify|enforce|choose|pick|enumerate|investigate|format|scaffold|design|define|describe|gate|block|refactor|migrate|transcribe|summari[sz]e|orchestrate|surface|propose|walk|stress-test|red-team|challenge|bootstrap|seed|install|deploy|package|split|merge|condense|harvest|evaluate|assess|diagnose|reproduce|trace|inspect|lint|test)/i;
80
91
 
92
+ /**
93
+ * (g) Preemption phrases — a description that argues for itself against the
94
+ * rest of the catalogue.
95
+ *
96
+ * Every other check here asks whether a description carries ENOUGH signal.
97
+ * This one is the opposite: a description claiming priority over a sibling, or
98
+ * instructing activation regardless of the request, degrades routing **globally
99
+ * and invisibly**. It does not misroute its own skill — it wins turns that
100
+ * belonged to other skills, and the loss surfaces as those skills mysteriously
101
+ * under-firing. The sweep behind this check found the class live in a shipped
102
+ * third-party description and in a second suite's own catalogue.
103
+ *
104
+ * Every pattern is anchored on the **directive**, never on a vocabulary word,
105
+ * and that is the whole design. A first pass keyed on the words alone
106
+ * (`overrides`, `supersedes`, `for every …`) returned three hits on this corpus
107
+ * and **all three were false positives**: `override-management` manages
108
+ * overrides, `decision-review` asks whether an ADR should be superseded, and
109
+ * `prediction-pool-optimizer` answers "every question" in a prediction pool.
110
+ * Those are subjects, not claims. The patterns below therefore require the
111
+ * shape of an instruction to the router (`always use`, `use this instead of`,
112
+ * `this skill takes precedence`), which no domain noun produces.
113
+ */
114
+ const PREEMPTION_PATTERNS: ReadonlyArray<readonly [string, RegExp]> = [
115
+ [
116
+ 'unconditional activation',
117
+ /\b(?:always|invariably|unconditionally)\s+(?:use|load|apply|run|activate|invoke|prefer)\b/i,
118
+ ],
119
+ [
120
+ 'activation regardless of the request',
121
+ /\b(?:regardless of|no matter)\s+(?:the|what|which)\b|\b(?:for|on)\s+(?:every|all|any)\s+(?:request|turn|prompt|conversation|session)s?\b|\beven if not (?:asked|requested)\b/i,
122
+ ],
123
+ [
124
+ 'priority over a sibling',
125
+ /\b(?:use|load|apply|invoke|prefer)\s+(?:this|these|it)\b[^.;]{0,60}?\b(?:instead of|rather than|over|in preference to)\b/i,
126
+ ],
127
+ [
128
+ 'authority claim over the catalogue',
129
+ /\bthis (?:skill|one|artifact)\s+(?:takes precedence|outranks|supersedes|overrides|wins)\b|\b(?:takes precedence over|outranks)\s+(?:all|any|every)\b/i,
130
+ ],
131
+ [
132
+ 'load-order claim',
133
+ /\b(?:before|prior to)\s+(?:any|all)\s+other\s+(?:skill|tool|rule)s?\b|\bload (?:this )?first\b/i,
134
+ ],
135
+ ];
136
+
137
+ /** The first preemption claim in a description, or null. */
138
+ function preemptionPhrase(desc: string): { kind: string; match: string } | null {
139
+ for (const [kind, rx] of PREEMPTION_PATTERNS) {
140
+ const m = rx.exec(desc);
141
+ if (m) {
142
+ return { kind: kind as string, match: m[0] };
143
+ }
144
+ }
145
+ return null;
146
+ }
147
+
81
148
  interface Violation {
82
149
  slug: string;
83
150
  code:
@@ -86,7 +153,8 @@ interface Violation {
86
153
  | 'triggers-are-name'
87
154
  | 'no-routing-signal'
88
155
  | 'clustered-no-sibling-routing'
89
- | 'clustered-no-quoted-phrase';
156
+ | 'clustered-no-quoted-phrase'
157
+ | 'preemption-phrase';
90
158
  detail: string;
91
159
  }
92
160
 
@@ -204,6 +272,22 @@ function analyseSkill(slug: string, fm: Record<string, string>, siblings: readon
204
272
  });
205
273
  }
206
274
 
275
+ // (g) a claim of priority over the rest of the catalogue. Unlike (a)-(d),
276
+ // this defect harms OTHER skills, so it is checked on every skill and is
277
+ // never scoped to a cluster — a preemption phrase costs turns regardless of
278
+ // whether the router already had a near-neighbour to confuse it with.
279
+ const preemption = preemptionPhrase(desc);
280
+ if (preemption) {
281
+ out.push({
282
+ slug,
283
+ code: 'preemption-phrase',
284
+ detail:
285
+ `description claims ${preemption.kind} ("${preemption.match}") — a description ` +
286
+ 'argues for its own routing conditions, never against its siblings; this wins ' +
287
+ 'turns that belonged to other skills and the loss is invisible at the source',
288
+ });
289
+ }
290
+
207
291
  // (e) + (f) fire ONLY for skills the canonical tool put in a cluster.
208
292
  if (siblings.length > 0) {
209
293
  const unrouted = siblings.filter((s) => !desc.includes(s));
@@ -332,4 +416,4 @@ if (path.resolve(process.argv[1] ?? '') === path.resolve(_HERE)) {
332
416
  process.exit(main(process.argv.slice(2)));
333
417
  }
334
418
 
335
- export { analyseSkill, normalize, triggerPhrases, main };
419
+ export { analyseSkill, normalize, triggerPhrases, preemptionPhrase, main };
@@ -18,6 +18,16 @@
18
18
  "enum": ["package", "project"],
19
19
  "default": "package"
20
20
  },
21
+ "decision_impact": {
22
+ "type": "string",
23
+ "enum": ["overrides-model-default", "encodes-house-choice", "already-complied-with"],
24
+ "description": "What is at stake when this rule fires — distinct from `type`, which is a DELIVERY class (how the rule reaches the model). `overrides-model-default`: the model's base behaviour is wrong here, so the rule is load-bearing. `encodes-house-choice`: the model would make *a* defensible choice but not *our* choice. `already-complied-with`: the model does this unprompted — the one value that permits removal, and therefore the one carrying an evidence bar (`decision_impact_evidence`, enforced by lint_decision_impact). OPTIONAL by design: classifying all 111 rules in one batch is exactly the shape that trips check_kernel_prefix_stability, so it lands on new rules and on rules touched for another reason."
25
+ },
26
+ "decision_impact_evidence": {
27
+ "type": "string",
28
+ "minLength": 20,
29
+ "description": "Required when `decision_impact: already-complied-with`, forbidden otherwise. A pointer a reviewer can follow to the observation that the model complies without this rule — an eval report, a PR discussion, a trajectory sample. The bar exists because that classification is what permits deleting a rule, and 'the model probably does this anyway' is the cheapest possible way to remove a floor that was working precisely because nothing had crossed it."
30
+ },
21
31
  "description": {
22
32
  "type": "string",
23
33
  "minLength": 1,