@event4u/agent-config 8.13.0 → 9.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 +136 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +35 -0
- package/dist/agent-src/commands/agents/init.md +1 -0
- package/dist/agent-src/commands/agents/optimize.md +1 -0
- package/dist/agent-src/commands/agents/user/accept.md +3 -2
- package/dist/agent-src/commands/agents/user/init.md +5 -4
- package/dist/agent-src/commands/agents/user/update.md +3 -2
- package/dist/agent-src/commands/agents/user.md +1 -0
- package/dist/agent-src/commands/agents.md +1 -0
- package/dist/agent-src/commands/analytics/show.md +1 -0
- package/dist/agent-src/commands/analytics.md +1 -0
- package/dist/agent-src/commands/analyze/decision.md +1 -0
- package/dist/agent-src/commands/analyze/incident.md +1 -0
- package/dist/agent-src/commands/analyze/near-miss.md +1 -0
- package/dist/agent-src/commands/analyze/postmortem.md +1 -0
- package/dist/agent-src/commands/analyze/premortem.md +1 -0
- package/dist/agent-src/commands/analyze/reference-repo.md +1 -0
- package/dist/agent-src/commands/analyze.md +3 -2
- package/dist/agent-src/commands/brand/identity.md +6 -5
- package/dist/agent-src/commands/brand/review.md +6 -5
- package/dist/agent-src/commands/brand/strategy.md +6 -4
- package/dist/agent-src/commands/brand/tokens.md +7 -6
- package/dist/agent-src/commands/brand/voice.md +5 -4
- package/dist/agent-src/commands/brand.md +9 -7
- package/dist/agent-src/commands/bug/fix.md +1 -0
- package/dist/agent-src/commands/bug/investigate.md +1 -0
- package/dist/agent-src/commands/bug.md +2 -1
- package/dist/agent-src/commands/challenge-me/vision.md +1 -0
- package/dist/agent-src/commands/challenge-me/with-docs.md +1 -0
- package/dist/agent-src/commands/challenge-me.md +28 -6
- package/dist/agent-src/commands/chat-history.md +1 -0
- package/dist/agent-src/commands/check-current-md.md +1 -0
- package/dist/agent-src/commands/commit.md +1 -0
- package/dist/agent-src/commands/context/create.md +3 -2
- package/dist/agent-src/commands/context.md +1 -0
- package/dist/agent-src/commands/cost/profile.md +1 -0
- package/dist/agent-src/commands/cost.md +2 -1
- package/dist/agent-src/commands/council/analysis.md +1 -0
- package/dist/agent-src/commands/council/debate.md +1 -0
- package/dist/agent-src/commands/council/default.md +21 -20
- package/dist/agent-src/commands/council/design.md +1 -0
- package/dist/agent-src/commands/council/optimize.md +1 -0
- package/dist/agent-src/commands/council/pr.md +1 -0
- package/dist/agent-src/commands/council.md +1 -0
- package/dist/agent-src/commands/estimate-ticket.md +1 -0
- package/dist/agent-src/commands/feature/dev.md +1 -0
- package/dist/agent-src/commands/feature/explore.md +1 -0
- package/dist/agent-src/commands/feature/plan.md +1 -0
- package/dist/agent-src/commands/feature/refactor.md +1 -0
- package/dist/agent-src/commands/feature/roadmap.md +1 -0
- package/dist/agent-src/commands/feature.md +2 -1
- package/dist/agent-src/commands/fix/pr-comments.md +19 -0
- package/dist/agent-src/commands/fix.md +2 -1
- package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
- package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
- package/dist/agent-src/commands/ghostwriter/show.md +1 -0
- package/dist/agent-src/commands/ghostwriter/write.md +1 -0
- package/dist/agent-src/commands/ghostwriter.md +1 -0
- package/dist/agent-src/commands/grill-me.md +17 -12
- package/dist/agent-src/commands/humanize.md +1 -0
- package/dist/agent-src/commands/image/analyse.md +2 -1
- package/dist/agent-src/commands/image/create.md +1 -0
- package/dist/agent-src/commands/image/verify.md +1 -0
- package/dist/agent-src/commands/image.md +16 -12
- package/dist/agent-src/commands/implement-ticket.md +1 -0
- package/dist/agent-src/commands/judge/on-diff.md +1 -0
- package/dist/agent-src/commands/judge/solo.md +1 -0
- package/dist/agent-src/commands/judge/steps.md +1 -0
- package/dist/agent-src/commands/judge.md +1 -0
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
- package/dist/agent-src/commands/knowledge/forget.md +1 -0
- package/dist/agent-src/commands/knowledge/ingest.md +1 -0
- package/dist/agent-src/commands/knowledge/list.md +10 -0
- package/dist/agent-src/commands/knowledge.md +1 -0
- package/dist/agent-src/commands/memory/learn-low-impact.md +1 -0
- package/dist/agent-src/commands/memory/mine-session.md +1 -0
- package/dist/agent-src/commands/memory/promote.md +3 -2
- package/dist/agent-src/commands/memory.md +1 -0
- package/dist/agent-src/commands/mission/upgrade.md +45 -24
- package/dist/agent-src/commands/mode.md +1 -0
- package/dist/agent-src/commands/module/create.md +1 -0
- package/dist/agent-src/commands/module/explore.md +1 -0
- package/dist/agent-src/commands/module.md +1 -0
- package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
- package/dist/agent-src/commands/optimize/project.md +1 -0
- package/dist/agent-src/commands/optimize/prompt.md +1 -0
- package/dist/agent-src/commands/optimize.md +2 -1
- package/dist/agent-src/commands/orchestrate.md +1 -0
- package/dist/agent-src/commands/override.md +1 -0
- package/dist/agent-src/commands/package.md +2 -1
- package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
- package/dist/agent-src/commands/post-as/me.md +1 -0
- package/dist/agent-src/commands/post-as.md +1 -0
- package/dist/agent-src/commands/pr/create/description-only.md +1 -0
- package/dist/agent-src/commands/pr/create.md +19 -17
- package/dist/agent-src/commands/prediction-pool.md +7 -6
- package/dist/agent-src/commands/prepare-for-review.md +1 -0
- package/dist/agent-src/commands/profile/activate.md +1 -0
- package/dist/agent-src/commands/profile/deactivate.md +1 -0
- package/dist/agent-src/commands/profile.md +1 -0
- package/dist/agent-src/commands/project.md +2 -1
- package/dist/agent-src/commands/refine-ticket.md +7 -0
- package/dist/agent-src/commands/research/deep.md +1 -0
- package/dist/agent-src/commands/research.md +1 -0
- package/dist/agent-src/commands/review/routing.md +1 -0
- package/dist/agent-src/commands/review.md +2 -1
- package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
- package/dist/agent-src/commands/roadmap/materialize.md +1 -0
- package/dist/agent-src/commands/roadmap/process-full.md +1 -0
- package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
- package/dist/agent-src/commands/roadmap/process-step.md +1 -0
- package/dist/agent-src/commands/roadmap.md +1 -0
- package/dist/agent-src/commands/security-audit-config.md +2 -1
- package/dist/agent-src/commands/skill/preview.md +1 -0
- package/dist/agent-src/commands/skill.md +1 -0
- package/dist/agent-src/commands/skills/discover.md +1 -0
- package/dist/agent-src/commands/skills.md +1 -0
- package/dist/agent-src/commands/sync/agent-settings.md +1 -0
- package/dist/agent-src/commands/sync.md +2 -1
- package/dist/agent-src/commands/team/adversarial.md +3 -2
- package/dist/agent-src/commands/team/delegate.md +3 -2
- package/dist/agent-src/commands/team/review.md +3 -2
- package/dist/agent-src/commands/team/status.md +49 -18
- package/dist/agent-src/commands/team-knowledge.md +8 -6
- package/dist/agent-src/commands/team.md +21 -16
- package/dist/agent-src/commands/tests/e2e-heal.md +1 -0
- package/dist/agent-src/commands/tests/e2e-plan.md +1 -0
- package/dist/agent-src/commands/tests/execute.md +1 -0
- package/dist/agent-src/commands/tests.md +2 -1
- package/dist/agent-src/commands/update-form-request-messages.md +1 -0
- package/dist/agent-src/commands/upstream-contribute.md +1 -0
- package/dist/agent-src/commands/video/from-script.md +3 -2
- package/dist/agent-src/commands/video/from-song.md +22 -21
- package/dist/agent-src/commands/video/scene.md +1 -0
- package/dist/agent-src/commands/video/stitch.md +2 -1
- package/dist/agent-src/commands/video/storyboard.md +1 -0
- package/dist/agent-src/commands/video.md +1 -0
- package/dist/agent-src/commands/work.md +1 -0
- package/dist/agent-src/commands/worktree/cleanup.md +8 -7
- package/dist/agent-src/commands/worktree/create.md +1 -0
- package/dist/agent-src/commands/worktree/verify.md +1 -0
- package/dist/agent-src/commands/worktree.md +1 -0
- package/dist/agent-src/rules/active-remediation.md +12 -36
- package/dist/agent-src/rules/artifact-drafting-protocol.md +7 -64
- package/dist/agent-src/rules/context-hygiene.md +19 -113
- package/dist/agent-src/rules/design-fidelity.md +4 -60
- package/dist/agent-src/rules/domain-adoption-policy.md +10 -106
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +12 -60
- package/dist/agent-src/rules/improve-before-implement.md +4 -0
- package/dist/agent-src/rules/minimal-safe-diff.md +6 -86
- package/dist/agent-src/rules/size-enforcement.md +10 -0
- package/dist/agent-src/rules/tool-safety.md +17 -3
- package/dist/agent-src/skills/agent-security-review/SKILL.md +12 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -0
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +24 -2
- package/dist/agent-src/skills/code-review/SKILL.md +105 -93
- package/dist/agent-src/skills/code-review/checklists/backend.md +50 -0
- package/dist/agent-src/skills/code-review/checklists/database.md +19 -0
- package/dist/agent-src/skills/code-review/checklists/dependency.md +18 -0
- package/dist/agent-src/skills/code-review/checklists/docs.md +14 -0
- package/dist/agent-src/skills/code-review/checklists/frontend.md +19 -0
- package/dist/agent-src/skills/code-review/checklists/infra.md +17 -0
- package/dist/agent-src/skills/code-review/checklists/producing-the-review.md +62 -0
- package/dist/agent-src/skills/code-review/checklists/test-only.md +13 -0
- package/dist/agent-src/skills/code-review/evals/evals.json +53 -15
- package/dist/agent-src/skills/condense-memory/SKILL.md +3 -2
- package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +15 -0
- package/dist/agent-src/skills/docker/SKILL.md +10 -0
- package/dist/agent-src/skills/docx-authoring/SKILL.md +102 -0
- package/dist/agent-src/skills/github-ci/evals/evals.json +25 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +79 -3
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +112 -0
- package/dist/agent-src/skills/humanizer/references/fixtures.md +70 -0
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +7 -1
- package/dist/agent-src/skills/laravel/SKILL.md +10 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +35 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +30 -0
- package/dist/agent-src/skills/pdf-tools/SKILL.md +101 -0
- package/dist/agent-src/skills/quality-tools/evals/evals.json +15 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +29 -0
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +90 -0
- package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +52 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +79 -0
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +11 -3
- package/dist/agent-src/skills/subagent-orchestration/schemas/team-review-status.json +103 -0
- package/dist/agent-src/skills/terraform/SKILL.md +10 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +31 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +15 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/dist/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
- package/dist/agent-src/templates/scripts/telemetry_record.ts +5 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +256 -190
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +20 -17
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +16 -13
- package/dist/install/install.mjs +10 -2
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/router.json +1 -1
- package/dist/scripts/condense.js +5 -0
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +5 -1
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/CLAIMS.md +8 -1
- package/docs/SKILL_CENSUS.md +8 -0
- package/docs/architecture.md +2 -2
- package/docs/benchmark.md +67 -2
- package/docs/catalog.md +2 -2
- package/docs/contracts/ai-council-config.md +9 -2
- package/docs/contracts/ai-team-config.md +37 -4
- package/docs/contracts/prelaunch-diagnostics.md +151 -0
- package/docs/contracts/release-pr-gating.md +1 -0
- package/docs/decisions/ADR-049-configuration-trust-boundary.md +9 -1
- package/docs/featured-skills.md +2 -2
- package/docs/getting-started-by-role.md +1 -1
- package/docs/getting-started.md +16 -5
- package/docs/governance-advantage.md +1 -1
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +45 -0
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +28 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +76 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +90 -0
- package/docs/guidelines/agent-infra/domain-adoption-gates.md +112 -0
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +99 -0
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +13 -0
- package/docs/guidelines/design-fidelity-mechanics.md +76 -0
- package/docs/parity/command-frontmatter.md +60 -0
- package/docs/proof.md +6 -5
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
- package/src/agent-src/templates/scripts/telemetry_record.ts +5 -0
- package/src/config/agent-settings.template.yml +34 -10
- package/src/config/prelaunch-areas.yml +36 -0
- package/src/scripts/_cli/cmd_doctor.ts +118 -26
- package/src/scripts/_lib/claude_plugin.ts +77 -2
- package/src/scripts/_lib/orchestration_record.ts +5 -0
- package/src/scripts/_lib/tool_adapter_registry.ts +120 -0
- package/src/scripts/ai_team/config.ts +73 -1
- package/src/scripts/ai_team/review_gate.ts +636 -0
- package/src/scripts/ai_team/team_dispatch.ts +612 -0
- package/src/scripts/bench_ab_task_runner.ts +11 -1
- package/src/scripts/bench_parity_count.ts +279 -0
- package/src/scripts/build_linear_digest.ts +3 -1
- package/src/scripts/check_bridge_derivation.ts +172 -0
- package/src/scripts/check_consumer_scope_flip.ts +179 -0
- package/src/scripts/check_council_config_location.ts +115 -15
- package/src/scripts/check_host_loadability.ts +81 -0
- package/src/scripts/condense.ts +5 -0
- package/src/scripts/hook_manifest.yaml +12 -1
- package/src/scripts/lint_handoffs.ts +42 -0
- package/src/scripts/lint_skill_descriptions.ts +228 -0
- package/src/scripts/lint_skill_descriptions_allowlist.json +1 -0
- package/src/scripts/lint_skill_scripts_readonly.ts +145 -0
- package/src/scripts/lint_skill_scripts_readonly_allowlist.json +8 -0
- package/src/scripts/lint_supported_tools_matrix.ts +35 -0
- package/src/scripts/optimize_skill_description.ts +144 -0
- package/src/scripts/orchestration_record.ts +2 -1
- package/src/scripts/prelaunch_diagnostics.ts +248 -0
- package/src/scripts/run_skill_evals.ts +70 -4
- package/src/scripts/schemas/command.schema.json +7 -0
- package/src/scripts/schemas/evals.schema.json +105 -14
- package/src/scripts/schemas/prelaunch-report.schema.json +107 -0
- package/src/scripts/schemas/skill.schema.json +18 -1
- package/src/scripts/schemas/subagent.schema.json +6 -0
- package/src/scripts/skill_linter.ts +43 -3
- package/src/scripts/smoke_host_loadability.sh +73 -0
- package/src/scripts/team_review_gate_hook.ts +115 -0
- package/src/scripts/trigger_eval_grandfather.json +1 -2
- package/src/scripts/utilization_report.ts +225 -0
- package/src/server/schemas/settings.ts +9 -1
|
@@ -105,10 +105,15 @@ export function _spawn_subagent(
|
|
|
105
105
|
*
|
|
106
106
|
* Deterministic on purpose: this only *counts*. The substantive judgement —
|
|
107
107
|
* is each match a real finding, and what should `n` be per host — is the
|
|
108
|
-
* calibration layer
|
|
109
|
-
*
|
|
110
|
-
* `
|
|
111
|
-
*
|
|
108
|
+
* calibration layer. CALIBRATED 2026-07-12: the cross-model count-distribution
|
|
109
|
+
* pass (`bench_parity_count.ts`, design in
|
|
110
|
+
* `docs/design/cross-model-parity-eval.md`) recorded per-host finding-count
|
|
111
|
+
* distributions over the orchestration corpus for 2 vendors and derived
|
|
112
|
+
* per-task floors from the cross-host lower envelope
|
|
113
|
+
* (`internal/bench/reports/parity-count.json`). `finding_floor` is therefore an
|
|
114
|
+
* ENFORCING gate: a fixture's `n` is justified against the cross-vendor norm,
|
|
115
|
+
* not one vendor's output shape. New floors follow the same envelope rule
|
|
116
|
+
* (max(1, min over hosts of median count); negative controls excluded).
|
|
112
117
|
*/
|
|
113
118
|
export function _count_findings(output: string, pattern?: string): number {
|
|
114
119
|
if (pattern !== undefined && pattern !== '') {
|
|
@@ -130,6 +135,31 @@ export function _count_findings(output: string, pattern?: string): number {
|
|
|
130
135
|
return count;
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Load the recorded tool trace from `<run_dir>/tool-trace.json` — an array of
|
|
140
|
+
* tool-call names (strings) or `{tool: string}` objects. Returns null when the
|
|
141
|
+
* file is absent (→ tool-choice / trajectory assertions report manual-pending).
|
|
142
|
+
*/
|
|
143
|
+
export function _load_tool_trace(run_dir: string): string[] | null {
|
|
144
|
+
const p = path.join(run_dir, 'tool-trace.json');
|
|
145
|
+
if (!_exists(p)) return null;
|
|
146
|
+
const raw = JSON.parse(fs.readFileSync(p, 'utf-8')) as Array<string | { tool?: string }>;
|
|
147
|
+
if (!Array.isArray(raw)) return null;
|
|
148
|
+
return raw.map((e) => (typeof e === 'string' ? e : (e.tool ?? ''))).filter((s) => s !== '');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Count meaningful steps: tool calls net of retries (a call whose name equals
|
|
152
|
+
* the immediately-preceding call name is a retry, not a new step). */
|
|
153
|
+
export function _count_meaningful_steps(trace: string[]): number {
|
|
154
|
+
let steps = 0;
|
|
155
|
+
let prev: string | null = null;
|
|
156
|
+
for (const t of trace) {
|
|
157
|
+
if (t !== prev) steps += 1;
|
|
158
|
+
prev = t;
|
|
159
|
+
}
|
|
160
|
+
return steps;
|
|
161
|
+
}
|
|
162
|
+
|
|
133
163
|
export function _grade_assertions(
|
|
134
164
|
output: string,
|
|
135
165
|
run_dir: string,
|
|
@@ -141,6 +171,10 @@ export function _grade_assertions(
|
|
|
141
171
|
if (kind === 'contains') {
|
|
142
172
|
const ok = output.includes(a['value'] as string);
|
|
143
173
|
results.push({ kind, value: a['value'] as JsonValue, pass: ok });
|
|
174
|
+
} else if (kind === 'not_contains') {
|
|
175
|
+
// U2 golden-adversarial negative: benign look-alikes must NOT be flagged.
|
|
176
|
+
const ok = !output.includes(a['value'] as string);
|
|
177
|
+
results.push({ kind, value: a['value'] as JsonValue, pass: ok });
|
|
144
178
|
} else if (kind === 'file_exists') {
|
|
145
179
|
const apath = a['path'] as string;
|
|
146
180
|
const ok = _exists(path.join(run_dir, apath)) || _exists(apath);
|
|
@@ -157,6 +191,38 @@ export function _grade_assertions(
|
|
|
157
191
|
const pattern = a['pattern'] as string | undefined;
|
|
158
192
|
const count = _count_findings(output, pattern);
|
|
159
193
|
results.push({ kind, n, count, pass: count >= n });
|
|
194
|
+
} else if (kind === 'tool-choice') {
|
|
195
|
+
// Evaluated against the recorded tool trace (<run_dir>/tool-trace.json).
|
|
196
|
+
// No trace (e.g. scaffold-only / CI without a live run) → manual-pending,
|
|
197
|
+
// NEVER a silent pass.
|
|
198
|
+
const mustUse = (a['must_use'] as string[] | undefined) ?? [];
|
|
199
|
+
const mustNot = (a['must_not_use'] as string[] | undefined) ?? [];
|
|
200
|
+
const trace = _load_tool_trace(run_dir);
|
|
201
|
+
if (trace === null) {
|
|
202
|
+
results.push({
|
|
203
|
+
kind, must_use: mustUse, must_not_use: mustNot, pass: null,
|
|
204
|
+
note: 'manual-pending: no tool-trace.json in run dir — record a trace or grade manually',
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
const used = new Set(trace);
|
|
208
|
+
const missing = mustUse.filter((t) => !used.has(t));
|
|
209
|
+
const forbidden = mustNot.filter((t) => used.has(t));
|
|
210
|
+
results.push({
|
|
211
|
+
kind, must_use: mustUse, must_not_use: mustNot,
|
|
212
|
+
missing, forbidden, pass: missing.length === 0 && forbidden.length === 0,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
} else if (kind === 'trajectory_budget') {
|
|
216
|
+
// Meaningful step = one tool call net of retries (a retry is a call whose
|
|
217
|
+
// tool name repeats the immediately-preceding call). No trace → manual-pending.
|
|
218
|
+
const budget = a['n'] as number;
|
|
219
|
+
const trace = _load_tool_trace(run_dir);
|
|
220
|
+
if (trace === null) {
|
|
221
|
+
results.push({ kind, n: budget, pass: null, note: 'manual-pending: no tool-trace.json in run dir' });
|
|
222
|
+
} else {
|
|
223
|
+
const steps = _count_meaningful_steps(trace);
|
|
224
|
+
results.push({ kind, n: budget, steps, pass: steps <= budget });
|
|
225
|
+
}
|
|
160
226
|
} else {
|
|
161
227
|
results.push({ kind: kind ?? null, pass: false, note: `unknown assertion kind ${_pyRepr(kind)}` });
|
|
162
228
|
}
|
|
@@ -35,6 +35,13 @@
|
|
|
35
35
|
"default": true,
|
|
36
36
|
"description": "Commands are always user-invoked; model-invocation is disabled."
|
|
37
37
|
},
|
|
38
|
+
"argument-hint": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"minLength": 1,
|
|
41
|
+
"maxLength": 120,
|
|
42
|
+
"description": "Official-spec argument hint shown next to the slash command in hosts that render one (Claude Code). Bracket notation: `<required>` / `[optional]`, e.g. '<ticket-key | url> [notes]'. Set on every command whose body documents an invocation argument; omit on zero-argument commands. Projection: commands symlink into .claude/skills/<slug>/SKILL.md, so the field reaches Claude Code verbatim; other hosts ignore it (see docs/parity/command-frontmatter.md).",
|
|
43
|
+
"$comment": "road-to-ecosystem-harvest-skill-quality-gates Phase 4, Source C (official CLI command-authoring standard)."
|
|
44
|
+
},
|
|
38
45
|
"skills": {
|
|
39
46
|
"type": "array",
|
|
40
47
|
"items": {
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
"$id": "https://github.com/event4u-app/agent-config/scripts/schemas/evals.schema.json",
|
|
4
4
|
"x-schemaVersion": "1.0.0",
|
|
5
5
|
"title": "Skill behavioural evals (evals.json)",
|
|
6
|
-
"$comment": "Behavioural-eval spec consumed by run_skill_evals.ts (scaffold/aggregate/report) and counted by skill_eval_coverage.ts. Distinct from triggers.json (activation/routing axis). Roadmap: road-to-skill-eval-coverage Phase 1. Assertion kinds mirror _grade_assertions() in run_skill_evals.ts exactly
|
|
6
|
+
"$comment": "Behavioural-eval spec consumed by run_skill_evals.ts (scaffold/aggregate/report) and counted by skill_eval_coverage.ts. Distinct from triggers.json (activation/routing axis). Roadmap: road-to-skill-eval-coverage Phase 1. Assertion kinds mirror _grade_assertions() in run_skill_evals.ts exactly \u2014 add a kind there before adding it here.",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
|
9
|
-
"required": [
|
|
9
|
+
"required": [
|
|
10
|
+
"skill",
|
|
11
|
+
"scenarios"
|
|
12
|
+
],
|
|
10
13
|
"properties": {
|
|
11
14
|
"skill": {
|
|
12
15
|
"type": "string",
|
|
@@ -20,7 +23,7 @@
|
|
|
20
23
|
"skill_body_sha": {
|
|
21
24
|
"type": "string",
|
|
22
25
|
"pattern": "^[0-9a-f]{64}$",
|
|
23
|
-
"description": "Optional SHA-256 of the skill's SKILL.md body at the time these evals were authored/last verified. When present, lint_behavioural_eval_freshness flags the eval stale if the current SKILL.md sha differs
|
|
26
|
+
"description": "Optional SHA-256 of the skill's SKILL.md body at the time these evals were authored/last verified. When present, lint_behavioural_eval_freshness flags the eval stale if the current SKILL.md sha differs \u2014 the body changed, so the eval may no longer exercise it. Absent = unpinned (out of scope for the staleness gate), mirroring lint_eval_freshness's upstream:null handling."
|
|
24
27
|
},
|
|
25
28
|
"scenarios": {
|
|
26
29
|
"type": "array",
|
|
@@ -29,7 +32,11 @@
|
|
|
29
32
|
"items": {
|
|
30
33
|
"type": "object",
|
|
31
34
|
"additionalProperties": false,
|
|
32
|
-
"required": [
|
|
35
|
+
"required": [
|
|
36
|
+
"id",
|
|
37
|
+
"prompt",
|
|
38
|
+
"assertions"
|
|
39
|
+
],
|
|
33
40
|
"properties": {
|
|
34
41
|
"id": {
|
|
35
42
|
"type": "string",
|
|
@@ -41,6 +48,20 @@
|
|
|
41
48
|
"minLength": 1,
|
|
42
49
|
"description": "The input fixture handed to the skill under test."
|
|
43
50
|
},
|
|
51
|
+
"environment": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"minLength": 1,
|
|
54
|
+
"description": "Optional precondition note (v2, additive) — the environment the scenario assumes (e.g. 'a git repo with an open PR', 'quality.local_auto_run: true'). Advisory context for the runner/operator; not graded."
|
|
55
|
+
},
|
|
56
|
+
"requires_human": {
|
|
57
|
+
"type": "boolean",
|
|
58
|
+
"description": "Optional (v2, additive). When true, the scenario cannot be auto-graded in CI — the runner skips it and reports `manual-pending` (NEVER a silent pass). Pair with human_instructions."
|
|
59
|
+
},
|
|
60
|
+
"human_instructions": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"minLength": 1,
|
|
63
|
+
"description": "Optional (v2, additive). Steps for a human to grade a requires_human scenario."
|
|
64
|
+
},
|
|
44
65
|
"assertions": {
|
|
45
66
|
"type": "array",
|
|
46
67
|
"minItems": 1,
|
|
@@ -50,9 +71,14 @@
|
|
|
50
71
|
{
|
|
51
72
|
"type": "object",
|
|
52
73
|
"additionalProperties": false,
|
|
53
|
-
"required": [
|
|
74
|
+
"required": [
|
|
75
|
+
"kind",
|
|
76
|
+
"value"
|
|
77
|
+
],
|
|
54
78
|
"properties": {
|
|
55
|
-
"kind": {
|
|
79
|
+
"kind": {
|
|
80
|
+
"const": "contains"
|
|
81
|
+
},
|
|
56
82
|
"value": {
|
|
57
83
|
"type": "string",
|
|
58
84
|
"minLength": 1,
|
|
@@ -63,9 +89,14 @@
|
|
|
63
89
|
{
|
|
64
90
|
"type": "object",
|
|
65
91
|
"additionalProperties": false,
|
|
66
|
-
"required": [
|
|
92
|
+
"required": [
|
|
93
|
+
"kind",
|
|
94
|
+
"path"
|
|
95
|
+
],
|
|
67
96
|
"properties": {
|
|
68
|
-
"kind": {
|
|
97
|
+
"kind": {
|
|
98
|
+
"const": "file_exists"
|
|
99
|
+
},
|
|
69
100
|
"path": {
|
|
70
101
|
"type": "string",
|
|
71
102
|
"minLength": 1,
|
|
@@ -76,13 +107,18 @@
|
|
|
76
107
|
{
|
|
77
108
|
"type": "object",
|
|
78
109
|
"additionalProperties": false,
|
|
79
|
-
"required": [
|
|
110
|
+
"required": [
|
|
111
|
+
"kind",
|
|
112
|
+
"n"
|
|
113
|
+
],
|
|
80
114
|
"properties": {
|
|
81
|
-
"kind": {
|
|
115
|
+
"kind": {
|
|
116
|
+
"const": "finding_floor"
|
|
117
|
+
},
|
|
82
118
|
"n": {
|
|
83
119
|
"type": "integer",
|
|
84
120
|
"minimum": 0,
|
|
85
|
-
"description": "Minimum number of findings the output must carry (counted deterministically). 0 is a trivially-passing floor (the grader passes when count >= n)
|
|
121
|
+
"description": "Minimum number of findings the output must carry (counted deterministically). 0 is a trivially-passing floor (the grader passes when count >= n) \u2014 used where the case only guards against over-reporting."
|
|
86
122
|
},
|
|
87
123
|
"pattern": {
|
|
88
124
|
"type": "string",
|
|
@@ -93,13 +129,68 @@
|
|
|
93
129
|
{
|
|
94
130
|
"type": "object",
|
|
95
131
|
"additionalProperties": false,
|
|
96
|
-
"required": [
|
|
132
|
+
"required": [
|
|
133
|
+
"kind",
|
|
134
|
+
"criterion"
|
|
135
|
+
],
|
|
97
136
|
"properties": {
|
|
98
|
-
"kind": {
|
|
137
|
+
"kind": {
|
|
138
|
+
"const": "rubric"
|
|
139
|
+
},
|
|
99
140
|
"criterion": {
|
|
100
141
|
"type": "string",
|
|
101
142
|
"minLength": 1,
|
|
102
|
-
"description": "Natural-language pass criterion graded by a sub-agent. NON-deterministic
|
|
143
|
+
"description": "Natural-language pass criterion graded by a sub-agent. NON-deterministic \u2014 the grader returns pass:null until a pinned judge fills it. Use only where no deterministic check exists; record the judge as a known limit."
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"type": "object",
|
|
149
|
+
"additionalProperties": false,
|
|
150
|
+
"required": [
|
|
151
|
+
"kind",
|
|
152
|
+
"value"
|
|
153
|
+
],
|
|
154
|
+
"properties": {
|
|
155
|
+
"kind": {
|
|
156
|
+
"const": "not_contains"
|
|
157
|
+
},
|
|
158
|
+
"value": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"minLength": 1,
|
|
161
|
+
"description": "Substring the output must contain (deterministic)."
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"required": ["kind"],
|
|
169
|
+
"properties": {
|
|
170
|
+
"kind": { "const": "tool-choice" },
|
|
171
|
+
"must_use": {
|
|
172
|
+
"type": "array",
|
|
173
|
+
"items": { "type": "string", "minLength": 1 },
|
|
174
|
+
"description": "Tool names the run MUST have called (checked against <run_dir>/tool-trace.json). v2, additive."
|
|
175
|
+
},
|
|
176
|
+
"must_not_use": {
|
|
177
|
+
"type": "array",
|
|
178
|
+
"items": { "type": "string", "minLength": 1 },
|
|
179
|
+
"description": "Tool names the run MUST NOT have called. v2, additive."
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"$comment": "Evaluated against the recorded tool trace. No trace present → pass:null manual-pending, never a silent pass."
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"type": "object",
|
|
186
|
+
"additionalProperties": false,
|
|
187
|
+
"required": ["kind", "n"],
|
|
188
|
+
"properties": {
|
|
189
|
+
"kind": { "const": "trajectory_budget" },
|
|
190
|
+
"n": {
|
|
191
|
+
"type": "integer",
|
|
192
|
+
"minimum": 1,
|
|
193
|
+
"description": "Ceiling on meaningful steps = tool calls net of retries (a call repeating the immediately-preceding call name is a retry, not a step). Counted from <run_dir>/tool-trace.json; no trace → manual-pending. v2, additive."
|
|
103
194
|
}
|
|
104
195
|
}
|
|
105
196
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/event4u-app/agent-config/scripts/schemas/prelaunch-report.schema.json",
|
|
4
|
+
"x-schemaVersion": "1.0.0",
|
|
5
|
+
"title": "Pre-launch diagnostic report",
|
|
6
|
+
"$comment": "road-to-ecosystem-harvest-prelaunch-diagnostics Phase 1 (Source L). Contract: docs/contracts/prelaunch-diagnostics.md. Area vocabulary: src/config/prelaunch-areas.yml. Epistemics: pass requires evidence; absence of findings is unknown, never an automatic pass; not-applicable requires a reason. NO numeric score field — the 0-100 score is council-locked (revisit note in the roadmap); adding one here is a contract violation.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": ["schema_version", "project", "run_at", "areas", "findings"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"schema_version": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"enum": ["prelaunch-report-v1"]
|
|
14
|
+
},
|
|
15
|
+
"project": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "Consumer project identifier (repo slug or name)."
|
|
19
|
+
},
|
|
20
|
+
"run_at": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1,
|
|
23
|
+
"description": "ISO-8601 timestamp of the diagnostic run."
|
|
24
|
+
},
|
|
25
|
+
"areas": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"description": "Per-area epistemic state. Keys come from src/config/prelaunch-areas.yml. An area missing here is UNKNOWN by definition.",
|
|
29
|
+
"patternProperties": {
|
|
30
|
+
"^[a-z][a-z0-9-]*$": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"required": ["state"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"state": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"enum": ["pass", "finding", "unknown", "not-applicable"],
|
|
38
|
+
"description": "pass = evidence-cited clean; finding = at least one open finding (IDs in findings[]); unknown = not diagnosed — NEVER an automatic pass; not-applicable = does not exist on this launch surface (reason required)."
|
|
39
|
+
},
|
|
40
|
+
"evidence": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"minLength": 1,
|
|
43
|
+
"description": "Citation proving the state — file:line, command output, run URL. REQUIRED when state is pass (enforced by the validator; a pass without evidence is assertion, not diagnosis)."
|
|
44
|
+
},
|
|
45
|
+
"reason": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"minLength": 1,
|
|
48
|
+
"description": "REQUIRED when state is not-applicable — why the area does not exist on this surface."
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"findings": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"description": "Every finding ever assigned in this project, open or resolved — IDs are immutable and never re-assigned, so resolved findings stay (status flips, the entry never disappears).",
|
|
57
|
+
"items": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"additionalProperties": false,
|
|
60
|
+
"required": ["id", "area", "severity", "title", "status"],
|
|
61
|
+
"properties": {
|
|
62
|
+
"id": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"pattern": "^AC-[A-Z][A-Z0-9]{1,7}-[0-9]{3}$",
|
|
65
|
+
"description": "Immutable finding ID: AC-<AREA-CODE>-NNN. The AREA code comes from prelaunch-areas.yml; NNN is zero-padded, monotonically assigned, NEVER re-used — a retitled or re-scoped finding keeps its ID; a genuinely new problem gets the next number."
|
|
66
|
+
},
|
|
67
|
+
"area": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
70
|
+
"description": "Area key (prelaunch-areas.yml) the finding belongs to; must agree with the ID's area code (validator-enforced)."
|
|
71
|
+
},
|
|
72
|
+
"severity": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enum": ["P0", "P1", "P2", "P3"],
|
|
75
|
+
"description": "P0 = launch-blocking; P1 = fix-before-general-rollout; P2 = fix-soon; P3 = nice-to-have. Any OPEN P0 refuses a ready verdict regardless of every other area."
|
|
76
|
+
},
|
|
77
|
+
"title": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1,
|
|
80
|
+
"maxLength": 200,
|
|
81
|
+
"description": "Human title. Mutable — the ID, not the title, is the diff key."
|
|
82
|
+
},
|
|
83
|
+
"evidence": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"minLength": 1,
|
|
86
|
+
"description": "Citation locating the finding (file:line, endpoint, config key)."
|
|
87
|
+
},
|
|
88
|
+
"status": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"enum": ["open", "fixed", "accepted-risk", "deferred-with-reason", "suppressed-with-evidence", "not-applicable"],
|
|
91
|
+
"description": "Fix-loop status vocabulary (Phase 3). Everything except open/fixed requires `reason`; suppressed-with-evidence additionally requires a matching entry in the project suppression file."
|
|
92
|
+
},
|
|
93
|
+
"reason": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"minLength": 1,
|
|
96
|
+
"description": "REQUIRED for accepted-risk / deferred-with-reason / suppressed-with-evidence / not-applicable."
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"questions": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"items": {"type": "string", "minLength": 1},
|
|
104
|
+
"description": "Questions that would change the diagnosis — open information gaps the next run should answer; the honest sibling of the unknowns."
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"maxLength": 220,
|
|
24
24
|
"description": "Trigger phrase; ≤ 200 chars recommended, 220 is the ceiling (lean-initial-context: descriptions load eagerly via progressive disclosure). Over-cap is a soft warning, not a hard fail — a warning window so authors adapt."
|
|
25
25
|
},
|
|
26
|
+
"compatibility": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"maxLength": 500,
|
|
29
|
+
"description": "Agent-Skills spec field (optional): machine-readable declaration of environment requirements — system packages, network access, product/host constraints. Mirrors the public spec so media/doc skills can state requirements outside prose."
|
|
30
|
+
},
|
|
26
31
|
"source": {
|
|
27
32
|
"type": "string",
|
|
28
33
|
"enum": ["package", "project"],
|
|
@@ -87,6 +92,12 @@
|
|
|
87
92
|
"enum": ["large"],
|
|
88
93
|
"description": "Optional orthogonal modifier (ADR-035): the skill needs a large-context model regardless of reasoning tier (e.g. summarising a 500-page log). Sparse — most skills omit it. Metadata only; does not change the native Claude `model:` (the tier owns the model choice)."
|
|
89
94
|
},
|
|
95
|
+
"effort": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"enum": ["low", "medium", "high", "max"],
|
|
98
|
+
"description": "Optional pinned reasoning-effort level for hosts with an effort knob (Claude Code `--effort` / agent frontmatter). Passthrough: skills project verbatim, so the key reaches Claude Code as-is and is inert on hosts without the knob. The bench harness pins it per run (bench_ab_task_runner `--effort`) so measurements are reproducible. Orthogonal to `model_tier` (capability band) — effort tunes how hard the model thinks, not which model runs. Omit unless the skill measurably needs a non-default effort.",
|
|
99
|
+
"$comment": "road-to-ecosystem-harvest-skill-quality-gates Phase 4, Source S (pinned effort frontmatter)."
|
|
100
|
+
},
|
|
90
101
|
"council_depth": {
|
|
91
102
|
"type": "string",
|
|
92
103
|
"enum": ["deep"],
|
|
@@ -130,7 +141,13 @@
|
|
|
130
141
|
},
|
|
131
142
|
"allowed_tools": {
|
|
132
143
|
"type": "array",
|
|
133
|
-
"items": { "type": "string" }
|
|
144
|
+
"items": { "type": "string" },
|
|
145
|
+
"description": "Allow-list of tool grants. Prefer the scoped-grant syntax over bare tool names where the host supports it — e.g. Bash(npm test:*) instead of Bash — per tool-safety Least Agency."
|
|
146
|
+
},
|
|
147
|
+
"disallowed_tools": {
|
|
148
|
+
"type": "array",
|
|
149
|
+
"items": { "type": "string" },
|
|
150
|
+
"description": "U3 (ecosystem harvest): optional deny-list layered UNDER allowed_tools — defense-in-depth; a tool matching here is refused even if a broad allow pattern would admit it. Supports the scoped-grant syntax (e.g. Bash(git push:*))."
|
|
134
151
|
},
|
|
135
152
|
"command": {
|
|
136
153
|
"type": "array",
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
"enum": ["lite", "medium", "high", "inherit"],
|
|
38
38
|
"description": "Vendor-neutral capability band (ADR-034/035). high/medium/lite project to a native Claude `model:` (high→opus, medium→sonnet, lite→haiku) via model_tier.ts; `inherit` is a documented passthrough sentinel (→ CC `model: inherit`), not a new mapping."
|
|
39
39
|
},
|
|
40
|
+
"effort": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"enum": ["low", "medium", "high", "max"],
|
|
43
|
+
"description": "Optional pinned reasoning-effort level. Projects into the generated .claude/agents/<name>.md frontmatter (`effort:`) on hosts with an effort knob; ignored elsewhere. Orthogonal to `model_tier`. Omit for host-default effort.",
|
|
44
|
+
"$comment": "road-to-ecosystem-harvest-skill-quality-gates Phase 4, Source S."
|
|
45
|
+
},
|
|
40
46
|
"tools": {
|
|
41
47
|
"type": "array",
|
|
42
48
|
"minItems": 1,
|
|
@@ -196,7 +196,7 @@ const VALID_EXECUTION_FIELDS = new Set([
|
|
|
196
196
|
'timeout_seconds',
|
|
197
197
|
'safety_mode',
|
|
198
198
|
'allowed_tools',
|
|
199
|
-
'command',
|
|
199
|
+
'command', 'disallowed_tools',
|
|
200
200
|
]);
|
|
201
201
|
|
|
202
202
|
// --- Wing-3 GTM cognition-boundary patterns ---
|
|
@@ -1404,6 +1404,29 @@ export function lint_skill(p: string, text: string): LintResult {
|
|
|
1404
1404
|
issues.push(new Issue('warning', 'missing_description', 'Frontmatter description is missing or unreadable'));
|
|
1405
1405
|
}
|
|
1406
1406
|
|
|
1407
|
+
// --- Agent-Skills spec alignment (U2, ecosystem harvest 2026-07-13) ---
|
|
1408
|
+
// Public-spec name rules for spec-portable skills: frontmatter `name`
|
|
1409
|
+
// must match the parent directory; no consecutive hyphens.
|
|
1410
|
+
{
|
|
1411
|
+
const fmNameMatch = text.match(/^name:\s*["']?([A-Za-z0-9-]+)["']?\s*$/m);
|
|
1412
|
+
const fmName = fmNameMatch ? fmNameMatch[1] : null;
|
|
1413
|
+
if (basename(p) === 'SKILL.md' && fmName && fmName !== parentName(p)) {
|
|
1414
|
+
issues.push(new Issue(
|
|
1415
|
+
'error',
|
|
1416
|
+
'spec_name_dir_mismatch',
|
|
1417
|
+
`Frontmatter name \`${fmName}\` must match the parent directory \`${parentName(p)}\` (Agent-Skills spec)`,
|
|
1418
|
+
));
|
|
1419
|
+
}
|
|
1420
|
+
const nameForHyphens = fmName ?? (basename(p) === 'SKILL.md' ? parentName(p) : stem(p));
|
|
1421
|
+
if (nameForHyphens && nameForHyphens.includes('--')) {
|
|
1422
|
+
issues.push(new Issue(
|
|
1423
|
+
'error',
|
|
1424
|
+
'spec_name_consecutive_hyphens',
|
|
1425
|
+
`Skill name \`${nameForHyphens}\` contains consecutive hyphens (Agent-Skills spec forbids them)`,
|
|
1426
|
+
));
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1407
1430
|
// --- Bare-noun name check ---
|
|
1408
1431
|
const skillName = basename(p) === 'SKILL.md' ? parentName(p) : stem(p);
|
|
1409
1432
|
if (skillName && !skillName.includes('-') && skillName.length >= 3) {
|
|
@@ -1670,7 +1693,7 @@ export function validate_evals_json(skillPath: string): Issue[] {
|
|
|
1670
1693
|
);
|
|
1671
1694
|
return issues;
|
|
1672
1695
|
}
|
|
1673
|
-
const validKinds = ['contains', 'file_exists', 'rubric', 'finding_floor'];
|
|
1696
|
+
const validKinds = ['contains', 'not_contains', 'file_exists', 'rubric', 'finding_floor', 'tool-choice', 'trajectory_budget'];
|
|
1674
1697
|
const validKindsSet = new Set(validKinds);
|
|
1675
1698
|
scenarios.forEach((scenario, idx) => {
|
|
1676
1699
|
const loc = `scenarios[${idx}]`;
|
|
@@ -1726,8 +1749,25 @@ export function validate_evals_json(skillPath: string): Issue[] {
|
|
|
1726
1749
|
new Issue('warning', 'evals_json_assertion_field_type', `${aLoc} (kind=finding_floor) 'pattern' must be a string`),
|
|
1727
1750
|
);
|
|
1728
1751
|
}
|
|
1752
|
+
} else if (kind === 'tool-choice') {
|
|
1753
|
+
// tool-choice (eval-schema v2): `must_use` / `must_not_use` are both
|
|
1754
|
+
// OPTIONAL string arrays — validate type only when present.
|
|
1755
|
+
for (const f of ['must_use', 'must_not_use']) {
|
|
1756
|
+
if (f in a && !(Array.isArray(a[f]) && (a[f] as unknown[]).every((x) => typeof x === 'string'))) {
|
|
1757
|
+
issues.push(
|
|
1758
|
+
new Issue('warning', 'evals_json_assertion_field_type', `${aLoc} (kind=tool-choice) '${f}' must be an array of strings`),
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
} else if (kind === 'trajectory_budget') {
|
|
1763
|
+
// trajectory_budget (eval-schema v2): required integer `n` >= 1.
|
|
1764
|
+
if (typeof a.n !== 'number' || !Number.isInteger(a.n) || (a.n as number) < 1) {
|
|
1765
|
+
issues.push(
|
|
1766
|
+
new Issue('warning', 'evals_json_assertion_field_type', `${aLoc} (kind=trajectory_budget) 'n' must be an integer >= 1`),
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1729
1769
|
} else {
|
|
1730
|
-
const requiredField = { contains: 'value', file_exists: 'path', rubric: 'criterion' }[kind] as string;
|
|
1770
|
+
const requiredField = { contains: 'value', not_contains: 'value', file_exists: 'path', rubric: 'criterion' }[kind] as string;
|
|
1731
1771
|
if (!(requiredField in a) || typeof a[requiredField] !== 'string') {
|
|
1732
1772
|
issues.push(
|
|
1733
1773
|
new Issue(
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# smoke_host_loadability.sh — real-host loadability smoke
|
|
3
|
+
# (road-to-ecosystem-harvest-skill-quality-gates Phase 4, Source G).
|
|
4
|
+
#
|
|
5
|
+
# The static check (check_host_loadability.ts) proves the generated trees
|
|
6
|
+
# PARSE; this smoke proves the real Claude Code CLI actually ACCEPTS them:
|
|
7
|
+
#
|
|
8
|
+
# 1. `claude plugin validate .claude-plugin` — the host's own validator on
|
|
9
|
+
# the marketplace manifest + plugin dirs.
|
|
10
|
+
# 2. Temp-home install: add this repo as a marketplace in a throwaway HOME,
|
|
11
|
+
# install the bootstrap-shim plugin, assert it shows up in
|
|
12
|
+
# `claude plugin list`. Nothing touches the developer's real ~/.claude.
|
|
13
|
+
# 3. Metadata cross-consistency (marketplace ↔ plugin dirs ↔ docs):
|
|
14
|
+
# lint_marketplace + lint_marketplace_install_completeness +
|
|
15
|
+
# lint_supported_tools_matrix + check_host_loadability.
|
|
16
|
+
#
|
|
17
|
+
# Contract: OPTIONAL in CI (runners without the claude CLI skip with exit 0
|
|
18
|
+
# and a notice), REQUIRED before releases — pass --require to make a missing
|
|
19
|
+
# CLI a failure (wired into the release flow, see docs/contracts/release-pr-gating.md).
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
|
|
22
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
23
|
+
cd "$REPO_ROOT"
|
|
24
|
+
|
|
25
|
+
REQUIRE=0
|
|
26
|
+
for arg in "$@"; do
|
|
27
|
+
case "$arg" in
|
|
28
|
+
--require) REQUIRE=1 ;;
|
|
29
|
+
*) echo "usage: smoke_host_loadability.sh [--require]" >&2; exit 2 ;;
|
|
30
|
+
esac
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
CLAUDE_BIN="${CLAUDE_CLI:-$(command -v claude || true)}"
|
|
34
|
+
if [ -n "$CLAUDE_BIN" ] && [ ! -x "$CLAUDE_BIN" ]; then
|
|
35
|
+
CLAUDE_BIN=""
|
|
36
|
+
fi
|
|
37
|
+
if [ -z "$CLAUDE_BIN" ]; then
|
|
38
|
+
if [ "$REQUIRE" -eq 1 ]; then
|
|
39
|
+
echo "❌ claude CLI not found and --require set (release gate). Install Claude Code or set CLAUDE_CLI." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
echo "⚠️ claude CLI not found — real-host smoke skipped (static checks still run)."
|
|
43
|
+
./scripts-run src/scripts/check_host_loadability --root .
|
|
44
|
+
./scripts-run src/scripts/lint_supported_tools_matrix
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
MARKETPLACE_NAME="$(node -e "console.log(JSON.parse(require('node:fs').readFileSync('.claude-plugin/marketplace.json','utf8')).name)")"
|
|
49
|
+
PLUGIN_NAME="$(node -e "console.log(JSON.parse(require('node:fs').readFileSync('.claude-plugin/marketplace.json','utf8')).plugins[0].name)")"
|
|
50
|
+
|
|
51
|
+
echo "→ 1/3 host-CLI manifest validation (claude plugin validate)"
|
|
52
|
+
# validate expects the directory that CONTAINS .claude-plugin/.
|
|
53
|
+
"$CLAUDE_BIN" plugin validate "$REPO_ROOT"
|
|
54
|
+
|
|
55
|
+
echo "→ 2/3 temp-home install + load assertion (${PLUGIN_NAME}@${MARKETPLACE_NAME})"
|
|
56
|
+
TMP_HOME="$(mktemp -d)"
|
|
57
|
+
cleanup() { rm -rf "$TMP_HOME"; }
|
|
58
|
+
trap cleanup EXIT
|
|
59
|
+
export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-}"
|
|
60
|
+
HOME="$TMP_HOME" "$CLAUDE_BIN" plugin marketplace add "$REPO_ROOT"
|
|
61
|
+
HOME="$TMP_HOME" "$CLAUDE_BIN" plugin install "${PLUGIN_NAME}@${MARKETPLACE_NAME}"
|
|
62
|
+
if ! HOME="$TMP_HOME" "$CLAUDE_BIN" plugin list | grep -q "$PLUGIN_NAME"; then
|
|
63
|
+
echo "❌ plugin '${PLUGIN_NAME}' not listed after temp-home install — host did not load it" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo "→ 3/3 metadata cross-consistency (marketplace ↔ plugin dirs ↔ docs)"
|
|
68
|
+
./scripts-run src/scripts/lint_marketplace
|
|
69
|
+
./scripts-run src/scripts/lint_marketplace_install_completeness
|
|
70
|
+
./scripts-run src/scripts/lint_supported_tools_matrix
|
|
71
|
+
./scripts-run src/scripts/check_host_loadability --root .
|
|
72
|
+
|
|
73
|
+
echo "✅ host-loadability smoke green (validate + temp-home install + cross-consistency)"
|