Skip to content

fix(kit): refund rejected replay attempts - #273

Merged
hyochan merged 2 commits into
mainfrom
fix/kit-replay-token-refund
Aug 2, 2026
Merged

hyochan merged 2 commits into
mainfrom
fix/kit-replay-token-refund

Conversation

@hyochan

@hyochan hyochan commented Aug 2, 2026 •

Copy link
Copy Markdown
Member

Summary

  • refund replay-budget tokens when the in-flight guard rejects verification with 503 SERVICE_BUSY
  • preserve replay charges for accepted verification work, including downstream 503 responses
  • record the manual routine docs deployment policy without creating a routine Docs GitHub Release

Implementation

  • mark capacity rejections on the Hono context so the outer replay guard can refund only attempts that never received a verification slot
  • keep the existing middleware order and negative-verdict cooldown behavior intact
  • cover capacity rejection, successful verification, and downstream 503 behavior with integration tests
  • document the replay-budget behavior on the IAPKit Operations page
  • make the repository SSOT explicit that merging does not deploy production docs

Deployment note

After this PR is merged, deploy routine production docs manually from a clean, up-to-date main checkout with npm run deploy. Do not create a routine Docs GitHub Release; release.yml remains for an actual spec release or an explicit maintainer request.

No deployment, release, or merge is performed by this PR.

Preview

See the Preview comment for a short recording of the locally rendered IAPKit Operations page.

Test plan

  • bun install --frozen-lockfile
  • bun run --filter @hyodotdev/openiap-kit lint
  • Kit Prettier check
  • bun run --filter @hyodotdev/openiap-kit test (75 files, 884 tests)
  • bun run --filter @hyodotdev/openiap-kit smoke:server
  • bun run audit:parity
  • bun run audit:docs
  • node --test scripts/release-branch-policy.test.mjs
  • bun run audit:release-state
  • two consecutive clean $review-self snapshots separated by five minutes

Summary by CodeRabbit

  • Bug Fixes

    • Prevented verification attempts rejected due to capacity limits from consuming replay capacity.
    • Ensured retries remain classified as SERVICE_BUSY instead of incorrectly becoming DUPLICATE_PAYLOAD.
    • Preserved replay charges for successful verification and downstream 503 responses.
  • Documentation

    • Clarified manual production documentation deployment procedures and verification steps.
    • Distinguished routine documentation deployments from specification releases.
    • Documented deployment behavior after combined Kit and documentation changes.
    • Clarified that routine deployments should not create a documentation release.

Refund the per-payload replay token only when the in-flight capacity guard returns SERVICE_BUSY before verification starts. Preserve charges for accepted work, including downstream 503 responses, and cover the behavior with integration tests.

Record that routine production docs deploys are manual and do not create a Docs GitHub Release.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@hyochan hyochan added openiap-kit packages/kit (IAPKit SaaS) 📖 documentation Improvements or additions to documentation 🛠 bugfix All kinds of bug fixes labels Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 73558058-e91c-4155-9244-613966337314

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR refunds replay capacity when verification requests are rejected before slot allocation. It adds integration tests and updates operations documentation. It also separates routine documentation deployment from specification releases and adds deployment verification guidance.

Changes

Replay capacity handling

Layer / File(s) Summary
Capacity rejection signaling
packages/kit/server/api/v1/in-flight-limit.ts, packages/kit/server/api/v1/routes.ts
The in-flight limit middleware records capacity rejection in the request context. Middleware documentation describes the replay-guard notification.
Replay refund and validation
packages/kit/server/api/v1/replay-guard.ts, packages/kit/server/api/v1/replay-guard.integration.test.ts, packages/kit/src/pages/docs/sections/operations.tsx
The replay guard refunds attempts rejected before verification. Tests cover SERVICE_BUSY, successful verification, and downstream 503 behavior. Operations documentation describes the resulting replay behavior.

Documentation deployment guidance

Layer / File(s) Summary
Deployment workflow documentation
.claude/guides/*, knowledge/_claude-context/context.md, knowledge/internal/06-git-deployment.md
Documentation states that production docs require manual deployment, separates routine deployment from specification release, and adds timestamp and page-content verification steps.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • hyodotdev/openiap#169: Both changes modify replay-guard middleware cleanup and failure handling.
  • hyodotdev/openiap#269: This PR coordinates with the in-flight limit middleware and routes introduced by that PR.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: refunding replay capacity for rejected verification attempts.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/kit-replay-token-refund

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyochan

hyochan commented Aug 2, 2026

Copy link
Copy Markdown
Member Author

Preview

Locally rendered IAPKit Operations documentation showing the replay-budget behavior for 503 SERVICE_BUSY.

replay-budget-preview.mp4

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/kit/src/pages/docs/sections/operations.tsx`:
- Around line 59-62: Update the documentation around X-Concurrency-Scope to
clarify that capacity-rejected requests may access the replay guard’s bucket
store and have their token refunded, but never reach an upstream verification
store; preserve the SERVICE_BUSY versus DUPLICATE_PAYLOAD behavior description.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cd261260-82d7-48e9-b5be-8d6b4a9fd585

📥 Commits

Reviewing files that changed from the base of the PR and between 2e6bb7d and c4ccd8a.

📒 Files selected for processing (9)
  • .claude/guides/07-docs-package.md
  • .claude/guides/08-deployment.md
  • knowledge/_claude-context/context.md
  • knowledge/internal/06-git-deployment.md
  • packages/kit/server/api/v1/in-flight-limit.ts
  • packages/kit/server/api/v1/replay-guard.integration.test.ts
  • packages/kit/server/api/v1/replay-guard.ts
  • packages/kit/server/api/v1/routes.ts
  • packages/kit/src/pages/docs/sections/operations.tsx

Comment thread packages/kit/src/pages/docs/sections/operations.tsx Outdated
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts IAPKit’s /v1/purchase/verify replay-budget behavior so that requests rejected before receiving verification capacity (503 SERVICE_BUSY from the in-flight limiter) do not consume a per-payload replay token, while preserving replay charges for requests that were admitted to capacity (including downstream 503s). It also documents the operational implications for docs deployment and the updated replay-budget semantics.

Changes:

  • Propagate an in-flight capacity rejection signal (verifyCapacityRejected) so the outer replay guard can refund the consumed replay token for SERVICE_BUSY rejections.
  • Add integration tests covering capacity rejection refunds, successful verification charges, and downstream 503 behavior after capacity acceptance.
  • Update operations + deployment documentation to clarify replay-budget semantics and that routine docs deployment is manual and should not create a routine Docs GitHub Release.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/kit/src/pages/docs/sections/operations.tsx Documents that capacity rejections don’t consume replay budget and retries remain SERVICE_BUSY.
packages/kit/server/api/v1/routes.ts Updates middleware-order commentary and adds a typed per-request flag for capacity rejections.
packages/kit/server/api/v1/replay-guard.ts Refunds replay tokens when the in-flight limiter rejects with SERVICE_BUSY before verification work starts.
packages/kit/server/api/v1/replay-guard.integration.test.ts Adds integration tests for refund vs. charge behavior across capacity rejection and downstream failures.
packages/kit/server/api/v1/in-flight-limit.ts Sets verifyCapacityRejected on capacity rejections so the replay guard can refund the attempt.
knowledge/internal/06-git-deployment.md Clarifies manual docs deployment, merge-vs-deploy expectations, and “no routine docs GitHub Release” policy.
knowledge/_claude-context/context.md Regenerates compiled context to reflect updated deployment documentation.
.claude/guides/08-deployment.md Updates deployment surface matrix to distinguish routine docs deploys vs spec releases.
.claude/guides/07-docs-package.md Aligns docs package guidance with the manual deploy / no-routine-release policy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hyodotdev hyodotdev deleted a comment from coderabbitai Bot Aug 2, 2026
@hyochan
hyochan merged commit 8e13e07 into main Aug 2, 2026
14 checks passed
@hyochan
hyochan deleted the fix/kit-replay-token-refund branch August 2, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠 bugfix All kinds of bug fixes 📖 documentation Improvements or additions to documentation openiap-kit packages/kit (IAPKit SaaS)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants