Start from a provider covered by current tests, not from an old planning document. In the ARC source tree:
| Artifact | Role |
|---|---|
providers/core/json/src/index.ts | Compact implementation baseline (AFSJSON extends AFSBaseProvider) |
providers/core/json/test/conformance.test.ts | Conformance fixture via runProviderTests |
packages/testing (@aigne/afs-testing) | Shared suite runner and contract-gated fixtures |
docs/guides/provider-authoring.md | Authoring discipline (ops vs semantic actions, ifMatch, query) |
Minimal public contract
| Piece | What to implement |
|---|---|
| Module identity | name, optional description, uri / load params |
| Path ownership | Stable path layout; no reserved virtual prefix abuse (.actions, .meta, .as, …) |
| Operations | Only methods you can enforce: list / read / write / delete / stat / search / exec / explain / rename / optional query / optional batch |
| Capability declaration | OperationsDeclaration (+ features). Declare ⇒ execute; never advertise ifMatch/query without enforcement |
| Errors | Use shared AFS*Error codes (AFS_NOT_FOUND, AFS_VALIDATION_ERROR, AFS_CONFLICT, …) |
| Conformance | test/conformance.test.ts calling runProviderTests |
Typical baseline pattern (JSON provider):
- Extend
AFSBaseProvider. - Provide
static manifest()/load()for registry/URI loading. - Decorate handlers with
@List,@Read,@Write,@Delete,@Search,@Stat,@Explain, … - Override
getOperationsDeclaration()when you need features such asifMatch. - Expose
/.meta/.capabilitiesfor runtime discovery.
Run the JSON baseline conformance
From a current ARC monorepo checkout (package @aigne/afs-json):
pnpm --filter @aigne/afs-json test -- test/conformance.test.tsVerified on ARC source 44fbd616f (2026-08-10):
372 pass
6 skip
0 fail
Ran 378 tests across 1 file.Treat that result as evidence for this baseline and this commit, not for every provider or every release. Skipped suites (for example subscribe when not declared) are expected when fixtures omit optional capabilities.
Suggested implementation order
- Sketch the FS layout (directories vs leaves vs action paths).
- Implement inspection first:
list+read(+stat/explain). Anything stored should be enumerable—do not hide data only behind custom actions. - Add path mutation (
write/delete/rename) only where the store can enforce it. - Add semantic
@Actionsonly for operations that need provider-specific meaning beyond path CRUD. - Wire
runProviderTestswith astructurefixture matching real data. - If you declare
query, ship acollectionQueryfixture (declare ⇒ test). - If you declare
write.features.ifMatch, shipifMatchandpeerProvideragainst the same backing store. - Document data, auth, search, and failure boundaries separately from the generic AFS contract.
Do not claim query because you can list, or a particular search quality because you expose search.
Keep an acceptance record
Use this record before presenting a provider as a public catalog candidate. It is a checklist, not a claim that every provider has already passed it.
| Record | What to capture |
|---|---|
| Contract | Owned paths, operations, declared capabilities; do not infer one from another |
| Data and access boundary | Backing system, credentials or caller boundary, data read/changed, observable failures |
| Conformance evidence | Exact test command, ARC/source version, pass/skip/fail counts |
| Local acceptance | Isolated local exercise: ARC version, commands, non-secret env choices, observed result. Do not substitute DID Space deploy for local evidence |
| Compatibility | ARC/runtime version and provider backend versions the observation depends on |
| Support ownership | Maintainer, lifecycle state, documentation location users should rely on |
If any row is unknown, keep the provider out of the public catalog. A package in the source tree is implementation evidence, not a support promise. See Provider catalog.