feat(discovery): buildSkillMd renderer for /skill.md agent surface#5
Merged
Conversation
Adds a new discovery builder that emits a Claude-Skill-compatible manifest (YAML frontmatter + markdown body) describing the merchant's agent-facing contract: payment rails, compatible clients per rail, identity requirements as outcomes, shipping policy, endpoints, triggers, support links. Renders strictly agent-facing data — no failOpen, no mount-strategy names, no KYC vendor names, no defense parameters, no idempotency construction shape. Internal posture stays in merchant runtime config. Compatible-clients-per-rail table sources from the same SDK constant (compatibleClientsByRails, extracted from challenge/agent_instructions.ts) that drives the live 402 body's compatible_clients field, so updating a smoke-verified client in one place propagates to skill.md, the 402 body, and any future surface that consumes it. Bump to 1.2.0 (additive surface, no breaking changes). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add /skill.md to defaultDiscoveryPaths so the existing noindex middleware and discovery-path predicate auto-recognize the new surface. - Update README + CLAUDE.md to mention buildSkillMd alongside the other discovery builders. - Update robots_tag tests to assert /skill.md is in the default set. Keeps node + python parity (python-commerce ships the same change). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses spec violations + cross-language parity issues from end-to-end review against https://agentskills.io/specification: P0 — spec violations: - description / license / compatibility / allowed-tools / metadata-values now emitted as YAML double-quoted scalars. Fixes the colon / quote / newline parse failure the spec explicitly warns about. - metadata.version emitted as quoted string ("1") not int (1). Spec requires metadata values to be strings. P1 — validation + exports: - Validate name against the spec regex (1-64 chars, lowercase alphanumeric + hyphens, no leading / trailing / consecutive hyphens). Throws with a clear agentskills.io-spec message on bad input. - Validate description length ≤1024 + non-empty. - Validate compatibility length ≤500. - Re-export RailKey + compatibleClientsByRails from src/discovery so callers don't have to reach into challenge/. P2 — additional spec fields: - Surface optional license, compatibility, allowed-tools frontmatter fields. - Move homepage from top-level to metadata.homepage (top-level non-spec fields belong under metadata per spec). P3 — edge cases: - Drop compatibleClients overrides for rails not in acceptedRails (silent filter). - Escape pipe characters in markdown table cells (file labels, file URLs, endpoint paths, endpoint descriptions) so embedded `|` doesn't break rows. - Add /SKILL.md (uppercase) to defaultDiscoveryPaths so the canonical-cased alias inherits the noindex exemption. Tests: 38 cases covering spec-violation regression + edge cases + escape behavior + the new validation throw paths. Coverage 90.36% (over 90%). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
End-to-end review flagged version: 0 as potential parity drift between node (?? nullish coalescing) and python (str()). Verified both pass 0 through unchanged; this test locks the contract so a future refactor to || (falsy) wouldn't silently change emission. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CodeQL flagged the markdown-cell sanitizer as incomplete escaping: prior implementation escaped \`|\` but not \`\\\`, so an input like \`a\\|b\` rendered as \`a\\\\|b\` which markdown reads as literal-backslash + cell-terminator — breaking the row. Fix matches the spec'd two-pass escape (backslash first, then pipe), same order quoteYaml uses. Test asserts \`a\\|b\` round-trips as \`a\\\\\\|b\`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan