feat(skills): skill marketplace v0 — sell + rate skills as a single unit#632
feat(skills): skill marketplace v0 — sell + rate skills as a single unit#632bussyjd wants to merge 3 commits into
Conversation
…dle download + skill-as-a-service)
- ServiceOffer type=skill (spec.skill: name/version/sha256/bundleConfigMap, CEL
guard); controller validates bundle CM (existence/900KB cap/sha256 match) and
renders a restricted-PSS busybox httpd bundle server behind the standard
Middleware+HTTPRoute publish path; anti-spoof: upstream pinned to the
controller-rendered workload name
- 402 extra.skill {name,version,sha256} surfaced free pre-purchase (additive)
- obol sell skill (--from/--from-embedded, deterministic tar via
internal/skillpkg, warn-only secret scan, server-side CM apply, resume-ledger
bundle) + --as-service sugar over type=agent
- obol skills calldata set-hash|feedback (tag1=asr:skill, ERC-8239 PR#1704
interim tag2), reputation (getSummary + --raters whitelist), verify
(on-chain sha256 vs local bundle); operator submits, controller never signs
- hermes-skill-publish Role (namespace-scoped CM create/get/update/patch) gated
by new VAP rule: agent ConfigMap writes must be *-skill-bundle — hermes-config
untouchable; agent-side publish documented in sell/monetize-guide skills
- flows/flow-19-skill-sale.sh + docs/guides/skill-marketplace.md
- review: high (binary-corrupting buy.py download instructions) fixed in-flow;
post-review hand fixes: 63-char Service/label cap on workload names, VAP
ConfigMap guard, sell delete cleans bundle CM, secret-scan errors surfaced,
doc drift
|
Is this just different UX for |
|
It's not. It sells the bundle bytes with integrity + a publisher-portable identity, vs. sell mcp which proxies a running tool. |
The user: a seller whose edge isn't GPU but a capability — a good research |
The --as-service mode was thin sugar over `obol sell agent` (it emitted a plain type=agent offer with the skill name in registration metadata, no controller involvement). It duplicated the agent sell path and muddied the `sell skill` surface, which is about selling bundle BYTES. Removed the flag, its --agent companion, the runSellSkillAsService/buildSkillServiceOfferManifest code, and the service-mode test; docs now point at `obol sell agent` for selling a skill's execution. SHARE mode (paid bundle download) is unchanged.
What
Makes a skill (a
SKILL.md+ scripts bundle, like the ones embedded in the obol binary) a first-class sellable and ratable unit on the stack, in two modes:ServiceOffer type=skill: the gzipped bundle lives in a ConfigMap, the controller validates it (existence, 900 KB cap, sha256 match) and renders a restricted-PSS busybox httpd servingbundle.tar.gz+skill.jsonbehind the standard x402 payment gate at/services/<name>/*.obol sell skill --as-service --agent <a>is thin sugar over the existingtype=agentoffer path, carrying the skill identity in registration metadata. Zero new controller surface.Ratings and integrity ride ERC-8004 (live on Base mainnet + Sepolia) rather than a new contract:
obol skills calldata set-hash→setMetadata(agentId, "skill.sha256:<name>@<ver>", <hash>)on the IdentityRegistry — binds bundle bytes to the publisher identity.obol skills calldata feedback→giveFeedbackwithtag1="asr:skill",tag2="eip155:<chainId>:<registry>:<agentId>:<name>@<ver>"— per-skill ratings under the publisher's agentId, on-chain filterable viagetSummary(agentId, raters, tag1, tag2). The tag convention follows the draft ERC-8239 (ethereum/ERCs PR #1704) so we are forward-compatible if it merges; we deliberately do NOT depend on its contracts (unmerged, Sepolia-only).obol skills reputation(summary read w/--raterswhitelist → spam-resistant) andobol skills verify(local bundle sha256 vs on-chain metadata).All chain writes are operator-submitted calldata. The controller never signs.
Why
The 402 response advertises
extra.skill = {name, version, sha256}for free, pre-purchase — a buyer can verify what they will get against the publisher's on-chain hash before paying, and verify the bytes after. That closes the marketplace loop (discover → verify → pay → re-verify → rate) with only the registries already deployed.Agent self-publish (and its guardrails)
A running agent can sell its own skills: a new namespace-scoped
hermes-skill-publishRole grants ConfigMap create/get/update/patch in the agent's own namespace (it already had ServiceOffer CRUD). Two containment layers:*-skill-bundle—hermes-configand every other operator-managed ConfigMap are untouchable (test-pinned).Notable implementation details
internal/skillpkg): sorted entries, fixed epoch mtimes, cleared uid/gid, normalized modes → reproducible sha256 across machines (test-pinned). Warn-only secret scan before publish.obol sell deletecleans up the bundle ConfigMap (CLI-created, so no ownerRef GC).obol sell resume/stack up.internal/erc8004/{reputation,validation}.go(calldata builders + readers for the Reputation/Validation registries) which the CLI commands need — additive, golden-tested selectors.Validation
extra.skillbyte-exact vs served bundle → VAP denies the agent SA onhermes-configand allows*-skill-bundle→ delete cleans everything.0xb3075516fbbb4c14076b5b94d7db30e2a68ae2c2cf977c58ba1e8ca0715da6d3(status 0x1), exact ±0.001 USDC balance deltas on buyer and payTo.flows/flow-19-skill-sale.sh+docs/guides/skill-marketplace.md.Known v0 limitations
buy.py payis text-only — the printed purchase instructions steer binary downloads to a binary-safe client (paidskill.jsonfetch is the documented buy.py path).