Part of #160. Depends on #161 (emitter) and #162 (CLI). Consumed by the round-trip gate.
Goal
Define a small set of x-altair-* OpenAPI specification extensions that the forward path (spec:emit-openapi) writes into OpenAPI and the reverse path (openapi:import) reads back out. Lets a round-trip preserve Univeros-specific concerns \xe2\x80\x94 persistence entity, queue handler, webhook contract, idempotency policy \xe2\x80\x94 that OpenAPI 3.1 itself cannot express.
Why
OpenAPI describes the wire shape. Univeros specs describe more: which response maps to a Cycle entity, which side-effect dispatches a message, which endpoint is a webhook receiver, what the idempotency window is. If these concerns don't round-trip, importing then re-emitting silently loses them, and the round-trip drift gate becomes impossible to make green.
Adding them as x-altair-* extensions is the OpenAPI-idiomatic way to carry framework metadata while staying valid 3.1 \xe2\x80\x94 unknown x-* keys are explicitly permitted and ignored by conformant tooling.
Extensions to define (v1)
| Key |
Position |
Mirrors Altair YAML |
Status |
x-altair-action |
operation |
action: (FQCN of generated Action) |
Ship now |
x-altair-persistence |
operation |
persistence: block |
Ship now |
x-altair-queue |
operation |
queue: block |
Ship now |
x-altair-idempotency |
operation |
idempotency: block |
Ship now (key only; primitive lands separately) |
x-altair-webhook |
operation |
webhook: block |
Ship now (key only; framework lands separately) |
x-altair-input-location |
schema/property |
param in: (path/query/header) |
Ship now |
Each extension's JSON Schema lives under docs/openapi/extensions/x-altair-*.schema.json and is linked from the docs page so external tooling can validate.
Acceptance criteria
Out of scope
- The underlying webhook framework, idempotency primitive, and any new persistence/queue features. This issue defines the extension keys that point at them; the primitives ship under their own issues. (
x-altair-idempotency and x-altair-webhook are emitted/imported as-is; the runtime simply has no implementation to wire them to yet, which is fine.)
Notes
Pick x-altair- as the prefix (not x-univeros-) for consistency with internal namespacing \xe2\x80\x94 the package is univeros/framework, the PHP namespace is Altair\*, and OpenAPI consumers will see what's already on the wire from this framework. Don't bikeshed; pick and lock.
Part of #160. Depends on #161 (emitter) and #162 (CLI). Consumed by the round-trip gate.
Goal
Define a small set of
x-altair-*OpenAPI specification extensions that the forward path (spec:emit-openapi) writes into OpenAPI and the reverse path (openapi:import) reads back out. Lets a round-trip preserve Univeros-specific concerns \xe2\x80\x94 persistence entity, queue handler, webhook contract, idempotency policy \xe2\x80\x94 that OpenAPI 3.1 itself cannot express.Why
OpenAPI describes the wire shape. Univeros specs describe more: which response maps to a Cycle entity, which side-effect dispatches a message, which endpoint is a webhook receiver, what the idempotency window is. If these concerns don't round-trip, importing then re-emitting silently loses them, and the round-trip drift gate becomes impossible to make green.
Adding them as
x-altair-*extensions is the OpenAPI-idiomatic way to carry framework metadata while staying valid 3.1 \xe2\x80\x94 unknownx-*keys are explicitly permitted and ignored by conformant tooling.Extensions to define (v1)
x-altair-actionaction:(FQCN of generated Action)x-altair-persistencepersistence:blockx-altair-queuequeue:blockx-altair-idempotencyidempotency:blockx-altair-webhookwebhook:blockx-altair-input-locationin:(path/query/header)Each extension's JSON Schema lives under
docs/openapi/extensions/x-altair-*.schema.jsonand is linked from the docs page so external tooling can validate.Acceptance criteria
spec:emit-openapiwritesx-altair-*blocks for any spec field not expressible in pure OpenAPI 3.1openapi:importreadsx-altair-*blocks and emits the equivalent Altair YAML blocksdocs/openapi/extensions/x-altair-*keys produce a warning, not a failure (forward compatibility \xe2\x80\x94 a v2 extension can't break a v1 emitter)docs/openapi/extensions.mdenumerates every key with examplesOut of scope
x-altair-idempotencyandx-altair-webhookare emitted/imported as-is; the runtime simply has no implementation to wire them to yet, which is fine.)Notes
Pick
x-altair-as the prefix (notx-univeros-) for consistency with internal namespacing \xe2\x80\x94 the package isuniveros/framework, the PHP namespace isAltair\*, and OpenAPI consumers will see what's already on the wire from this framework. Don't bikeshed; pick and lock.