Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions agent-templates/contracts/a2a/v1/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,55 @@ protocol version appears in the card as `AgentInterface.protocolVersion` and on

---

## 1.3.0 — 2026-08-27

Additive, backward-compatible MINOR bump within v1. **Runtime tenant registration.** Tenants may now
be resolved from a runtime DB registry owned by the orchestrator instead of the static
`a2a.tenants[]` values array. Tracking issue: [izzywdev/FuzeAgent#203](https://github.com/izzywdev/FuzeAgent/issues/203).

This freezes the **interface** for the new topology; it is the gate the implementer slices build on
(Slice 1 migration, the orchestrator handlers, Slice 3 server reader, tests, docs). No handler, SQL
or chart is added here.

### Added

- `schema/tenant-registration.schema.json` — the runtime-registry shapes:
- `RegisteredTenant` — the canonical `a2a_tenants` record (`tenant` unique key, `repo`, `ref`,
`entryRole`, `servingRoles[]`, `external`, `provider`, `card`, `enabled`, `createdAt`,
`updatedAt`). Frozen ONCE here so the DB migration and the A2A server reader target one shape.
- `RegisterTenantRequest` / `RegisterTenantResponse` — the self-registration payload and its
upsert result.
- `TenantList` — the `GET /a2a/tenants` response (marked `x-pagination: exempt`: a bounded
whole-set config read the A2A server resolves atomically).
- The `card` field **reuses `agent-card.schema.json` by reference** — the projected card shape is
**not** redefined and remains byte-identical to a card projected from a cloned repo. A pushed
card MUST additionally satisfy `fuze-profile.schema.json`.
- `tenant-registration.md` — NORMATIVE spec for the two orchestrator HTTP operations
(`POST /a2a/tenants/register`, `GET /a2a/tenants` [+ `/{tenant}`]): idempotent-upsert semantics,
the OIDC caller-repo self-registration security rule (a registration whose `tenant`/`repo` ≠ the
authenticated identity is rejected `403` and never written), and the two-schema card-validation
rule.
- `examples/registration/fuzeplan.tenant-registration.json` — a worked registration built from the
frozen FuzePlan card, doubling as a fixture. Placed in a subdirectory so the card-conformance
suite's `examples/*.json` glob (which treats every flat entry as an Agent Card) does not mistake
the registration wrapper for a card.
- `client/fuze_a2a_client/registration_models.py` — GENERATED Pydantic models for the new shapes;
`regenerate.sh` now emits it (bundling the cross-file card ref for single-file codegen). Exported
from `fuze_a2a_client` (`RegisterTenantRequest`, `RegisteredTenant`, `RegisterTenantResponse`,
`TenantList`). Client package bumped `1.0.0` → `1.3.0` — the first bump since freeze that changes
the generated surface, so the package version now tracks the contract version again.

### Backward compatibility

Purely additive. `values-interface.schema.json` and the static `a2a.tenants[]` topology are
**unchanged and still valid**; `agent-card.schema.json`, `fuze-profile.schema.json`,
`a2a-wire.schema.json`, `card-projection.md`, `binding.md`, `state-mapping.md` and `authz.md` are
untouched. A v1 consumer that does not use runtime registration is unaffected; the two topologies
serve **byte-identical cards**. No wire/card *shape* changed, so existing `wire_models` / `card_models`
are byte-identical after regeneration.

---

## 1.2.0 — 2026-08-10

Additive, backward-compatible MINOR bump within v1. **Per-product A2A pods become deployable.**
Expand Down
4 changes: 4 additions & 0 deletions agent-templates/contracts/a2a/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ are human→agent; A2A is agent→agent. Both remain first-class (FuzeSDLC basel
| [`card-projection.md`](card-projection.md) | How a card is **derived** from `.fuze/manifest.json` + `agent-templates/roles/*/role.json`. Product **and** exec tier. |
| [`state-mapping.md`](state-mapping.md) | A2A ↔ `agent-templates/providers/base.py`. The pod is an **adapter**. |
| [`authz.md`](authz.md) | Callee enforces, caller is untrusted, `providesTo` is the grant, absence **denies**. |
| [`tenant-registration.md`](tenant-registration.md) | (v1.3.0) Runtime tenant registry: the two orchestrator HTTP operations, idempotent upsert, self-registration authz, card-as-data. |
| [`CHANGELOG.md`](CHANGELOG.md) | SemVer policy, decisions recorded, known gaps. |

## Layout
Expand All @@ -50,9 +51,12 @@ schema/
manifest-a2a-extension.schema.json .fuze/manifest.json additions (providesTo, a2a block)
role-a2a-extension.schema.json optional a2a block on role.json
values-interface.schema.json shared-server Helm values INTERFACE (no chart)
tenant-registration.schema.json (v1.3.0) runtime registry record + register req/resp
tenant-registration.md (v1.3.0) runtime tenant registration (NORMATIVE)
client/ generated Pydantic models + typed A2AClient
mock/ servable card + canned responses
examples/ FuzePlan (product) and CTO (exec) cards
examples/registration/ (v1.3.0) a worked tenant-registration request
VERSION CHANGELOG.md
```

Expand Down
2 changes: 1 addition & 1 deletion agent-templates/contracts/a2a/v1/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.0
1.3.0
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

Frozen against A2A specification 1.0.0 (`lf.a2a.v1`).

`wire_models` and `card_models` are GENERATED from the schemas in ../../schema/ by
`regenerate.sh`; do not hand-edit them. Editing a generated model instead of the
schema is how a contract silently forks from its spec.
`wire_models`, `card_models` and `registration_models` are GENERATED from the schemas
in ../../schema/ by `regenerate.sh`; do not hand-edit them. Editing a generated model
instead of the schema is how a contract silently forks from its spec.
"""
from .card_models import FuzeA2AAgentCard as AgentCard
from .client import (
Expand All @@ -24,13 +24,23 @@
UnsupportedOperationError,
VersionNotSupportedError,
)
from .registration_models import (
RegisteredTenant,
RegisterTenantRequest,
RegisterTenantResponse,
TenantList,
)
from .wire_models import Artifact, Message, Part, Role, Task, TaskState, TaskStatus

__version__ = "1.0.0"
__version__ = "1.3.0"

__all__ = [
"A2AClient",
"AgentCard",
"RegisterTenantRequest",
"RegisteredTenant",
"RegisterTenantResponse",
"TenantList",
"A2A_VERSION",
"WELL_KNOWN_CARD_PATH",
"TERMINAL_STATES",
Expand Down
Loading
Loading