feat(ra): AI Catalog generation, FQDN exclusivity, and seal-before-success activation#47
Draft
csnitker-godaddy wants to merge 1 commit into
Draft
feat(ra): AI Catalog generation, FQDN exclusivity, and seal-before-success activation#47csnitker-godaddy wants to merge 1 commit into
csnitker-godaddy wants to merge 1 commit into
Conversation
…s activation
Adds producer-side AI Catalog artifact generation to the RA, plus the two
invariants it leans on. Everything is derived from the registration
aggregate — nothing crawled, nothing fetched, and the registration request
and 202 response are untouched.
AI Catalog (IMPL slices 1-2)
- internal/catalog: pure generation of the per-agent CatalogEntry and the
host-complete ai-catalog.json document. Eligibility gates (versioned,
ACTIVE, A2A/MCP endpoint with a policy-passing metaDataUrl), single vs
nested entries, leftmost-DNS-label URN, Cc/Cf text sanitization, and an
emitted-URL policy (absolute https, host==agentHost, no
userinfo/query/fragment).
- GET /v2/ans/agents/{agentId}/catalog-entry (bare entry) and
GET /v2/ans/agents/{agentId}/ai-catalog (host-complete document with a
strong ETag + If-None-Match/304). Owner-scoped via ReadOwnership.
- spec/api-spec-v2.yaml and the embedded docsui copy updated.
FQDN exclusivity (one-host-one-owner)
- Once a registration is live (ACTIVE/DEPRECATED) on an FQDN, a different
owner may not register or activate on it; checked at register,
verify-acme, and verify-dns. On activation the winner cancels losing
pending registrations (no TL event, ANS-1 §4.4). The check is
best-effort against a concurrent pending-window race (documented; a
pre-seal host claim is the follow-up).
Seal-before-success activation (ANS-1 §12.3)
- verify-dns seals the single terminal AGENT_REGISTERED event INLINE and
reports ACTIVE only after the TL acknowledges. A failing or unconfigured
sealer fails closed: TL_UNAVAILABLE (503), the agent stays PENDING_DNS,
nothing is committed, and no outbox row is written. Revocation still
rides the outbox. This is what lets a catalogued agent's SCITT-receipt
and badge links point at TL records that actually exist.
Tests and demos
- Unit coverage for catalog generation (100%), fail-closed activation
(sealer error + nil sealer), and FQDN exclusivity. make check green at
90.2%; race detector clean.
- scripts/demo/ai-catalog.sh produces and validates the host-complete
ai-catalog.json (multi-agent host, ineligible/pending/other-host
excluded, agent-scoped alias, deterministic ETag, 304). catalog.sh
covers the per-agent entry scenarios. Shared demo helpers factored into
common.sh.
Signed-off-by: Connor Snitker <csnitker@godaddy.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
Adds producer-side AI Catalog artifact generation to the RA, plus the two invariants it depends on. Every byte is derived from the registration aggregate — nothing crawled, nothing fetched — and the registration request and 202 response are untouched.
What's in this PR
1. AI Catalog generation (IMPL slices 1–2)
internal/catalog(pure, no I/O): the per-agentCatalogEntryand the host-completeai-catalog.jsondocument. Eligibility gates (versioned, ACTIVE, an A2A/MCP endpoint with a policy-passingmetaDataUrl), single vs nested entries, leftmost-DNS-label URN,Cc/Cftext sanitization, and an emitted-URL policy (absolutehttps,host == agentHost, no userinfo/query/fragment).ReadOwnership):GET /v2/ans/agents/{agentId}/catalog-entry— the bare entry (application/json).GET /v2/ans/agents/{agentId}/ai-catalog— the host-complete document (application/ai-catalog+json) with a strong ETag +If-None-Match/304. This is the literalai-catalog.jsonan Agent-Host Provider republishes athttps://{agentHost}/.well-known/ai-catalog.json.spec/api-spec-v2.yamland the embedded docsui copy updated.2. FQDN exclusivity (one-host-one-owner)
Once a registration is live (ACTIVE/DEPRECATED) on an FQDN, a different owner may not register or activate on it — checked at register, verify-acme, and verify-dns. On activation the winner cancels losing pending registrations (no TL event, ANS-1 §4.4).
3. Seal-before-success activation (ANS-1 §12.3)
verify-dnsseals the single terminalAGENT_REGISTEREDevent inline and reports ACTIVE only after the TL acknowledges. A failing or unconfigured sealer fails closed:503 TL_UNAVAILABLE, the agent staysPENDING_DNS, nothing is committed, no outbox row. Revocation still rides the outbox. This is what guarantees a catalogued agent's SCITT-receipt and badge links point at TL records that actually exist.The
ai-catalog.json(the deliverable)scripts/demo/ai-catalog.shbuilds one host with a mixed population and saves the validated document todata/demo/ai-catalog.json:It asserts host-completeness, the host object, sorted-by-version, per-card
mediaType, the agent-scoped alias (byte-identical via any agentId), a deterministic ETag, and 304.Quality gates
make checkgreen at 90.2% coverage (internal/catalogat 100%);go test -raceclean on the affected packages.run-lifecycle.sh(V2),run-lifecycle-v1.sh(V1),catalog.sh(per-agent entry),ai-catalog.sh(host document).Known limitations / follow-ups
PENDING_DNSregistration on the same FQDN can raceverify-dnsand both reach ACTIVE (the check runs before the inline seal and outside the activation tx). An in-tx re-check would trade this for a sealed-but-not-activated orphan under seal-before-success, so the proper fix is a pre-seal host claim (mirroring the identity lane's nonce claim) — deferred. Documented inpreflightRegistrationConflicts. The owner-scoped catalog read contains the blast radius.GET /v2/ans/catalog?agentHost=(IMPL slice 3) is unbuilt — that's the surface an AHP fetches without owner credentials.updatedAtuses registration/last-renewal time as a documented proxy for the spec's "activation/latest seal timestamp" (the RA persists no activation timestamp; the field is optional).🤖 Generated with Claude Code