Repository navigation
openapi-codegen: classify operations for safe retry hooks #36
Copy link
Copy link
Open
Labels
doingThe work step of the issue loop is on itThe work step of the issue loop is on itlib:openapi-codegenphase:createdtype:fix
Milestone
Description
Goal
openapi-codegen: classify operations for safe retry hooks produces the observable result frozen for faberline/axiom#3856.
How
Verified premises
- libs/openapi-codegen/README.md:1 names the owning openapi-codegen product or library.
Change points
- Add the issue-specific executable contract at
libs/openapi-codegen/e2e/legacy-3856-lib.rs. - Make the bounded implementation change under
libs/openapi-codegen/src/lib.rsand the exact paths frozen below.
Frozen decisions
- Keep the release, priority, work boundary, exclusions, and acceptance from openapi-codegen: classify operations for safe retry hooks axiom#3856.
- Do not widen the public API, wire format, durable format, or release boundary unless the frozen legacy contract says so.
Frozen legacy body
The exact pre-migration body SHA-256 is efd6319a64447ac3db3bed78dee00eecc43e700d40fcd54b816b38b253cbbeac.
## Problem
Release `lumen@0.12.0` needs one bounded result that can be implemented and verified independently.
## Required result
Emit service-supplied retry classification for safe reads, idempotency-key writes, and ambiguous non-retryable mutations.
## Scope
This issue owns only the result above. It is a child of faberline/axiom#3808.
## Acceptance Criteria
- [ ] All languages expose the classification and never infer write safety from HTTP method alone.
- [ ] Targeted tests include a negative control for the main failure mode.
- [ ] Support state and roadmap evidence change only when the implementation is complete.
- [ ] No credential, private key, secret value, or infrastructure residue enters logs or tracker output.
## Verification
- Required evidence: All languages expose the classification and never infer write safety from HTTP method alone.
- Run the exact project-required gates before the parent epic closes.
- Record the tested commit. A local candidate is not release evidence.
## Reference Context
- Parent release epic: faberline/axiom#3808
- Product contract commit: [`3d0eb090139e`](https://github.com/chrischeng-c4/axiom/commit/3d0eb090139e4c3d44f76442c402d26cc385c559)
- [`operation-aware-retry-hooks`](https://github.com/chrischeng-c4/axiom/blob/3d0eb090139e4c3d44f76442c402d26cc385c559/libs/openapi-codegen/ROADMAP.md#operation-aware-retry-hooks) in `libs/openapi-codegen`
<!-- lumen-release-backlog-reorg-2026-08-23 -->
Acceptance
| # | command | current | target | why it cannot hold by accident |
|---|---|---|---|---|
| 1 | cargo test -p openapi-codegen |
faberline/axiom#3856 has no canonical fix lifecycle evidence. |
The replacement passes its frozen acceptance and records canonical fix evidence. |
The full owner gate executes the affected project instead of matching tracker prose. |
| 2 | python3 scripts/meta/project_docs_contract.py check libs/openapi-codegen --format json |
The replacement has no final product-document readback. | The owning product-document set passes at the accepted commit. | The checker resolves links, support state, outcomes, and gates from repository bytes. |
Negative control
Temporarily remove the Current support link from libs/openapi-codegen/README.md. The document gate above must fail. Restore libs/openapi-codegen/README.md to SHA-256 87cacfacebe0ded59e3124c9a95d0ebc8322a050177907e38aefbf1cf66445bd before acceptance.
Never
This addresses the worker implementing this work item, not the controller reviewing it.
Must not touch
- Do not edit project roots outside
libs/openapi-codegen/unless the frozen contract names a prerequisite owner.
Must not do
- Do not change tracker order, tags, releases, or publication state.
- Do not claim acceptance from a candidate, filtered test, or summary alone.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
doingThe work step of the issue loop is on itThe work step of the issue loop is on itlib:openapi-codegenphase:createdtype:fix
Activity
chrischeng-c4 commentedon Oct 23, 2026
Scope of this spec: the first slice of #36 only, the shared model of the service-supplied retry class. The issue body paths under
libs/openapi-codegen/are stale; the crate iscrates/openapi-codegen/, and thee2e/legacy-3856-lib.rsfile and theproject_docs_contract.pygate do not exist here. Emitting the classification in TypeScript, Python, and Rust, the cross-language fixtures, and the STATUS/ROADMAP change are later slices: open them as smaller issues once this one is merged. Do not flipoperation-aware-retry-hooksinSTATUS.mdin this PR. The namex-retry-classand its values follow the existingx-post-twinvendor-extension pattern; the ROADMAP boundary stays: the generator carries the class, the service decides it.Goal
OperationIRincrates/openapi-codegen/src/domain/ir/operations.rshas no retry meaning;is_queryonly picks a TanStack hook kind. Read an operation'sx-retry-classvendor extension (already captured inOperation.extensions, see howpost_twin_pathreadsx-post-twin) into a typedRetryClassIR, so the emitters can later expose it. The class is never inferred from the HTTP method: aGETwithout the extension isUnclassified, and aPOSTis neverSafeRead.Acceptance
pub enum RetryClassIR { SafeRead, IdempotencyKey, NonRetryable, Unclassified }andOperationIR.retry_class: RetryClassIR.x-retry-classstring values"safe-read","idempotency-key","non-retryable"map to the first three variants. A missing extension givesUnclassified."yes",true) givesUnclassified, never a guess; it does not panic and does not fail generation in this slice.testsmodule ofoperations.rs: each of the three values; missing extension onget,post,delete, andquery; an unknown string; a non-string value; the extension on anadditionalOperationsentry.build_onesetSafeReadforgetwhen the extension is missing makes the missing-extensiongetrow fail, and only the rows that assertUnclassified.Never
is_query, or the presence of an idempotency header parameter.STATUS.md, orROADMAP.md.crates/openapi-codegen/src/api/beyond re-exportingRetryClassIRnext to theOperationIRre-export inapi/ir.rs.crates/openapi-codegen/Cargo.toml.OperationIR: rebase if either merges first.Gate
cargo test --locked -p openapi-codegen cargo clippy --locked -p openapi-codegen --all-targets -- -D warningschrischeng-c4 commentedon Oct 24, 2026
Work submitted in #68; waiting for required CI on the current head.