Repository navigation
feat(durable): list, read, and decide durable approvals - #341
Merged
Merged
Conversation
Add client.durable.approvals with list, get, stats, approve, and deny over the durable approvals endpoints, backed by the regenerated client. Responses map to frozen Data records; a deleted function, execution, or decider keeps its name with a nil id. Decision times and daily dates are validated, and daily dates stay YYYY-MM-DD UTC strings. HTTP 403 now raises Volcano::Error::PermissionDeniedError, a subclass of AuthenticationError, so existing rescues keep working. Co-authored-by: Cursor <cursoragent@cursor.com>
Match the Python SDK's name for the HTTP 403 error. Neither SDK has released it yet. Also say that an approval's decision is nil unless it was approved or denied, and document the nil decided_by in docs/functions.md. Co-authored-by: Cursor <cursoragent@cursor.com>
… defect checkout Co-authored-by: Cursor <cursoragent@cursor.com>
…s exception Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Steep 2.1 types DurableApproval.members.first as the literal :id, so `== :id` narrows to always true and the raise reads as an unreachable branch. Symbols are singletons, so an identity check keeps the same runtime assertion without that narrowing, as main did for true/false. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Oct 7, 2026
subnetmarco
commented
Oct 8, 2026
subnetmarco
left a comment
Member
Author
There was a problem hiding this comment.
Reviewed at 561e1a3. I found no P1 or P2 issues:
- Mapping 403 to
PermissionDeniedError < AuthenticationErroris backward compatible. 403 used to raiseAuthenticationError, nothing compares exact error classes, and the refresh paths still key on 401. - The OpenAPI matches Hosting's bundle, and query names, enums, conflict codes, and pagination all match.
- The records are frozen all the way down, and the RBS signatures match the implementation.
- rubocop, Steep, and the approval specs pass.
Two P3s inline.
… on window bounds Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Oct 8, 2026
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # lib/volcano/generated/README.md # lib/volcano/generated/lib/volcano-generated/api/durable_functions_api.rb # openapi/openapi.yaml # spec/volcano_generation_spec.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change
List, read, and decide durable approvals from Ruby. Tracks https://github.com/Kong/volcano-hosting/pull/1678.
client.durable.approvals:list(project_id, filters),get,stats(function:, from:, to:),approve(..., comment:),deny(..., comment:), returning frozenDatarecords. A decider with an empty email is accepted, and a string window bound must carry an offset (Zor±hh:mm), since one without would be read in the host's time zone.Volcano::Error::PermissionDeniedError, a subclass ofAuthenticationError, so existingrescue AuthenticationErrorstill catches it. A project access token deciding an approval gets this error.wait_for_approval; workflows request approvals from JavaScript or Python.main) flagged an unreachable branch in a type fixture; it now checks by identity.Verification
bundle exec rake quality: pass. Audit, generated client check, RuboCop (no offenses), Steep (both configurations), 2020 examples with 100% line and branch coverage, all injected defects detected, package smoke, documented quickstart.Cross-language impact
Classify this change: public facade / wire contract / shared behavior.
tests/sdk-contract/features/durable-approvals.featurewith JS, Python, and Ruby bindings in https://github.com/Kong/volcano-hosting/pull/1678.README.mdanddocs/functions.mdhere; JS and Python in their PRs.Merge order
404.localmode-e2e. That suite needs a nightly local-mode image with approvals, which exists only once Hosting merges. Hosting's merge queue runs its CLI E2E against CLImain, so the CLI goes first.