Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions devlog/_plan/261004_translated_reset_retry/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Translated Responses pre-header reset retry

A translated Responses request currently refuses a connection reset before headers even when its provider enables `retryOnReset`. Carry public PR #6525 through the existing request-wide grant and send accounting, with direct regression coverage for recovery legs and a real loopback disconnect.

- Archetype: satisfy-spec; trigger: next-release replacement of public PR #6525.
- Goal: one focused ordinary draft PR against `dev`, preserving the source behavior and authorship.
- Class: C3 transport repair, with C4 care for the replay/send-budget contract.
- Non-goals: adapter-owned fetch recovery, translated post-header recovery, merge, source closure, release/version changes, installed runtime or account changes, paid/live requests, native GitHub stacks.
- Verifier: focused handler and retry tests, typecheck, structure/privacy/layout/ratchet gates, docs build, independent review and current-head hosted CI inspection. Full/changed local suites are excluded by the explicit concurrent-lane resource contract.
- Stop: attributed replacement published and attached; source coverage accounted; focused gates green; applicable review findings fixed; hosted CI inspected with missing/native/live evidence disclosed and draft retained as needed.
- Artifacts: this unit; ignored `.tmp/next-release-retry/` contains raw evidence. New security material stays only in scratch.
- Outcomes: DONE is publication under those criteria; unresolved behavior or verification remains explicit, never described as passing.
- Escalation: scope changes beyond replay wiring; any denied publication; no new authority inferred.
- Resources: local checkout, git/gh for this lane, gpt-6.1-sol leaves, fake upstreams and ephemeral loopback only. No user token/time budget was set; use bounded commands, no shared process killing or lock bypass.

## Source and baseline

Source: #6525, commit `49c5c7012f1f27d781079231dde92562ced68594`, author Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>. Its single commit has 14 files and 10 handler cases. No source reviews/inline comments or native stack membership at inspection. Source common ancestor is `358b8ffd4c7f95237dadee1e9a5b4fedb671f4f4`; refreshed dev/base is `0818ea1812a028e1c14cd0b0511b44863407bc52`.

One cohesive work phase: plan/audit → carry and refine wiring/tests/docs → check/review → publish. No separate independently useful implementation units require a roadmap cycle.

## Existing owners and necessity

Reuse `request-resend-gate.ts`, `reset-replay.ts`, `request-send-budget.ts` and `upstream-retry.ts`; do not add a parallel retry policy or budget. Configuration alone cannot fix the missing callback; deleting the refusal would lose the safety boundary. `adapter-dispatch.ts` owns both generic send sites; public provider prose and `structure/transports/responses-failover.md` describe them. See the diff plan in `010_retry.md`.

## Consultation

V1 leaf surface, requested model gpt-6.1-sol. Architect handle (recorded in local evidence); proposal and first reflection received. RETRY-D01 shared gate, D02 external accounting, D03 exact caps with prepaid handling, D04 docs are accepted. D05 unreachable reset-then-recovery scenario was replaced by terminal-replacement and spent-grant-on-rebuild scenarios; final same-architect reflection ALIGNED on D01–D05 with no design gaps. The six reservation sites and prepaid last-slot handling are explicitly recorded in 010. Main owns the executable plan and all decisions. Documentation coverage is independently inspected by leaf (recorded in local evidence).

Independent A reviewer (recorded in local evidence) returned VERDICT: PASS with no blockers, confirming all source files/cases and reachable tests accounted. Main accepts the verdict. Baseline typecheck, structure/privacy, 561-page docs build and 77,944 link checks passed.

Implementation and focused verification are complete; see `011_verification.md` for source coverage, the combo accounting decision, current publication base and evidence limits. Publication targets an ordinary draft PR; hosted current-head results are reported in its Verification section.
49 changes: 49 additions & 0 deletions devlog/_plan/261004_translated_reset_retry/010_retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# One request-wide replay grant through translated dispatch

Depends on: existing reset-grant/send-budget owners; no new public type or config field.

## File map and concrete delta

- MODIFY `src/server/responses/adapter-dispatch.ts`: carry source #6525 imports, budget Pick fields `claimAmbiguousResend`/`sendsUsed`, memoized inbound self-contained judgment and one pre-header grant callback. Pass that same callback to both initial and rebuilt generic retry helpers. For reset opt-in, supply remaining send allowance and `noteTransientSends` to both helpers. Preserve compact prepaid sends and adapter-owned branches.
- Refine recovery accounting in that same file: all helper-counted reset-only credential/repair hop reservations must set `countedExternally` just like transient helpers; physical sends and workflow counts must agree. Exact configured transient totals must be reduced by prior sends and cannot borrow the final recovery reserve. Any adjustment stays in generic adapter dispatch and is activated by focused regressions.
- NEW `tests/responses/responses-translated-reset.test.ts`: carry all 10 original tests. Add previous-id refusal (construct valid stored predecessor if needed), post-header/output failure with exactly one physical send, shared grant across initial and rebuilt legs, explicit total across rebuilt legs, prepaid recovery accounting, and a loopback upstream which reads a full request then closes before headers, succeeds on the replacement, and verifies identical bodies and exactly two sends. Deterministic completion signals and `finally` cleanup, no sleeps for synchronization.
- MODIFY `scripts/test-layout/layout.json` and `tests/fixtures/test-layout-expected.json`: register the new test under responses with consistent existing indentation/order.
- MODIFY `src/types/provider.ts`: describe pre-header translated generic fetch support; no type/schema change.
- MODIFY `docs-site/src/content/docs/reference/configuration/providers.md` and corresponding `fr`, `ja`, `ko`, `ru`, `tr`, `zh-cn`, `zh-tw` pages: carry source policy extension, clarify existing native-only introductory wording, retain default-off/self-contained/grant/billing caveats and explicitly exclude adapter-owned and post-header translated failures.
- MODIFY `structure/transports/responses-failover.md`: state initial/rebuilt shared-grant behavior and accounting, link added regression; keep `fetchWithResetRetry` tool-side `replaySafe` distinct from operator grant.
- Existing unit docs record decisions, verification and publication; no screenshots or raw security notes enter public commits.

## Execution and delegation

After independent A audit, a bounded gpt-6.1-sol executor owns adapter-dispatch and the new test/layout entries, with no branches/commits/goals/FSM. Main handles integration, git and evidence. A separate doc executor owns provider type comment, the eight provider pages and failover SoT. Write sets are disjoint. Fresh independent C reviewer checks all changed files and source coverage.

## Acceptance activation

| Scenario | Observable proof |
|---|---|
| Bare opt-in plus pre-header reset | HTTP 200, two byte-identical translated sends, request/workflow count two |
| No/disabled opt-in, stored or prior state | No replay; existing refusal (or prior-state admission), no spent replacement |
| Grant already spent/repeated resets | At most the configured shared replacements; refusal preserves non-replayability |
| Effort refusal then reset on rebuild | Three sends, same downgraded bytes for final two, count three |
| Initial replacement returns a recoverable-looking HTTP failure | Non-replayable refusal prevents rebuild/target hop |
| Effort refusal reaches rebuilt send with already-spent shared grant | Rebuilt reset refuses replacement; grant is not reset |
| Exact one-send/total cap/exhaustion | No physical send beyond cap, zero dispatch when initially exhausted |
| Credential/repair prepaid hop | Count every wire send exactly once; workflow matches request count |
| Abort during failing send | 499 and no replacement |
| Post-header stream failure/output | No reset replay and no second upstream request |
| Real loopback reset | Full request consumed then socket closed before headers; replacement succeeds exactly once |
| Core optional subsystem | `tests/lab/core-lab-boundary.test.ts` stays green |

## Verification

Baseline commands executed before implementation: `bun test tests/lib/ambiguous-resend-gate.test.ts tests/responses/responses-reset-replay.test.ts` (23 pass); `bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts` (27 pass); `bun run structure:check`, `bun run privacy:scan`, `bun run typecheck` (completion recorded in evidence). Test paths are direct arguments, structure/privacy scripts inspect repository files, and tsconfig includes `src`.

After implementation run the new test plus reset/reasoning-downgrade/send-budget/fast-downgrade/lib-grant and core-lab suites; repeat static gates once on final code. Docs validation uses `cd docs-site && bun install --frozen-lockfile && bun run build`. Confirm the new happy-path test fails on original dispatch before claiming regression proof. Wider native/broad coverage belongs to real hosted PR checks; `.github/workflows/ci.yml` runs on ordinary `pull_request` events, not branch pushes. Missing/skipped/pending checks remain missing proof.

## Boundary strength

Existing runtime gate executes synchronously at ambiguous replay admission and uses the shared budget; no new enforcement layer is introduced. Known bypass: adapters owning `fetchResponse` retain their own policies outside this lane. Residual: upstream may have executed an inference before reset, which is why opt-in and billing caveats remain. No claim of exactly-once upstream inference.

Documentation coverage amendment: also MODIFY `structure/transports/responses.md` reset-replay ownership row and `ResetReplayPolicy` comment at `src/types/provider.ts:71`. Qualify failover helper prose at lines 52/62 to distinguish `replaySafe` from the existing operator-grant override. Scout reviewed all 20 mapped server/type SoT documents; no other consequence changed.

Architect refinements accepted (RETRY-D02/D03): all six generic helper-funded hop sites use transient OR reset policy for `countedExternally`. Exclude an already-booked pending permit from prior sends when calculating the exact configured remaining cap; preserve its last funded slot without opening a final reserve. Assert wire count = request delta = attempt-log count, with workflow count where observable. No new runtime file owner is needed.
25 changes: 25 additions & 0 deletions devlog/_plan/261004_translated_reset_retry/011_verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Verification and source coverage

All useful behavior from public PR #6525 at `49c5c7012f1f27d781079231dde92562ced68594` is carried: initial/rebuilt generic pre-header replay, shared grant, default-off and self-contained restrictions, physical accounting, all ten original test cases, provider comments, eight translated/reference pages, and failover SoT. No source behavior is deliberately dropped or unresolved. Yuxin Qiao's public commit identity is retained in co-author trailers. Source closure remains a coordinator decision after replacement publication and verification.

The implementation adds 25 regression cases. Coverage includes complete-body loopback disconnects, previous-response expansion, post-header prelude/output failures, terminal replacement statuses, exhausted/spent grants, exact direct/rebuild ceilings, and prepaid compaction/Fast/OAuth accounting. It preserves compact-only one-send behavior. Combo admission retains its target-local initial allowance: `comboTargetSendBudget` reserves capacity for later declared targets and the child settles an already-booked send. The shared aggregate budget and replacement grant remain authoritative; this change does not redesign combo admission.

## Observed checks

- Original source test on unchanged dispatch: 6 passed, 4 failed. Failures: initial/rebuilt reset opt-in returned 429 instead of 200; repeated reset made one send instead of two; exhausted budget sent once instead of zero.
- `bun test tests/responses/responses-translated-reset.test.ts tests/responses/responses-send-budget-counts.test.ts`: 55 passed, zero failed (35 new-file cases, including all original ten; 20 existing count cases).
- `bun test tests/lib/upstream-retry.test.ts tests/codex-integration/reserve-dispatch.test.ts`: 90 passed, zero failed.
- Adjacent reset-replay, reasoning-downgrade, Fast-downgrade and ambiguous-resend-gate files: 37 passed during implementation. The combined intermediate run also exposed three combo regressions. Those were repaired, and all 20 existing count cases passed unchanged in the final 55-test run.
- `bun test tests/lab/core-lab-boundary.test.ts`: 25 passed, zero failed after implementation.
- `bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts`: 27 passed, zero failed.
- Typecheck, privacy scan and diff whitespace check passed. Structure check passed after staging the new test, as required by its Git-index path authority.
- Docs frozen install/build passed: 561 pages and 77,944 internal links.
- Curl against an isolated loopback handler and a real disconnecting upstream: opt-in succeeded with two POSTs; absent opt-in and stored turn each stopped at one and returned `x-should-retry: false`; empty/malformed bodies returned 400 with zero POSTs. Temporary servers, leases and state directory were cleaned up.

Architect consultation and independent plan audit passed. A fresh implementation reviewer returned PASS with no remaining blockers. One publication hygiene finding removed private review handles from the unpushed plan history; code and tests were unchanged.

Before publication, remote dev advanced from the inspected `0818ea1812a028e1c14cd0b0511b44863407bc52` to `87e315633978a6a0431696b952bedde83ede1a47` through release-version PR #6549. The lane was rebased onto that commit. Only inherited version files changed; the feature diff and behavior verification remain identical.

## Verification limits

Concurrent release stabilization and parallel lanes make local full/changed suites impractical under the explicit resource contract. Wider checks belong to actual current-head hosted PR CI. Missing, pending, skipped or cancelled jobs are not passing proof; retain draft status while broad/native evidence is incomplete. Native packaged runtime and live-provider acceptance were not exercised. No merge, source closure, release/deploy or installed-runtime/account changes were performed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Repair emergency compaction target allowance

The first publication's local checks missed a compaction integration regression. Hosted test4/4 on #6555 head `9e8d7817fe458041a9410bf12b7758b1c40cc43c` proved that a configured three-send emergency provider made only two sends despite shared capacity for source plus three. This cycle restores that existing behavior without changing its assertion.

Loop: satisfy-spec follow-up to the prior D publication, with hosted failure as new evidence. Goal: repair and push the same PR with focused/local and current-head CI proof. Non-goals: merge/source closure/release/runtime/account changes, new retry owners, full/changed local suites, paid/live requests. Artifacts: this document plus ignored repair evidence. Stop: regression green unchanged, protections retained, independent review PASS, repaired head published and actual CI inspected. No user token/time budget was set; use bounded managed commands. Escalate scope/authority changes only.

## Evidence and root cause

The unchanged test is `tests/responses/responses-compaction-recovery.test.ts:340`; local RED reproduced Expected3/Received2. `compaction-recovery.ts:203` reserves the emergency child's first send against the shared budget and `:262` passes that permit. At dispatch entry, shared used=2 includes source1 and prepaid emergency1. `adapter-dispatch.ts:364` subtracts used-minus-prepaid from the emergency provider's configured attempts3, yielding2. That wrongly deducts the source provider's send from the emergency target's own initial ladder; the shared-budget intersection already accounts for it.

## Diff plan

- MODIFY `src/server/responses/adapter-dispatch.ts` initialSendCap only: treat a valid `compactPrepaid` handoff like combo admission for the target-local configured initial ceiling. Before: `options.comboAttempt ? 0 : sendsUsed - prepaid`. After: `(options.comboAttempt || compactPrepaid) ? 0 : sendsUsed`. Keep `Math.min(initialSendCap, remainingTransientSendBudget(initialSendCap) + prepaid)` unchanged, plus one-use permit and helper send reports. No change to direct/rebuilt deductions, absent-policy one-send behavior, grants or adapter-owned/post-header paths.
- MODIFY `tests/responses/responses-compaction-recovery.test.ts`: retain the original failing case and assertions byte-for-byte; add a small parameter matrix proving configured emergency attempts1/2/3 and shared cap2/3/4 intersect correctly, with reset opt-in present/absent. Synthetic upstream500, one source failure, assert emergency count and shared used. Reuse the existing fixture and no new registry file.
- MODIFY `structure/transports/responses-failover.md`: clarify emergency initial provider allowance is intersected with remaining shared capacity plus already-prepaid send; source provider usage is not deducted twice.
- Update this unit's verification record and PR Verification after actual results. Existing source coverage/attribution unchanged.

Main owns runtime/SoT/evidence; a bounded leaf may implement only the test matrix. No new abstraction, configuration, dependency or public type. Reuse existing cap and budget owners; configuring or deleting the refusal cannot repair arithmetic.

## Verification and acceptance

Executed baseline command: `bun test tests/responses/responses-compaction-recovery.test.ts -t 'emergency transient 5xx retry cannot exceed the shared cap'` failed0pass1fail for the hosted signature. After repair run the full compaction file plus translated-reset, send-count, reset-replay, Fast-downgrade, and core-lab tests. Run typecheck, structure/privacy/layout/ratchet gates. Do not repeat passing checks on unchanged code. The original case must show three emergency sends and totalused4; cap2 allows one emergency, cap3 allows at mosttwo, configured1 remains one. Existing35 translated cases retain exact direct/rebuild totals, prepaid last-slot, default-off, cancellation, no post-output replay and loopback behavior.

Independent architect and audit will assess the proposed target handoff boundary. Fresh final review inspects arithmetic/negative tests and no weakened assertions. Hosted ordinary PR checks run after push; no release dispatch or merge. The prior source was closed by the coordinator, not this lane.

Architect proposal/reflection CR-D01–D05 ALIGNED: target-local admitted handoff; unchanged shared clamp; direct and absent-policy behavior intact; permit/reporting intact; grants intact. Main accepts all. Matrix expected emergency sends by attempts1/2/3 and cap2/3/4: `[1,1,1]`, `[1,2,2]`, `[1,2,3]`, each with reset present/absent. HTTP500 matrix proves policy neutrality, not reset-grant exhaustion; retained reset tests own the latter.
Loading
Loading