@event4u/agent-config 14.19.0 → 14.21.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +351 -156
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +10 -0
- package/dist/agent-src/commands/agent-handoff.md +42 -41
- package/dist/agent-src/commands/analyze/inbox.md +1 -1
- package/dist/agent-src/commands/analyze/{reference-repo.md → repo.md} +247 -32
- package/dist/agent-src/commands/analyze/roadmap-repos.md +129 -0
- package/dist/agent-src/commands/analyze.md +12 -7
- package/dist/agent-src/commands/feature/plan.md +55 -16
- package/dist/agent-src/commands/feature/refactor.md +8 -3
- package/dist/agent-src/commands/humanize.md +48 -4
- package/dist/agent-src/contexts/execution/contract-decision-sheet.md +22 -1
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +11 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +35 -2
- package/dist/agent-src/contexts/execution/terminal-states.md +4 -1
- package/dist/agent-src/rules/evaluator-independence.md +4 -4
- package/dist/agent-src/rules/external-reference-deep-dive.md +2 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +0 -2
- package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +1 -1
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +27 -11
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +1 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +2 -2
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +28 -6
- package/dist/agent-src/skills/technical-specification/SKILL.md +4 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/features.md +5 -0
- package/dist/agent-src/templates/roadmaps.md +29 -1
- package/dist/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/dist/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/dist/cli/mcp/dispatch.js +10 -0
- package/dist/cli/mcp/stdio.js +33 -2
- package/dist/cli/mcp/telemetry.js +227 -0
- package/dist/cli-delegate/{chunk-KPBWFOPZ.js → chunk-2FTMENJL.js} +194 -37
- package/dist/cli-delegate/{chunk-PMEKGDED.js → chunk-2TAQ2K4V.js} +166 -1
- package/dist/cli-delegate/{chunk-GZTMRYCN.js → chunk-643Z7FIC.js} +79 -12
- package/dist/cli-delegate/{chunk-CYH5SP6M.js → chunk-I6RHFQEG.js} +151 -16
- package/dist/cli-delegate/{chunk-IDHUQIXP.js → chunk-J3RFNKG4.js} +41 -5
- package/dist/cli-delegate/{chunk-7PRE6ZV2.js → chunk-YS6XTLEK.js} +199 -4
- package/dist/cli-delegate/chunk-ZVBOHSVF.js +1109 -0
- package/dist/cli-delegate/cmd_conformance.js +88 -110
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +42 -12
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +59 -902
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- 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 +62 -31
- 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 +7 -6
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +6 -5
- package/dist/hooks/dispatch.js +3801 -2803
- package/dist/install/install.mjs +396 -168
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +809 -180
- package/dist/scripts/ai_council/content_ceiling.js +63 -0
- package/dist/scripts/ai_council/seat_policy.js +106 -0
- package/dist/scripts/ai_council/transport_resolver.js +21 -0
- package/dist/scripts/mcp_server/telemetry.js +148 -0
- package/docs/guidelines/agent-infra/naming.md +1 -1
- package/docs/guidelines/agent-infra/security-lint-containment.md +46 -6
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +4 -4
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +1 -1
- package/docs/guidelines/redundancy-taxonomy.md +28 -0
- package/llms.txt +14 -14
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/src/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/src/config/assurance-capability-registry.json +9 -0
- package/src/config/gate-coverage.yml +55 -0
- package/src/config/gate-violation-baselines.json +18 -6
- package/src/config/release-gate-locality.yml +4 -3
- package/src/scripts/_cli/cmd_session_recycle.ts +51 -3
- package/src/scripts/_lib/audit_field_provenance.ts +44 -3
- package/src/scripts/_lib/blocked_by_marker.ts +189 -0
- package/src/scripts/_lib/host_capability.ts +76 -1
- package/src/scripts/_lib/install_reach_checks.ts +33 -1
- package/src/scripts/_lib/mcp_bridge.ts +222 -10
- package/src/scripts/_lib/mcp_consent_residual.ts +173 -0
- package/src/scripts/_lib/orchestration_record.ts +23 -1
- package/src/scripts/_lib/recycle_envelope_paths.ts +190 -0
- package/src/scripts/_lib/release_highlights.ts +19 -211
- package/src/scripts/_lib/release_material.ts +27 -77
- package/src/scripts/_lib/release_position.ts +96 -0
- package/src/scripts/_lib/review_skipped_record.ts +17 -1
- package/src/scripts/_lib/security_lint.ts +179 -7
- package/src/scripts/_lib/self_repair.ts +141 -6
- package/src/scripts/_lib/self_repair_store.ts +273 -7
- package/src/scripts/_lib/structured_ask.ts +117 -0
- package/src/scripts/_lib/subagent_capsule.ts +155 -3
- package/src/scripts/_lib/tty_prompt.ts +76 -0
- package/src/scripts/ai_council/api_transport.ts +163 -0
- package/src/scripts/ai_council/clients.ts +58 -63
- package/src/scripts/ai_council/config.ts +13 -0
- package/src/scripts/ai_council/content_ceiling.ts +79 -0
- package/src/scripts/ai_council/jury_aggregate.ts +178 -0
- package/src/scripts/ai_council/seat_policy.ts +137 -0
- package/src/scripts/ai_council/status_surface.ts +79 -0
- package/src/scripts/ai_council/transport_resolver.ts +59 -1
- package/src/scripts/ai_tells_rules.ts +446 -5
- package/src/scripts/ask_block_census.ts +499 -0
- package/src/scripts/bench_humanizer_eval.ts +264 -40
- package/src/scripts/bench_prose_tells_fp.ts +198 -0
- package/src/scripts/build_rule_trigger_matrix.ts +5 -0
- package/src/scripts/check_branch_work_committed.ts +234 -0
- package/src/scripts/check_mcp_doc_drift.ts +217 -0
- package/src/scripts/check_pack_size.ts +321 -3
- package/src/scripts/check_release_highlights.ts +0 -157
- package/src/scripts/council_cli.ts +18 -27
- package/src/scripts/detect_ai_tells.ts +142 -20
- package/src/scripts/handoff_context_hook.ts +54 -7
- package/src/scripts/harvest_reference_tokens.ts +698 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +31 -1
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +45 -1
- package/src/scripts/hooks/one_question_per_ask_hook.ts +191 -0
- package/src/scripts/hooks/session_eol_hook.ts +18 -7
- package/src/scripts/install-hooks.sh +52 -0
- package/src/scripts/install.ts +4 -4
- package/src/scripts/lint_agent_security.ts +316 -25
- package/src/scripts/lint_confusables.ts +42 -6
- package/src/scripts/lint_handoffs.ts +0 -132
- package/src/scripts/lint_hidden_unicode.ts +49 -7
- package/src/scripts/lint_instruction_smuggling.ts +42 -6
- package/src/scripts/lint_mcp_config_security.ts +42 -6
- package/src/scripts/lint_roadmap_blockers.ts +51 -1
- package/src/scripts/lint_roadmap_later_disposition.ts +217 -27
- package/src/scripts/lint_skill_frontmatter_safety.ts +43 -7
- package/src/scripts/mcp_server/resources.ts +41 -0
- package/src/scripts/mcp_server/telemetry.ts +19 -4
- package/src/scripts/migrate_command_suggestions.ts +1 -1
- package/src/scripts/orchestration_record.ts +12 -1
- package/src/scripts/probe_unblocked_ask.ts +135 -2
- package/src/scripts/release.ts +50 -95
- package/src/scripts/release_drill.ts +6 -10
- package/src/scripts/release_env.ts +1 -0
- package/src/scripts/release_publication.ts +40 -31
- package/src/scripts/self_repair_cli.ts +31 -1
- package/src/scripts/self_review_gate.ts +409 -15
- package/src/scripts/skill_scout.ts +69 -0
- package/dist/cli-delegate/chunk-2GNWGMAL.js +0 -172
- package/dist/cli-delegate/chunk-LPPWO5CE.js +0 -161
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One binary content ceiling per seat — road-to-admissible-council-seats 2.2.
|
|
3
|
+
*
|
|
4
|
+
* Redaction today is a SECRETS floor and says so
|
|
5
|
+
* (`src/skills/ai-council/references/cost-and-redaction.md`). Nothing above it
|
|
6
|
+
* could express "this project's diff may not go to that seat", which is a
|
|
7
|
+
* different question with a different answer: a diff carrying no secret at all
|
|
8
|
+
* is still the consumer's private source.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately BINARY. A graded scale invites a middle value nobody can define
|
|
11
|
+
* and every caller reads differently; two values force the decision at
|
|
12
|
+
* authoring time, where it belongs.
|
|
13
|
+
*
|
|
14
|
+
* public-artifact — repo-owned artefacts: skill descriptions, the trigger
|
|
15
|
+
* corpus, rule text, bench fixtures. Already public.
|
|
16
|
+
* project-content — everything a consumer supplies. The DEFAULT, so an
|
|
17
|
+
* unclassified payload is treated as private rather than
|
|
18
|
+
* as publishable.
|
|
19
|
+
*
|
|
20
|
+
* A seat's ceiling is the most sensitive class it may receive. `public-artifact`
|
|
21
|
+
* is therefore the NARROWER seat: it admits public artefacts only.
|
|
22
|
+
*/
|
|
23
|
+
export const CONTENT_CLASSES = ['public-artifact', 'project-content'];
|
|
24
|
+
/** The default for anything not explicitly classified: private, not public. */
|
|
25
|
+
export const DEFAULT_CONTENT_CLASS = 'project-content';
|
|
26
|
+
/** The default seat ceiling: unchanged behaviour for every existing seat. */
|
|
27
|
+
export const DEFAULT_SEAT_CEILING = 'project-content';
|
|
28
|
+
const _SET = new Set(CONTENT_CLASSES);
|
|
29
|
+
/**
|
|
30
|
+
* Any configured value → a content class. Unrecognised input becomes
|
|
31
|
+
* `project-content`, the RESTRICTIVE value: a typo must narrow what a seat may
|
|
32
|
+
* receive, never widen it.
|
|
33
|
+
*/
|
|
34
|
+
export function classifyContentClass(raw, fallback = DEFAULT_CONTENT_CLASS) {
|
|
35
|
+
if (typeof raw === 'string' && _SET.has(raw)) {
|
|
36
|
+
return raw;
|
|
37
|
+
}
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Does a seat whose ceiling is `seatCeiling` admit a payload of `contentClass`?
|
|
42
|
+
*
|
|
43
|
+
* The one refusal is `project-content` into a `public-artifact` seat. Every
|
|
44
|
+
* other pairing is admitted, including public artefacts into a
|
|
45
|
+
* `project-content` seat — a seat cleared for private content is trivially
|
|
46
|
+
* cleared for public content, and refusing that would be a nonsense that
|
|
47
|
+
* disables the default seat for its own repo's fixtures.
|
|
48
|
+
*
|
|
49
|
+
* Refusal is a GREEN path (this roadmap's 2.2 verify): the caller drops the
|
|
50
|
+
* seat and the run continues. It is not an error, because a policy working as
|
|
51
|
+
* designed is not a failure.
|
|
52
|
+
*/
|
|
53
|
+
export function admitsContent(seatCeiling, contentClass) {
|
|
54
|
+
if (seatCeiling === 'public-artifact' && contentClass === 'project-content') {
|
|
55
|
+
return {
|
|
56
|
+
admitted: false,
|
|
57
|
+
reason: "seat ceiling is 'public-artifact'; the payload is classified " +
|
|
58
|
+
"'project-content' (consumer-supplied)",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { admitted: true, reason: null };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=content_ceiling.js.map
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { classifyContentClass as _classifyContentClass, DEFAULT_SEAT_CEILING as _DEFAULT_SEAT_CEILING, } from './content_ceiling.js';
|
|
2
|
+
/**
|
|
3
|
+
* Seat policy — the vocabulary for refusing a route that IS reachable.
|
|
4
|
+
*
|
|
5
|
+
* road-to-admissible-council-seats 2.1. `AbsentReason` was exactly four values
|
|
6
|
+
* — `no_binary | no_auth | timeout | quota` — and every one of them means "the
|
|
7
|
+
* route is not reachable". A route that is reachable and **must not be used**
|
|
8
|
+
* had no name at all, so the resolver could not fail closed on terms, privacy,
|
|
9
|
+
* unproven cost, or a served model that is not the requested one. The absence
|
|
10
|
+
* of a word was the absence of the refusal: `resolveTransport`'s `api`/`cli`
|
|
11
|
+
* branches return `available: true` unconditionally, so anything the four
|
|
12
|
+
* reachability reasons could not express resolved OPEN.
|
|
13
|
+
*
|
|
14
|
+
* Fail closed on the unknown, which is the whole point.
|
|
15
|
+
* `classifyPolicyExclusion` maps anything it does not recognise to
|
|
16
|
+
* `policy_unknown`, and `policy_unknown` is an ABSENT reason like every other
|
|
17
|
+
* member of this union. An unrecognised policy token is the case where the
|
|
18
|
+
* config is trying to say something the code cannot understand; resolving it
|
|
19
|
+
* to "available" would make a typo an authorisation. This is the roadmap's own
|
|
20
|
+
* Risk 3 — "a new refusal vocabulary defaults open instead of closed".
|
|
21
|
+
*
|
|
22
|
+
* What this is NOT. It is not a secrets floor. Redaction (`skills/ai-council/references/
|
|
23
|
+
* cost-and-redaction.md`) still runs underneath and is not replaced. It is not
|
|
24
|
+
* an authorisation either: nothing here ever makes a seat available that was
|
|
25
|
+
* not already available — every value in the union only ever subtracts.
|
|
26
|
+
*/
|
|
27
|
+
/** Reachable-but-refused reasons. Every value means ABSENT. */
|
|
28
|
+
export const POLICY_EXCLUSIONS = [
|
|
29
|
+
/** The provider's terms forbid this use of the route. */
|
|
30
|
+
'policy_terms',
|
|
31
|
+
/** A privacy constraint forbids sending to this route. */
|
|
32
|
+
'policy_privacy',
|
|
33
|
+
/** The route's cost property is asserted rather than proven. */
|
|
34
|
+
'policy_unproven_cost',
|
|
35
|
+
/** The route serves a model other than the one requested. */
|
|
36
|
+
'policy_model_mismatch',
|
|
37
|
+
/** 2.2 — the payload's content class exceeds the seat's ceiling. */
|
|
38
|
+
'policy_content_ceiling',
|
|
39
|
+
/** The config named an exclusion this build does not understand. */
|
|
40
|
+
'policy_unknown',
|
|
41
|
+
];
|
|
42
|
+
const _SET = new Set(POLICY_EXCLUSIONS);
|
|
43
|
+
/** True for a value this build can act on. `policy_unknown` included: it is a
|
|
44
|
+
* real, actionable verdict (refuse), not a parse failure. */
|
|
45
|
+
export function isPolicyExclusion(v) {
|
|
46
|
+
return typeof v === 'string' && _SET.has(v);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Any configured value → a verdict. Unrecognised input, including `null` used
|
|
50
|
+
* where a string was meant, becomes `policy_unknown` — never `null`, because a
|
|
51
|
+
* `null` return would put the caller back in the position of deciding what an
|
|
52
|
+
* unreadable policy means, which is where the open default came from.
|
|
53
|
+
*
|
|
54
|
+
* `undefined` and `null` are the two ways of saying "no exclusion configured"
|
|
55
|
+
* and are the ONLY inputs that return `null`. Everything else is a refusal.
|
|
56
|
+
*/
|
|
57
|
+
export function classifyPolicyExclusion(raw) {
|
|
58
|
+
if (raw === undefined || raw === null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return isPolicyExclusion(raw) ? raw : 'policy_unknown';
|
|
62
|
+
}
|
|
63
|
+
/** One-line human reason for a refusal. `council:status` prints this. */
|
|
64
|
+
export function policyExclusionReason(p, provider) {
|
|
65
|
+
const who = provider === undefined ? 'this seat' : provider;
|
|
66
|
+
switch (p) {
|
|
67
|
+
case 'policy_terms':
|
|
68
|
+
return `${who} is excluded by policy: the route's terms forbid this use`;
|
|
69
|
+
case 'policy_privacy':
|
|
70
|
+
return `${who} is excluded by policy: a privacy constraint forbids this route`;
|
|
71
|
+
case 'policy_unproven_cost':
|
|
72
|
+
return `${who} is excluded by policy: the route's cost property is asserted, not proven`;
|
|
73
|
+
case 'policy_model_mismatch':
|
|
74
|
+
return `${who} is excluded by policy: the route serves a model other than the one requested`;
|
|
75
|
+
case 'policy_content_ceiling':
|
|
76
|
+
return `${who} is excluded by policy: the payload exceeds the seat's content ceiling`;
|
|
77
|
+
case 'policy_unknown':
|
|
78
|
+
return `${who} is excluded by policy: an exclusion this build does not understand (failing closed)`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function parseSeatFields(name, raw) {
|
|
82
|
+
const dr = raw['disabled_reason'];
|
|
83
|
+
let disabled_reason = null;
|
|
84
|
+
if (dr !== undefined && dr !== null) {
|
|
85
|
+
if (typeof dr !== 'string' || dr.trim() === '') {
|
|
86
|
+
return {
|
|
87
|
+
error: `members.${name}.disabled_reason must be a non-empty string when set ` +
|
|
88
|
+
`(got ${JSON.stringify(dr)}).`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
disabled_reason = dr.trim();
|
|
92
|
+
}
|
|
93
|
+
// Both of the next two fail CLOSED on an unreadable value: an unknown
|
|
94
|
+
// exclusion token becomes `policy_unknown` (which resolves ABSENT) and an
|
|
95
|
+
// unknown ceiling falls back to the RESTRICTIVE one. Throwing instead would
|
|
96
|
+
// be defensible, but a config typo would then take the whole council down
|
|
97
|
+
// rather than the one seat it names.
|
|
98
|
+
return {
|
|
99
|
+
fields: {
|
|
100
|
+
disabled_reason,
|
|
101
|
+
policy_exclusion: classifyPolicyExclusion(raw['policy_exclusion']),
|
|
102
|
+
content_ceiling: _classifyContentClass(raw['content_ceiling'], _DEFAULT_SEAT_CEILING),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=seat_policy.js.map
|
|
@@ -40,6 +40,8 @@
|
|
|
40
40
|
*/
|
|
41
41
|
import { classifyBilling, isCommunityCli, strongestAuth, PROVIDER_CLI_META, } from '../_lib/environment_detector.js';
|
|
42
42
|
import { resolve_mode } from './modes.js';
|
|
43
|
+
import { admitsContent, DEFAULT_SEAT_CEILING, } from './content_ceiling.js';
|
|
44
|
+
import { policyExclusionReason } from './seat_policy.js';
|
|
43
45
|
/** The accepted values of the `mode` key, including the resolver-only `auto`. */
|
|
44
46
|
export const VALID_TRANSPORT_MODES = new Set([
|
|
45
47
|
'api',
|
|
@@ -84,6 +86,22 @@ export function resolveTransport(opts) {
|
|
|
84
86
|
const auth = strongestAuth(report, provider);
|
|
85
87
|
const authSource = auth?.source ?? null;
|
|
86
88
|
const billing = classifyBilling(provider, authSource);
|
|
89
|
+
// Policy first (2.1). Before the mode dispatch, because `api` and `cli`
|
|
90
|
+
// below return `available: true` UNCONDITIONALLY — a refusal placed after
|
|
91
|
+
// them would be unreachable for exactly the seats it exists to stop.
|
|
92
|
+
const exclusion = opts.policyExclusion ?? null;
|
|
93
|
+
if (exclusion !== null) {
|
|
94
|
+
return unavailable(provider, billing, policyExclusionReason(exclusion, provider), exclusion);
|
|
95
|
+
}
|
|
96
|
+
// Content ceiling (2.2). Only runs when the caller declared what it would
|
|
97
|
+
// send; an undeclared pass is unchanged, not silently refused.
|
|
98
|
+
const contentClass = opts.contentClass ?? null;
|
|
99
|
+
if (contentClass !== null) {
|
|
100
|
+
const verdict = admitsContent(opts.seatCeiling ?? DEFAULT_SEAT_CEILING, contentClass);
|
|
101
|
+
if (!verdict.admitted) {
|
|
102
|
+
return unavailable(provider, billing, `${provider}: ${verdict.reason ?? 'content ceiling refused the payload'}`, 'policy_content_ceiling');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
87
105
|
if (mode === 'manual') {
|
|
88
106
|
return {
|
|
89
107
|
available: true,
|
|
@@ -173,6 +191,9 @@ export function resolveMemberTransport(opts) {
|
|
|
173
191
|
// optional-boolean field, so the key is omitted entirely rather than
|
|
174
192
|
// forwarded as `apiKeyPresent: undefined`.
|
|
175
193
|
...(opts.apiKeyPresent !== undefined ? { apiKeyPresent: opts.apiKeyPresent } : {}),
|
|
194
|
+
policyExclusion: opts.policyExclusion ?? null,
|
|
195
|
+
seatCeiling: opts.seatCeiling ?? null,
|
|
196
|
+
contentClass: opts.contentClass ?? null,
|
|
176
197
|
});
|
|
177
198
|
return { ...resolved, configuredMode };
|
|
178
199
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// MCP telemetry sink — Phase 1 J4 instrumentation.
|
|
2
|
+
//
|
|
3
|
+
// Per `agents/roadmaps/archive/road-to-mcp-full-coverage.md` §Phase 1 J4 +
|
|
4
|
+
// `docs/contracts/mcp-tool-stub-envelope.md`, both transports log every
|
|
5
|
+
// `tools/call` with `{tool_name, client_id_hash, ts, transport,
|
|
6
|
+
// outcome}`. The stdio-lite surface (`src/cli/mcp/`) appends a sixth,
|
|
7
|
+
// optional `host` field; callers that do not know their client omit it and
|
|
8
|
+
// their records stay byte-identical to the frozen five-field envelope. Payload bodies are never logged; the client identifier is
|
|
9
|
+
// hashed at the server boundary so the queryable store never sees raw
|
|
10
|
+
// identity.
|
|
11
|
+
//
|
|
12
|
+
// Outcomes:
|
|
13
|
+
//
|
|
14
|
+
// - `implemented` — real handler ran (no envelope returned).
|
|
15
|
+
// - `stub` — catalog entry missing this transport; `not_implemented`
|
|
16
|
+
// envelope returned.
|
|
17
|
+
// - `latent_demand` — caller asked for a tool not in the catalog.
|
|
18
|
+
//
|
|
19
|
+
// The sink writes JSONL to `agents/runtime/mcp-telemetry/calls.jsonl` under the
|
|
20
|
+
// consumer root. Failure to write must not break the wire surface: the
|
|
21
|
+
// `record_call` helper swallows OSError + ValueError and emits a single
|
|
22
|
+
// warning to stderr.
|
|
23
|
+
//
|
|
24
|
+
// TS port of the retired Python telemetry.py (ADR-200). Preserves the full public surface:
|
|
25
|
+
// - Outcome type, TELEMETRY_REL_DIR, TELEMETRY_FILENAME, hash_client_id,
|
|
26
|
+
// build_record, record_call.
|
|
27
|
+
import * as crypto from 'node:crypto';
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as os from 'node:os';
|
|
30
|
+
import * as path from 'node:path';
|
|
31
|
+
// Stable file location relative to consumer_root. Phase 2 K1 routes
|
|
32
|
+
// this into a queryable store; Phase 1 only needs the file to exist.
|
|
33
|
+
export const TELEMETRY_REL_DIR = 'agents/runtime/mcp-telemetry';
|
|
34
|
+
export const TELEMETRY_FILENAME = 'calls.jsonl';
|
|
35
|
+
// Truncation length for the client_id hash. 12 hex chars = 48 bits of
|
|
36
|
+
// entropy — enough to distinguish hundreds of consumers without
|
|
37
|
+
// becoming a re-identification vector.
|
|
38
|
+
const _HASH_LEN = 12;
|
|
39
|
+
/**
|
|
40
|
+
* Identity components that together pin a consumer install.
|
|
41
|
+
*
|
|
42
|
+
* USER + machine hostname + repo path is a stable triple that survives
|
|
43
|
+
* sessions without leaking PII into the log. The hash never reverses.
|
|
44
|
+
*/
|
|
45
|
+
function _client_id_seed() {
|
|
46
|
+
const user = process.env.USER || process.env.USERNAME || 'unknown';
|
|
47
|
+
let host = process.env.HOSTNAME;
|
|
48
|
+
if (!host) {
|
|
49
|
+
// Mirrors Python `os.uname().nodename` (POSIX) — Node exposes
|
|
50
|
+
// `os.hostname()`. Guarded so an empty value falls through to "unknown".
|
|
51
|
+
try {
|
|
52
|
+
host = os.hostname();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
host = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
host = host || 'unknown';
|
|
59
|
+
const cwd = _resolvePath(process.cwd());
|
|
60
|
+
return `${user}|${host}|${cwd}`;
|
|
61
|
+
}
|
|
62
|
+
/** SHA-256(seed) truncated to 12 hex chars. Boundary-only call. */
|
|
63
|
+
export function hash_client_id(seed) {
|
|
64
|
+
const raw = seed !== undefined ? seed : _client_id_seed();
|
|
65
|
+
const digest = crypto.createHash('sha256').update(Buffer.from(raw, 'utf-8')).digest('hex');
|
|
66
|
+
return digest.slice(0, _HASH_LEN);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolve a path like Python `Path(...).resolve()` — absolutize + realpath
|
|
70
|
+
* the existing prefix, tolerating a non-existent tail (Python resolve does
|
|
71
|
+
* not require the path to exist; `fs.realpathSync` does, so fall back to a
|
|
72
|
+
* plain absolute path on ENOENT).
|
|
73
|
+
*/
|
|
74
|
+
function _resolvePath(p) {
|
|
75
|
+
try {
|
|
76
|
+
return fs.realpathSync(p);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return path.resolve(p);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Pick the JSONL location. Defaults to CWD when no override given. */
|
|
83
|
+
function _resolve_log_path(consumer_root) {
|
|
84
|
+
const root = _resolvePath(consumer_root ?? process.cwd());
|
|
85
|
+
return path.join(root, TELEMETRY_REL_DIR, TELEMETRY_FILENAME);
|
|
86
|
+
}
|
|
87
|
+
/** ISO-8601 UTC timestamp, seconds precision. */
|
|
88
|
+
function _now_iso() {
|
|
89
|
+
// Mirrors Python `time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())`.
|
|
90
|
+
return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Pure helper — assemble the record without touching the filesystem.
|
|
94
|
+
*
|
|
95
|
+
* Field insertion order matches the Python dict literal so the
|
|
96
|
+
* compact-JSON serialization is byte-identical.
|
|
97
|
+
*/
|
|
98
|
+
export function build_record(options) {
|
|
99
|
+
const { tool_name, outcome, transport, client_id_hash_value, ts, host } = options;
|
|
100
|
+
const record = {
|
|
101
|
+
tool_name,
|
|
102
|
+
client_id_hash: client_id_hash_value || hash_client_id(),
|
|
103
|
+
ts: ts || _now_iso(),
|
|
104
|
+
transport,
|
|
105
|
+
outcome,
|
|
106
|
+
};
|
|
107
|
+
// `host` is APPENDED, and only when a caller supplies one, so a record
|
|
108
|
+
// written by a caller that does not know its client stays byte-identical
|
|
109
|
+
// to the five-field envelope the stub contract froze. It is a closed
|
|
110
|
+
// vocabulary resolved at the boundary (see `src/cli/mcp/telemetry.ts`),
|
|
111
|
+
// never a free-form string: a record type that cannot hold arbitrary text
|
|
112
|
+
// has no scrubber to fail.
|
|
113
|
+
if (typeof host === 'string' && host !== '') {
|
|
114
|
+
record.host = host;
|
|
115
|
+
}
|
|
116
|
+
return record;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Append one JSONL record. Returns the record or null on failure.
|
|
120
|
+
*
|
|
121
|
+
* Failures are swallowed: telemetry must never break the wire surface.
|
|
122
|
+
* A single `mcp-server: warn: telemetry` line is emitted to stderr
|
|
123
|
+
* so silent-failure windows show up in the boot log and the J6
|
|
124
|
+
* healthcheck can detect them.
|
|
125
|
+
*/
|
|
126
|
+
export function record_call(options) {
|
|
127
|
+
const { tool_name, outcome, transport, consumer_root, client_id_hash_value, host } = options;
|
|
128
|
+
const record = build_record({
|
|
129
|
+
tool_name,
|
|
130
|
+
outcome,
|
|
131
|
+
transport,
|
|
132
|
+
client_id_hash_value,
|
|
133
|
+
host,
|
|
134
|
+
});
|
|
135
|
+
const target = _resolve_log_path(consumer_root ?? undefined);
|
|
136
|
+
try {
|
|
137
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
138
|
+
// json.dumps(record, separators=(",", ":")) — compact, no spaces.
|
|
139
|
+
fs.appendFileSync(target, JSON.stringify(record) + '\n', { encoding: 'utf-8' });
|
|
140
|
+
}
|
|
141
|
+
catch (exc) {
|
|
142
|
+
const message = exc instanceof Error ? exc.message : String(exc);
|
|
143
|
+
process.stderr.write(`mcp-server: warn: telemetry write failed: ${message}\n`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
return record;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -34,7 +34,7 @@ source: package
|
|
|
34
34
|
|---|---|---|
|
|
35
35
|
| `{concern}` | Behavioral constraint | `scope-control`, `ask-when-uncertain` |
|
|
36
36
|
| `{domain}-{concern}` | Domain-specific rule | `php-coding`, `e2e-testing` |
|
|
37
|
-
| `{action}-{target}` | Trigger-based auto rule | `
|
|
37
|
+
| `{action}-{target}` | Trigger-based auto rule | `invite-challenge`, `downstream-changes` |
|
|
38
38
|
|
|
39
39
|
### Commands
|
|
40
40
|
|
|
@@ -45,18 +45,51 @@ are *expected* to contain illustrative patterns. Only a full-weight (1.0×)
|
|
|
45
45
|
**HIGH** finding in a real artifact fails the build. (`is_example_path()` in the
|
|
46
46
|
shared lib defines the path set.)
|
|
47
47
|
|
|
48
|
-
### 3.
|
|
48
|
+
### 3. Bound pragma
|
|
49
49
|
|
|
50
|
-
A single check can be suppressed for one file with an
|
|
51
|
-
marker placed anywhere in the file:
|
|
50
|
+
A single check can be suppressed for **specific evidence** in one file with an
|
|
51
|
+
auditable, reasoned, content-bound marker placed anywhere in the file:
|
|
52
52
|
|
|
53
53
|
```
|
|
54
|
-
<!-- security-lint: allow instruction-smuggling "teaching example: quotes a prompt-injection string" -->
|
|
54
|
+
<!-- security-lint: allow instruction-smuggling "teaching example: quotes a prompt-injection string" sha256:<hex> -->
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
- The `<check>` token is the linter's check id (`hidden-unicode`,
|
|
58
|
-
`instruction-smuggling`, `mcp-config-security`,
|
|
58
|
+
`mixed-script-confusable`, `instruction-smuggling`, `mcp-config-security`,
|
|
59
|
+
`dangerous-frontmatter`).
|
|
59
60
|
- The `"<reason>"` is **mandatory** — an empty reason does not parse.
|
|
61
|
+
- Each `sha256:<hex>` **binds the suppression to one accepted match**. Repeat the
|
|
62
|
+
token once per accepted match; a file with three accepted matches carries three
|
|
63
|
+
hashes. Anything the check finds that is not in that set is still reported.
|
|
64
|
+
- The fingerprint covers the **check id**, the artifact's **source identity**, and
|
|
65
|
+
the **normalized text of the matched line** — ASCII whitespace runs collapse so
|
|
66
|
+
a reflow does not break the binding, and nothing else is stripped, because the
|
|
67
|
+
zero-width characters this suite hunts are exactly what a wider normalizer
|
|
68
|
+
would erase. It is deliberately NOT the line number (an unrelated insert above
|
|
69
|
+
would break every pragma in the file) and NOT the whole file (every unrelated
|
|
70
|
+
edit would re-fire it, which is how blanket suppressions get written).
|
|
71
|
+
A `dist/agent-src/` path folds to its `src/` original first: the projection is
|
|
72
|
+
byte-exact by contract, so an artifact and its copy are one identity.
|
|
73
|
+
- **A pair pinned equal by a parity test carries ONE HASH PER IDENTITY.** The
|
|
74
|
+
fold above covers `dist/agent-src/` and nothing else, so where a second
|
|
75
|
+
hand-maintained copy exists and a test asserts the two are byte-identical —
|
|
76
|
+
`src/subagents/<stem>.md` and `docs/wedge/<stem>/<stem>.md`, pinned by
|
|
77
|
+
`tests/scripts/subagent_distribution.test.ts` — one hash cannot satisfy both:
|
|
78
|
+
giving each file its own makes the lines differ and reds the parity test,
|
|
79
|
+
which is exactly how this was found. Put BOTH hashes in BOTH files. That is
|
|
80
|
+
what the repeatable token is for, and it is why the grammar has one. A purely
|
|
81
|
+
GENERATED third copy (`.claude/agents/<stem>.md`) needs no hash of its own:
|
|
82
|
+
nothing scans it and nobody edits it, so binding it would be a fingerprint
|
|
83
|
+
for an identity no finding can arise at.
|
|
84
|
+
- Compute one with the linter itself, never by hand — a hash typed from memory
|
|
85
|
+
is a suppression nobody audited.
|
|
86
|
+
|
|
87
|
+
**The unbound form still parses**, suppresses the whole file as it always did,
|
|
88
|
+
and reports itself as a `legacy-pragma` LOW finding. That is a migration signal,
|
|
89
|
+
not a mode to choose: a key lookup with no content binding accepts whatever the
|
|
90
|
+
matched text is later changed to say, which is the defect the hash exists to
|
|
91
|
+
close. There are zero unbound pragmas in the tree.
|
|
92
|
+
|
|
60
93
|
- Pragmas are **counted and capped**: crossing **20** across the repo means the
|
|
61
94
|
linter is mis-scoped. Stop adding pragmas; redesign or narrow the check
|
|
62
95
|
(escalate per `autonomous-execution` — the allowlist-growth antipattern).
|
|
@@ -72,7 +105,14 @@ marker placed anywhere in the file:
|
|
|
72
105
|
|
|
73
106
|
`security-example` fence → confidence weight → pragma. A HIGH finding survives
|
|
74
107
|
to fail the build only when it is full-weight (not in an example path), not
|
|
75
|
-
inside a `security-example` fence, and not covered by a
|
|
108
|
+
inside a `security-example` fence, and not covered by a pragma whose fingerprint
|
|
109
|
+
set contains that match.
|
|
110
|
+
|
|
111
|
+
One consumer deliberately departs from the weighting rung: `skill_scout`'s
|
|
112
|
+
`security_licence` gate refuses a quarantined candidate on **any** HIGH finding,
|
|
113
|
+
whatever its weight. Path-based confidence is a false-positive containment device
|
|
114
|
+
for a corpus whose provenance is known; a third-party candidate has none, and a
|
|
115
|
+
directory named `examples/` in it is the submitter's word for it.
|
|
76
116
|
|
|
77
117
|
## See also
|
|
78
118
|
|
|
@@ -4,10 +4,10 @@ Five-stage flow that turns real project experience into reviewed
|
|
|
4
4
|
rule / skill / command / guideline changes. No autonomous self-edits;
|
|
5
5
|
every upstream change ships via a human-reviewed PR.
|
|
6
6
|
|
|
7
|
-
Referenced by `road-to-curated-self-improvement.md`. Consumed by the
|
|
8
|
-
|
|
9
|
-
`skill-improvement-pipeline`, and
|
|
10
|
-
a stage, not a standalone invocation.
|
|
7
|
+
Referenced by `road-to-curated-self-improvement.md`. Consumed by the live
|
|
8
|
+
artifacts — the `skill-improvement-trigger` rule and the existing skills
|
|
9
|
+
`learning-to-rule-or-skill`, `skill-improvement-pipeline`, and
|
|
10
|
+
`upstream-contribute` — each becomes a stage, not a standalone invocation.
|
|
11
11
|
|
|
12
12
|
## The five stages
|
|
13
13
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- security-lint: allow instruction-smuggling "defense guideline: quotes role-takeover phrases (ignore previous instructions, you are now, <IMPORTANT>) to teach refusal" -->
|
|
1
|
+
<!-- security-lint: allow instruction-smuggling "defense guideline: quotes role-takeover phrases (ignore previous instructions, you are now, <IMPORTANT>) to teach refusal" sha256:d84759534e0fd3ebc5a66533b4a9f52364ef5286eaf3674a611c9c2adf89b969 sha256:f08c68182232149c7ecd881e88ca81dc98a9313c06ba6d010b065f9feef2c149 sha256:4f5936bb0a57de8ff3ce590fb12607cdcb046a31262b5e4d40377c6e6184f494 -->
|
|
2
2
|
|
|
3
3
|
# untrusted-input spotlighting + least-agency mapping
|
|
4
4
|
|
|
@@ -86,6 +86,34 @@ translation frequently denote different mechanisms — here `route`, `dispatch`,
|
|
|
86
86
|
five ways — so a sweep over them destroys information the echo classes exist to
|
|
87
87
|
protect.
|
|
88
88
|
|
|
89
|
+
## The avoid-list — one term, one concept
|
|
90
|
+
|
|
91
|
+
A homonym collision is only half-diagnosed when it is classified. The other
|
|
92
|
+
half is the **decision**: which concept keeps the word, and what every other
|
|
93
|
+
sense is called instead. This list carries the decided ones. A word is added
|
|
94
|
+
here when the same term has been observed denoting more than one shipped
|
|
95
|
+
mechanism; it is removed only when the collision is gone from the tree, never
|
|
96
|
+
because the entry became inconvenient.
|
|
97
|
+
|
|
98
|
+
Read the columns as a rename instruction for **prose you write from now on**.
|
|
99
|
+
The identifier layer is decided separately and per cluster, exactly as the
|
|
100
|
+
prose/identifier split above requires — a term may be `canonicalize-term` in
|
|
101
|
+
prose and `keep-distinct` in identifiers, and both verdicts are recorded.
|
|
102
|
+
|
|
103
|
+
| Term | Concept that keeps the word | Other senses, and what to call them | Identifier verdict |
|
|
104
|
+
|---|---|---|---|
|
|
105
|
+
| `envelope` | The **transport wrapper** around a payload — `OutcomeEnvelope` (a run's terminal outcome, `src/scripts/_lib/outcome_envelope.ts`) and the `CHECKPOINT` envelope a worker capsule rides in. | The **session continuity record** is a **capsule**. The word is not chosen for readability — it is the shipped discriminator (`CAPSULE_SCHEMA_VERSION`, `CAPSULE_VARIANTS = ['worker','main_session']`, `src/scripts/_lib/subagent_capsule.ts`), so the surviving term is read off what ships rather than off what reads best. | `keep-distinct` for now. `MainSessionRecycleEnvelope` and `RECYCLE_ENVELOPE_*` keep their names until a rename is costed on its own; the prose rule binds immediately and the symbols are a separate blast radius. |
|
|
106
|
+
| `handoff` | The **session-to-session continuity handover** a developer invokes — the `handoff` verb and the `/agent-handoff` command. | The lint over senior-tier skills' `## Related Skills` edges is a **cross-wing skill link**, never "a handoff". | `keep-distinct`, recorded reason: `lint_handoffs.ts` mirrors a ported CLI contract (ADR-200) whose name is an external surface. Its module docstring already says "cross-wing", which is the disambiguation the prose rule now requires everywhere else. |
|
|
107
|
+
|
|
108
|
+
**Why a list and not a linter.** `lint_canonical_terms` decides *spelling*
|
|
109
|
+
pairs, where one side is mechanically wrong. A homonym is not mechanically
|
|
110
|
+
wrong anywhere — every occurrence is a legitimate word for a legitimate
|
|
111
|
+
concept, and only the reader's inability to tell them apart is the defect. A
|
|
112
|
+
gate that flagged `envelope` would flag the entry that is supposed to survive.
|
|
113
|
+
So this list is enforced at review, by citation, and its cost of being ignored
|
|
114
|
+
is the cost the taxonomy already names: the model telling you it has not
|
|
115
|
+
decided.
|
|
116
|
+
|
|
89
117
|
## Why any of this is worth a gate at all
|
|
90
118
|
|
|
91
119
|
Generated code trends toward duplication rather than reuse: measured
|
package/llms.txt
CHANGED
|
@@ -37,11 +37,11 @@ brand-strategy: Ground a brand strategy from the corpus — archetype, opposable
|
|
|
37
37
|
brand-to-tokens: Turn a confirmed brand identity into a DTCG .tokens.json source of truth — emit CSS vars + Tailwind via design-tokens, export locked brand deck templates.
|
|
38
38
|
bug-analyzer: Use when the user shares a Sentry error, Jira bug ticket, or error description and wants root cause analysis. Also for proactive bug hunting and code audits for hidden bugs.
|
|
39
39
|
build-buy-partner: Use when deciding insource vs outsource vs acquire — integration-cost analysis, dependency-risk, optionality preservation. Triggers on 'should we build', 'buy vs partner'.
|
|
40
|
-
canvas-design:
|
|
40
|
+
canvas-design: Creating static visual art — posters, marketing visuals, brand assets, PDF/PNG design pieces — on 'design a poster' or 'mach uns ein Visual'. Grounded by design-intelligence.
|
|
41
41
|
character-consistency: Use when a character must stay visually identical across AI video scenes — locks identity tokens (silhouette, palette, wardrobe, prop) in JSON. Triggers 'character lock', 'same character'.
|
|
42
42
|
check-refs: Use when verifying cross-references between skills, rules, commands, guidelines, and context documents are not broken after edits, renames, or deletions.
|
|
43
43
|
churn-prevention: Use when designing churn defence — health-score signals, churn-cause split (involuntary / value / relationship / fit), early-warning loop. Triggers on 'why are accounts leaving'.
|
|
44
|
-
code-intelligence: Route codebase-structure questions (who calls X, where used, what imports, change-impact) to
|
|
44
|
+
code-intelligence: Route codebase-structure questions (who calls X, where is this used, what imports, change-impact) to an existing code-graph first: cheaper, never more precise; grep stays routine. Also 'call graph'.
|
|
45
45
|
code-refactoring: When the user says 'refactor this', 'rename class', or 'move method'. Safely refactors code in any language — finds all callers, updates downstream dependencies, verifies via quality tools.
|
|
46
46
|
code-review: Use when the user says \"review this\", \"check my code\", or wants feedback on changes. Reviews for correctness, quality, security, and coding standards.
|
|
47
47
|
command-routing: Use when the user invokes a slash command like /create-pr, /commit, /fix-ci, or pastes command file content — routes to the right command with context inference and GitHub API patterns.
|
|
@@ -57,7 +57,7 @@ context-authoring: Use when filling knowledge-layer context files — auth-model
|
|
|
57
57
|
context-document: Use when the user says \"create context\", \"document this area\", or wants a structured snapshot of a codebase area for agent orientation.
|
|
58
58
|
contract-review: Use when reviewing a contract clause-by-clause from your party's side — buyer/seller/vendor/licensee. Triggers on 'review this contract', 'redline this MSA', 'is this clause a problem'.
|
|
59
59
|
contracts-cognition: Use when reading a contract for risk and constraint — clause shape, redline priority, what the contract actually binds. Triggers on 'review this contract', 'what does this MSA constrain'.
|
|
60
|
-
conventional-commits-writing: When writing commit
|
|
60
|
+
conventional-commits-writing: When writing a commit message, branch name or squash title — measure the repo's own convention first, Conventional Commits as fallback — even on a bare 'commit this'.
|
|
61
61
|
copilot-agents-optimization: Use when optimizing AGENTS.md or copilot-instructions.md — deduplicates against .augment/ content, enforces line budgets, and focuses each file on its audience.
|
|
62
62
|
copilot-config: Tune the GitHub Copilot AI — `copilot-instructions.md`, PR-review patterns, suggestion behavior, output verbosity. NOT for dev-environment setup (use `devcontainer`).
|
|
63
63
|
corpus-grounding: Shared corpus-grounding engine — BM25 + structured filters + decision rules over CSV corpora via a domain manifest. Use when a skill needs grounded pre-action option-space constraints.
|
|
@@ -74,11 +74,11 @@ deep-reading-analyst: Deep analysis of articles/long-form via thinking framework
|
|
|
74
74
|
defense-in-depth: Use when validation needs entry, business-logic, environment, and instrumentation guards so a bad value cannot reach the failure point — turns a local bug fix into a structural one.
|
|
75
75
|
dependency-upgrade: Use when upgrading dependencies — 'update framework X', 'bump runtime version', or 'upgrade packages'. Covers changelog review, breaking-change detection, and verification. Stack-agnostic.
|
|
76
76
|
description-assist: Use when polishing a skill/rule/command/guideline frontmatter description — pushier phrasing, trigger coverage, undertrigger audit — even if the user just says 'make this pushier'.
|
|
77
|
-
design-intelligence: Grounded design brief from the
|
|
78
|
-
design-review: When the user says \"review the design\", \"check the UI\", or wants a comprehensive UI/UX review.
|
|
77
|
+
design-intelligence: Grounded design brief from the corpus — style, WCAG color tokens, typography, layout, anti-patterns. Use on ui-design-brief or any which-style/palette/font/chart call; feeds fe-design.
|
|
78
|
+
design-review: When the user says \"review the design\", \"check the UI\", or wants a comprehensive UI/UX review. 7 phases: interaction, responsiveness, accessibility. Inventory via existing-ui-audit.
|
|
79
79
|
design-system-capture: Write and maintain DESIGN.md + PRODUCT.md — captures visual decisions and interaction patterns so design tasks stay consistent across sessions without re-scanning past work.
|
|
80
80
|
design-tokens: Author a 3-layer DTCG token system (primitive → semantic → component) with light/dark theming; generate CSS vars + Tailwind colors and lint hardcoded values. Use on design tokens / CSS variables.
|
|
81
|
-
design-variations: Produce 3+
|
|
81
|
+
design-variations: Produce 3+ distinct hi-fi design variations — basic to bold, one file with tweak controls — when the user asks for options, alternatives, \"show me a few takes\". Extends fe-design.
|
|
82
82
|
devcontainer: Wire up DevContainers / GitHub Codespaces — `devcontainer.json`, container images, secrets, VS Code features, port forwarding. NOT for tuning Copilot itself (use `copilot-config`).
|
|
83
83
|
developer-like-execution: Use when implementing, debugging, refactoring, or reviewing code — enforces the think → analyze → verify → execute workflow — even when the user just says 'implement X' without naming it.
|
|
84
84
|
discovery-interview: When running discovery interviews — question-bank build, bias audit, insight extraction. Triggers on 'audit my guide', 'extract insights from transcript', 'is my hypothesis falsifiable'.
|
|
@@ -92,10 +92,10 @@ emit-tickets: Use when materialising a roadmap into a ticket bundle — 'turn th
|
|
|
92
92
|
error-handling-patterns: Use when picking a failure-reporting strategy — exceptions vs Result types, recoverable vs not, retry / circuit-breaker / graceful degradation — decision framework only, catalogues externalized.
|
|
93
93
|
"estimate-ticket": Estimate a Jira/Linear ticket — 'estimate PROJ-123', 'wie groß ist das?', 'should we split this?' — size + risk + split + uncertainty, sibling of /refine-ticket, close-prompt.
|
|
94
94
|
evaluate-llm-feature: Black-box evaluation of a shipped LLM feature — adversarial probes for hallucination, prompt-injection, and cost-runaway vs stated expectations. Not RAG/embedding. Triggers 'review my chatbot'.
|
|
95
|
-
existing-ui-audit: Use BEFORE writing or editing any non-trivial UI — inventories components, design tokens, shadcn primitives, and reusable patterns into state.ui_audit. Hard gate for
|
|
95
|
+
existing-ui-audit: Use BEFORE writing or editing any non-trivial UI — inventories components, design tokens, shadcn primitives, and reusable patterns into state.ui_audit. Hard gate for fe-design.
|
|
96
96
|
expansion-playbook: Use when designing account-expansion mechanics — upsell vs cross-sell, expansion-trigger signals, NRR cognition. Triggers on 'lift NRR', 'when do we upsell vs cross-sell'.
|
|
97
97
|
experiment-loop: Use to drive a scalar metric down or up across bounded iterations — keep on strict improvement, revert otherwise, state on disk. Triggers 'minimize X', 'optimize until it stops improving'.
|
|
98
|
-
fe-design: Frontend design heuristics
|
|
98
|
+
fe-design: Frontend design heuristics and the loop applying them: existing-ui-audit, brief, inventory, build, review. Use when building or changing any UI, not only when planning one.
|
|
99
99
|
feature-planning: Use when the user says \"plan a feature\", \"brainstorm\", \"explore this idea\", or wants to go from idea to structured plan and roadmap.
|
|
100
100
|
file-editor: Use when opening edited files in the user's IDE. Reads settings from .agent-settings.yml to determine IDE and whether auto-open is enabled.
|
|
101
101
|
finishing-a-development-branch: Use when the feature is implementation-complete and the next step is 'ship it' — verifies, cleans up, routes to merge/PR/park/discard; never destroys work without explicit confirmation.
|
|
@@ -225,7 +225,7 @@ prompt-optimizer: When the user wants a prompt optimized for ChatGPT, Claude, Ge
|
|
|
225
225
|
prompt-validator: Pre-spend contradiction gate for AI-video runs: checks every prompt in the batch, blocks on style / character / physics mismatch. Triggers 'validate the prompts', 'check the storyboard'.
|
|
226
226
|
quality-tools: Use when PHPStan, Rector, or ECS output appears — \"phpstan says mixed\", type errors, \"fix code style\", \"run rector\" — even when Eloquent/Laravel/model code is also mentioned.
|
|
227
227
|
react-native-setup: Use when setting up React Native or Expo dev environments — Xcode, Android Studio, CocoaPods, EAS, Metro, New Architecture — even when the user just says 'my RN build won't start'.
|
|
228
|
-
react-shadcn-ui:
|
|
228
|
+
react-shadcn-ui: Building React UI on shadcn/ui primitives + Tailwind — the apply/review/polish skill dispatched by `directives/ui/*` for the `react-shadcn` stack; idiom from tailwind-engineer.
|
|
229
229
|
readme-reviewer: Use when reviewing a README for accuracy, usability, and alignment with the actual repository. Detects invented content, broken setup steps, and structural issues.
|
|
230
230
|
readme-writing: Use when creating, rewriting, or significantly improving a README based on the actual repository structure, commands, and intended audience.
|
|
231
231
|
readme-writing-package: Use when creating or rewriting a README for a reusable package or library. Focus on installability, minimal usage example, compatibility, and developer onboarding.
|
|
@@ -275,22 +275,22 @@ subagent-orchestration: Use when orchestrating implementer/judge subagents — f
|
|
|
275
275
|
supply-chain-intake: Before adding/installing any dependency the agent named — verify the package exists (slopsquatting: ~1 in 5 AI suggestions are hallucinated), isn't typo-adjacent, is pinned + locked, and CVE-scanned
|
|
276
276
|
symfony-workflow: Writes Symfony PHP — DI container, bundles, Doctrine, Messenger, Security voters, console commands. For Laravel / Eloquent / Artisan use `laravel`. For framework-free PHP use `php-coder`.
|
|
277
277
|
systematic-debugging: Use on a bug, test failure, crash, or unexpected behavior — enforce reproduce → isolate → hypothesize → verify before any fix; fires even on 'this is broken' / 'quick fix'.
|
|
278
|
-
tailwind-engineer:
|
|
278
|
+
tailwind-engineer: Writing or reviewing Tailwind CSS — utility-first, design tokens, no inline-style drift, responsive variants, dark mode — 'style this' or 'mach das hübsch'. Pairs with react-shadcn-ui.
|
|
279
279
|
tech-debt-tracker: Use when surfacing tech debt as trackable items — interest-vs-principal framing, prioritisation by carrying cost, repayment plan — even if the user just says 'this codebase is a mess'.
|
|
280
280
|
technical-specification: Use when the user says \"write a spec\", \"create RFC\", \"write a PRD\", or \"document this decision\". Writes technical specifications, PRDs, RFCs, and ADRs with clear structure.
|
|
281
281
|
terraform: Use when writing Terraform — AWS modules, resources, variables, outputs, remote state — even when the user just says 'provision this infra' or 'add an S3 bucket' without naming Terraform.
|
|
282
282
|
terragrunt: Use when working with Terragrunt — DRY multi-env configs, module dependencies, remote state orchestration — even when the user just says 'deploy this to staging and prod' without naming Terragrunt.
|
|
283
283
|
test-case-discovery: Use BEFORE writing any test — enumerate cases per behavior (happy / boundary / error / abuse), prioritize by likelihood × impact, cross-check via subagent — even if the user just says 'add tests'.
|
|
284
|
-
test-driven-development:
|
|
284
|
+
test-driven-development: Implementing a feature, fixing a bug, refactoring — failing test first, then the code. For a WRONG test, `testing-anti-patterns` wins.
|
|
285
285
|
test-performance: Use when optimizing test suite performance — database setup, seeder optimization, parallel testing, CI pipeline efficiency, or RefreshDatabase alternatives.
|
|
286
|
-
testing-anti-patterns:
|
|
286
|
+
testing-anti-patterns: BEFORE writing/changing tests, mocks, or test-only methods on production classes — mocking-the-mock, production pollution, overfit assertions; for order, `test-driven-development` wins.
|
|
287
287
|
threat-modeling: Use when adding auth, webhooks, uploads, queues, secrets, tenant boundaries, or public endpoints — produces trust boundaries + abuse cases mapped to files, BEFORE implementation.
|
|
288
288
|
throughput-vs-morale-tradeoff: Use when balancing eng-team velocity vs quality vs burnout — on-call load, focus fragmentation, reorg shock. Triggers on 'team is burning out', 'why is velocity dropping'.
|
|
289
289
|
token-optimizer: Use BEFORE any verbose CLI run, large file read, doc conversion, or near-context handoff — decision tree keyed by intent citing the canonical token-saving asset.
|
|
290
290
|
traefik: Use when setting up Traefik as a local reverse proxy — real domains on 127.0.0.1, trusted HTTPS via mkcert, automatic service discovery, and multi-project routing.
|
|
291
291
|
typography-system: Derive a type system from a style constraint — font pairings, scale/line-height/weights, DTCG tokens via design-tokens. Use to choose fonts or build a typographic scale.
|
|
292
|
-
ui-apply-generic: Use when implementing a UI brief on a stack with no framework executor — Svelte, Astro, Angular, plain HTML.
|
|
293
|
-
ui-component-architect:
|
|
292
|
+
ui-apply-generic: Use when implementing a UI brief on a stack with no framework executor — Svelte, Astro, Angular, plain HTML. Stack-independent sibling of react-shadcn-ui; idiom from the stack corpus.
|
|
293
|
+
ui-component-architect: Shaping a UI component tree — composition vs inheritance, slot patterns, prop API design, controlled vs uncontrolled, polymorphic — on 'split this component'. Feeds react-shadcn-ui.
|
|
294
294
|
unit-economics-modeling: Use when modeling CAC, LTV, payback, contribution margin, or burn-multiple per customer — SaaS, marketplace, or transactional. Triggers on 'are we unit-economic', 'what is our LTV/CAC'.
|
|
295
295
|
universal-project-analysis: Deep multi-pass codebase audit — orchestrates project-analysis-core plus the framework-specific project-analysis-*; explicit request only. Single-pass scan → project-analyzer.
|
|
296
296
|
upstream-contribute: Use when a learning, new skill, rule improvement, or bug fix from a consumer project should be contributed back to the shared agent-config package.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
3
|
"mcpName": "io.github.event4u-app/agent-config",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.21.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including the counts in these badges.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|