TL;DR: A card nobody can find is not a card. The catalog faf cards writes now names who publishes it, keys every row the way the specs say to, and can be written as the ARD manifest agent search engines read.
In Plain English
Old state. You published a catalog of your agent's cards, and it was technically valid — but it never said who published it, and its row names were built from whatever your homepage happened to be. Search engines for agents either skipped it or filed it under the wrong owner.
Fix. Name the publisher. Key every row off the domain your .fafa actually declares. Write the file the agent search engines come looking
for.
New state. The same command writes a catalog that reads as discoverable, with identifiers both specs accept.
npm install -g faf-cli@7.16.1 faf cards --target catalog,ardThe receipt
This edition exists because of one line. Here is the identifier faf-cli used to emit for an
agent whose short name was Weather Bot:
urn:air:acme.example:a2a:Weather BotThe AI Catalog validator accepts that. ARD's conformance tool rejects it outright — three errors, "does not match RFC 8141 URN pattern". Same file, same line, two verdicts. A URN may not carry a space, and a display name is free text.
It was also keyed to the wrong publisher: the host of your homepage, rather than the domain
your .fafa declares. So a catalog could name one publisher at the top and file
every row under another.
Both are fixed, and both paths — the CLI and the library — now derive one identifier. An identifier is a catalog's primary key. It was worth fixing before anyone was holding a reference to it.
Naming who publishes
AI Catalog reads a catalog at Level 1 minimal until it names a host. With a host, it
reads as Level 2 discoverable. faf cards --target catalog wrote the
first; now it writes the second.
displayName is the field that earns the level — and an empty one is invalid, not merely minimal. So a .fafa that names nobody gets
no host at all: a minimal catalog that validates beats a discoverable one that doesn't.
On a catalog you share with other publishers, host is the one key faf adds, and
only when the catalog names none. A host already there is yours, and stays byte for byte.
Where the manifest actually lives
faf cards --target ard writes /.well-known/ard.json — the rows plus
the search hints registries index on, read from your .fafa: metadata.cards.keywords become tags, metadata.cards.examples become
representative queries.
Choosing that path took reading both the spec and its tooling, because they disagree. The
ARD prose still points at /.well-known/ai-catalog.json; ARD's own conformance
CLI says a consumer MUST fetch /.well-known/ard.json and calls
the other one the predecessor. The tool is newer than the document, so faf writes what
consumers are told to fetch — and --target catalog,ard writes both.
One more thing the tool taught us: a manifest with no representative queries is valid and
unfindable, because the semantic index is built from that field. Rather than write a card
nobody can find, faf cards now says so in one line and names the key to fill in.
Bounds
- Specs move, and these two are early. ARD says "Proposal"; its prose and its conformance tool currently disagree about the well-known path. We wrote to the tool and said why.
- A schema URL upstream is missing. A Server Card carries a
$schema, and the spec names one URL for it. That URL returns 404 today. We write it as the spec names it; it resolves when upstream publishes the file. - Identifiers changed. If your
.fafadeclares a domain other than its homepage host, or its name was never a handle, your rows get different identifiers than 7.15 wrote. That is the fix, and it is a breaking one for anything holding the old key. - Windows ships, Windows isn't gated. faf-cli runs on Windows and builds a Windows binary; there is no Windows job in CI, by a documented decision. A real pre-merge Windows gate is a tracked follow-up.
Try it
Install:
npm install -g faf-cli@7.16.1 faf cards --checkTry (no install):
npx --yes faf-cli@7.16.1 --version--check prints the cards without writing them. Same CLI under the shorter name: npm i -g faf@7.16.1. More: docs.faf.one/cards · release notes · repo.
Technical details
- Version: 7.16.1 (September 16, 2026)
- Packages:
faf-cliandfaf(same bits) · Homebrew - New target:
faf cards --target ard→/.well-known/ard.json - Checked with: ai-catalog-cli v0.2.2 · ARD conformance CLI v0.9.1
- Tests: 2050 passing
Feedback welcome
Questions, nits, suggestions — guide the next version. Tell us what you want to see.
