From d08debb7d414fe2ca644643452ff720d77499dd9 Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 22 Oct 2026 16:23:15 +0200 Subject: [PATCH 1/3] fix(registry): map Presentation write refusals at the write routes' statuses On presentation.write, binding_invalid, constraint_violation and resource_exhausted map at 400, frame_unavailable at 404 and release_mismatch at 503, the statuses the Presentation write routes serve. presentation.render keeps 422 and 409. frame_unavailable's definition names the causes it covers: a frame never stored, expired, revoked, or whose stored artifact is missing, quarantined, or fails its digest check. A frame store that fails to answer is service_unavailable, which presentation.write and presentation.render already map at 503. --- python/spec-kit/CHANGELOG.md | 6 ++++++ python/spec-kit/src/dfo_spec_kit/registry/codes.json | 12 ++++++------ registries/codes.json | 12 ++++++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index a0220df..598d28c 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -58,6 +58,12 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- On `presentation.write`, codes `binding_invalid`, `constraint_violation` + and `resource_exhausted` map at 400, `frame_unavailable` at 404 and + `release_mismatch` at 503, the statuses the Presentation write routes + serve. `presentation.render` keeps 422 for the first two and 409 for the + rest. `frame_unavailable` covers a frame that is not held in a readable + state. A frame store that fails to answer is `service_unavailable`. - Codes `identity_quarantined` (500), `service_unavailable` (503) and `internal_error` (500) map to `datasets.description` at the statuses they have on `datasets.snapshot`. diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 42fce0e..7c9f3a4 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -180,7 +180,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 422 + "http_status": 400 }, { "endpoint": "presentation.render", @@ -557,7 +557,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 422 + "http_status": 400 }, { "endpoint": "presentation.render", @@ -1447,7 +1447,7 @@ { "code": "frame_unavailable", "classification": "refusal", - "definition": "The frame the intent's frame_ref names cannot be read at request time.", + "definition": "The frame a request names is not held in a readable state: it was never stored, it has expired or been revoked, or its stored artifact is missing, quarantined, or fails its digest check.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1", @@ -1455,7 +1455,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 404 }, { "endpoint": "presentation.render", @@ -3107,7 +3107,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 503 }, { "endpoint": "presentation.render", @@ -3318,7 +3318,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 400 }, { "endpoint": "presentation.render", diff --git a/registries/codes.json b/registries/codes.json index 42fce0e..7c9f3a4 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -180,7 +180,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 422 + "http_status": 400 }, { "endpoint": "presentation.render", @@ -557,7 +557,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 422 + "http_status": 400 }, { "endpoint": "presentation.render", @@ -1447,7 +1447,7 @@ { "code": "frame_unavailable", "classification": "refusal", - "definition": "The frame the intent's frame_ref names cannot be read at request time.", + "definition": "The frame a request names is not held in a readable state: it was never stored, it has expired or been revoked, or its stored artifact is missing, quarantined, or fails its digest check.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1", @@ -1455,7 +1455,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 404 }, { "endpoint": "presentation.render", @@ -3107,7 +3107,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 503 }, { "endpoint": "presentation.render", @@ -3318,7 +3318,7 @@ { "endpoint": "presentation.write", "channel": "problem_details", - "http_status": 409 + "http_status": 400 }, { "endpoint": "presentation.render", From 0dc89eb617276bc44b8b61ff5df90d82c70745ea Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 22 Oct 2026 16:30:07 +0200 Subject: [PATCH 2/3] fix(registry): map edit_conflict on presentation.render The render routes read the stored revision they draw, and that read refuses edit_conflict (409) when the component has no current revision. edit_conflict maps to presentation.render at 409, and its definition names that case beside a revise of a revision that is no longer current. --- python/spec-kit/CHANGELOG.md | 3 +++ python/spec-kit/src/dfo_spec_kit/registry/codes.json | 7 ++++++- registries/codes.json | 7 ++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 598d28c..977f2a1 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -64,6 +64,9 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 serve. `presentation.render` keeps 422 for the first two and 409 for the rest. `frame_unavailable` covers a frame that is not held in a readable state. A frame store that fails to answer is `service_unavailable`. +- Code `edit_conflict` maps to `presentation.render` at 409, for a render + of a component that has no current revision, and its definition names + that case. - Codes `identity_quarantined` (500), `service_unavailable` (503) and `internal_error` (500) map to `datasets.description` at the statuses they have on `datasets.snapshot`. diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 7c9f3a4..228d234 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -905,7 +905,7 @@ { "code": "edit_conflict", "classification": "refusal", - "definition": "A revise_component request targets a revision that is no longer the component's current one.", + "definition": "The component's current revision is not the one the request reads or targets: a revise_component request names a revision that is no longer current, or the component has no current revision.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1", @@ -914,6 +914,11 @@ "endpoint": "presentation.write", "channel": "problem_details", "http_status": 409 + }, + { + "endpoint": "presentation.render", + "channel": "problem_details", + "http_status": 409 } ], "lifecycle": "active" diff --git a/registries/codes.json b/registries/codes.json index 7c9f3a4..228d234 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -905,7 +905,7 @@ { "code": "edit_conflict", "classification": "refusal", - "definition": "A revise_component request targets a revision that is no longer the component's current one.", + "definition": "The component's current revision is not the one the request reads or targets: a revise_component request names a revision that is no longer current, or the component has no current revision.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1", @@ -914,6 +914,11 @@ "endpoint": "presentation.write", "channel": "problem_details", "http_status": 409 + }, + { + "endpoint": "presentation.render", + "channel": "problem_details", + "http_status": 409 } ], "lifecycle": "active" From 4f927c09040fc287f81fc5d81ce22eebe3caa2fd Mon Sep 17 00:00:00 2001 From: Jorge Rivera Date: Thu, 22 Oct 2026 16:43:37 +0200 Subject: [PATCH 3/3] docs(registry): name every case frame_unavailable covers frame_unavailable's definition names each case Presentation refuses with it: a frame never stored or published, expired, or revoked, a spec in quarantine, and a stored artifact that is missing, fails its digest check, does not decode, or holds more rows than Presentation loads. --- python/spec-kit/CHANGELOG.md | 5 +++-- python/spec-kit/src/dfo_spec_kit/registry/codes.json | 2 +- registries/codes.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/python/spec-kit/CHANGELOG.md b/python/spec-kit/CHANGELOG.md index 977f2a1..0f09221 100644 --- a/python/spec-kit/CHANGELOG.md +++ b/python/spec-kit/CHANGELOG.md @@ -62,8 +62,9 @@ and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 and `resource_exhausted` map at 400, `frame_unavailable` at 404 and `release_mismatch` at 503, the statuses the Presentation write routes serve. `presentation.render` keeps 422 for the first two and 409 for the - rest. `frame_unavailable` covers a frame that is not held in a readable - state. A frame store that fails to answer is `service_unavailable`. + rest. `frame_unavailable` covers a frame that is not held in a state + Presentation can load, and its definition names each case. A frame store + that fails to answer is `service_unavailable`. - Code `edit_conflict` maps to `presentation.render` at 409, for a render of a component that has no current revision, and its definition names that case. diff --git a/python/spec-kit/src/dfo_spec_kit/registry/codes.json b/python/spec-kit/src/dfo_spec_kit/registry/codes.json index 228d234..ed52408 100644 --- a/python/spec-kit/src/dfo_spec_kit/registry/codes.json +++ b/python/spec-kit/src/dfo_spec_kit/registry/codes.json @@ -1452,7 +1452,7 @@ { "code": "frame_unavailable", "classification": "refusal", - "definition": "The frame a request names is not held in a readable state: it was never stored, it has expired or been revoked, or its stored artifact is missing, quarantined, or fails its digest check.", + "definition": "The frame a request names is not held in a state Presentation can load: it was never stored or published, it has expired or been revoked, its spec is quarantined, or its stored artifact is missing, fails its digest check, does not decode, or holds more rows than Presentation loads.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1", diff --git a/registries/codes.json b/registries/codes.json index 228d234..ed52408 100644 --- a/registries/codes.json +++ b/registries/codes.json @@ -1452,7 +1452,7 @@ { "code": "frame_unavailable", "classification": "refusal", - "definition": "The frame a request names is not held in a readable state: it was never stored, it has expired or been revoked, or its stored artifact is missing, quarantined, or fails its digest check.", + "definition": "The frame a request names is not held in a state Presentation can load: it was never stored or published, it has expired or been revoked, its spec is quarantined, or its stored artifact is missing, fails its digest check, does not decode, or holds more rows than Presentation loads.", "owning_contract": "presentation", "owner": "platform", "introduced_in": "v1",