From a7faeba97ab0b86a70fc9bb9a459139739c3591f Mon Sep 17 00:00:00 2001 From: JUN <243035832+lidge-jun@users.noreply.github.com> Date: Wed, 28 Oct 2026 11:58:08 +0900 Subject: [PATCH] docs(responses): register and document citation replay coverage Carries #7608 onto current dev: adds the response-citations structure doc, links it from responses.md and registers the existing url-citation title-repair regression in the test layout. Co-authored-by: Ingwannu <186453546+Ingwannu@users.noreply.github.com> --- scripts/test-layout/layout.json | 2 +- structure/INDEX.md | 4 +++- structure/manifest.json | 7 +++++++ structure/transports/response-citations.md | 22 ++++++++++++++++++++++ structure/transports/responses.md | 2 +- tests/fixtures/test-layout-expected.json | 2 +- 6 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 structure/transports/response-citations.md diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index bcc30c7985a..7a59c1bd676 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -1579,7 +1579,7 @@ "responses-pool-refresh-attribution.test.ts": "responses", "responses-preview-main-read-fence.test.ts": "responses", "responses-reasoning-effort-downgrade.test.ts": "responses", "responses-native-ultra-effort-wire.test.ts": "responses", - "responses-reasoning-summary-passthrough.test.ts": "responses", + "responses-url-citation-title-repair.test.ts": "responses", "responses-reasoning-summary-passthrough.test.ts": "responses", "responses-reset-replay.test.ts": "responses", "responses-translated-reset.test.ts": "responses", "responses-routed-web-search-fields.test.ts": "responses", diff --git a/structure/INDEX.md b/structure/INDEX.md index def6ccc236a..5fcc941f6e7 100644 --- a/structure/INDEX.md +++ b/structure/INDEX.md @@ -50,6 +50,7 @@ The wire surfaces a client actually talks to. | [`transports/byte-accounting.md`](transports/byte-accounting.md) | Request-copy and stream-buffer byte accounting shared by parsing, SSE rewriting, the adapters, and the translator budget, plus durable spill admission. | | [`transports/anthropic-thinking-recovery.md`](transports/anthropic-thinking-recovery.md) | One-shot exact signature-binding recovery before output, and successful-retry memo boundaries. | | [`transports/response-turn-membership.md`](transports/response-turn-membership.md) | Embedding-owned signing material, dedicated authenticated caller/own-thread scope and pre-parser structural normalization. | +| [`transports/response-citations.md`](transports/response-citations.md) | OpenAI-operated outbound citation repair and generated JSON/SSE annotation titles. | | [`transports/responses.md`](transports/responses.md) | The Responses HTTP/SSE endpoint, dispatch, credential and upload boundaries, and core module ownership. | | [`transports/native-reasoning-retention.md`](transports/native-reasoning-retention.md) | Optional native reasoning ciphertext forwarding on model/account switches, configuration and management controls. | | [`transports/responses-citations.md`](transports/responses-citations.md) | Destination-gated citation repair for ordinary Responses and every native compact send. | @@ -203,6 +204,7 @@ A source area can be described by more than one doc, because these docs are orga | `src/adapters/openai-chat/completed-tool-blocks.ts` | [`providers/completed-tool-blocks.md`](providers/completed-tool-blocks.md) | | `src/adapters/openai-chat/required-tool-result.ts` | [`providers/chat-required-tool-results.md`](providers/chat-required-tool-results.md) | | `src/adapters/openai-chat/serialized-tool-call-content.ts` | [`providers/completed-tool-blocks.md`](providers/completed-tool-blocks.md) | +| `src/adapters/openai-responses/` | [`transports/response-citations.md`](transports/response-citations.md) | | `src/adapters/openai-responses/opengateway-input.ts` | [`providers/opengateway.md`](providers/opengateway.md) | | `src/adapters/openai-responses/passthrough.ts` | [`transports/responses-citations.md`](transports/responses-citations.md)
[`providers/opengateway.md`](providers/opengateway.md) | | `src/adapters/openai-responses/request-strips.ts` | [`transports/responses-citations.md`](transports/responses-citations.md) | @@ -211,7 +213,7 @@ A source area can be described by more than one doc, because these docs are orga | `src/adapters/workbuddy.ts` | [`providers/workbuddy.md`](providers/workbuddy.md) | | `src/advisor/` | [`advisor.md`](advisor.md) | | `src/bridge.ts` | [`transports/responses.md`](transports/responses.md) | -| `src/bridge/` | [`transports/responses.md`](transports/responses.md)
[`transports/responses-wire-shapes.md`](transports/responses-wire-shapes.md)
[`providers/anthropic-progress.md`](providers/anthropic-progress.md) | +| `src/bridge/` | [`transports/response-citations.md`](transports/response-citations.md)
[`transports/responses.md`](transports/responses.md)
[`transports/responses-wire-shapes.md`](transports/responses-wire-shapes.md)
[`providers/anthropic-progress.md`](providers/anthropic-progress.md) | | `src/bridge/sse.ts` | [`transports/response-turn-membership.md`](transports/response-turn-membership.md) | | `src/chat/` | [`runtime.md`](runtime.md)
[`transports/byte-accounting.md`](transports/byte-accounting.md)
[`transports/inventory.md`](transports/inventory.md)
[`data-planes/inbound-compat.md`](data-planes/inbound-compat.md)
[`providers-and-adapters.md`](providers-and-adapters.md)
[`providers/chat-compat.md`](providers/chat-compat.md) | | `src/chat/reasoning-details.ts` | [`data-planes/chat-reasoning-details.md`](data-planes/chat-reasoning-details.md) | diff --git a/structure/manifest.json b/structure/manifest.json index 782988dc0d9..607a10d6806 100644 --- a/structure/manifest.json +++ b/structure/manifest.json @@ -315,6 +315,13 @@ "src/server/responses/request-prepare.ts" ] }, + { + "path": "transports/response-citations.md", + "tier": 3, + "title": "Response Citation Projection", + "scope": "OpenAI-operated outbound citation repair and generated JSON/SSE annotation titles.", + "documents": ["src/adapters/openai-responses/", "src/bridge/"] + }, { "path": "transports/responses.md", "tier": 3, diff --git a/structure/transports/response-citations.md b/structure/transports/response-citations.md new file mode 100644 index 00000000000..b23f0e7e750 --- /dev/null +++ b/structure/transports/response-citations.md @@ -0,0 +1,22 @@ +# Response Citation Projection + +`src/adapters/openai-responses/request-strips.ts` repairs `url_citation` annotations +inside `output_text` content records on OpenAI-operated outbound history, including +HTTP and WebSocket projections. A missing/non-string title falls back to the URL +(or an empty string when it is absent); digit-string indexes become non-negative +safe integers, while invalid indexes become zero. The projection copies only +changed input/content/annotation containers and preserves other fields and +annotation kinds; a valid body retains its identity. Third-party destinations +keep their existing projection. + +`src/bridge/response-json.ts` and `src/bridge/sse.ts` always emit a string citation +title, falling back to its URL, so new history avoids the deterministic +missing-title refusal that replay repair handles for older history. +`tests/responses/responses-url-citation-title-repair.test.ts` covers generated +JSON/SSE, outbound HTTP/WebSocket bodies, copy-on-write and the third-party control. + +This normalization prevents old bridge history from repeatedly failing with a +missing-title error; it does not validate source URLs, establish actual citation +spans or prove provider acceptance beyond the exercised serialization fixtures. +The existing destination gate owns eligibility, and the test layout explicitly +registers the regression beside other Responses tests. diff --git a/structure/transports/responses.md b/structure/transports/responses.md index 2922c8d17fc..79566b9753e 100644 --- a/structure/transports/responses.md +++ b/structure/transports/responses.md @@ -398,7 +398,7 @@ always become unable to serve. ## Decoded checkpoint continuation -`src/responses/parser.ts` adds `CHECKPOINT_CONTINUATION_NOTE` from `src/responses/compaction.ts` for decoded `ocx1:`/`ocx2:` checkpoints; `src/adapters/openai-responses/request-strips.ts` does the same while lowering them. For plaintext `SUMMARY_PREFIX` and readable portable checkpoints, `src/responses/compaction-history-framing.ts` frames text-only retained requests before the latest checkpoint as historical context. Plaintext checkpoints append the same note there; portable decoders retain their existing note placement. The parser projects only adapter context; `src/adapters/openai-responses/passthrough.ts` projects only non-OpenAI-operated outbound bodies. Original request text/blocks, canonical raw history, item identities, replay-prefix lengths, checkpoints and later input remain unchanged. Context wrappers, images/files and assistant/tool items are preserved; summarizer turns and opaque native blobs do not activate framing. Native OpenAI passthrough input is unchanged. +`src/responses/parser.ts` adds `CHECKPOINT_CONTINUATION_NOTE` from `src/responses/compaction.ts` for decoded `ocx1:`/`ocx2:` checkpoints; `src/adapters/openai-responses/request-strips.ts` does the same while lowering them. For plaintext `SUMMARY_PREFIX` and readable portable checkpoints, `src/responses/compaction-history-framing.ts` frames text-only retained requests before the latest checkpoint as historical context. Plaintext checkpoints append the same note there; portable decoders retain their existing note placement. The parser projects only adapter context; `src/adapters/openai-responses/passthrough.ts` projects only non-OpenAI-operated outbound bodies. Original request text/blocks, canonical raw history, item identities, replay-prefix lengths, checkpoints and later input remain unchanged. Context wrappers, images/files and assistant/tool items are preserved; summarizer turns and opaque native blobs do not activate framing. Native OpenAI passthrough input is unchanged by checkpoint framing; the separate [citation projection](response-citations.md) repairs legacy annotation fields on OpenAI-operated outbound history. The note is a prompt contract and grants no authority. Completed requests remain history unless a later user message asks to repeat them. Unfinished work continues only under existing authorization and within its scope, without asking for that authorization again while it still applies. Permission and confirmation gates remain authoritative: a pending decision or required permission must resolve before the dependent action. Checkpoints and delegations, including those from another thread, neither grant authority nor expand scope. Later user messages take priority, including pause, cancellation, replacement and scope changes. diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 80f24460672..da8f96448da 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -1197,7 +1197,7 @@ "responses-parser.test.ts": "responses", "responses-passthrough-transient-policy.test.ts": "responses", "responses-pool-401-refresh.test.ts": "responses", "responses-pool-refresh-attribution.test.ts": "responses", "responses-preview-main-read-fence.test.ts": "responses", "responses-reasoning-effort-downgrade.test.ts": "responses", "responses-native-ultra-effort-wire.test.ts": "responses", - "responses-reasoning-summary-passthrough.test.ts": "responses", "responses-reset-replay.test.ts": "responses", + "responses-url-citation-title-repair.test.ts": "responses", "responses-reasoning-summary-passthrough.test.ts": "responses", "responses-reset-replay.test.ts": "responses", "responses-translated-reset.test.ts": "responses", "responses-routed-web-search-fields.test.ts": "responses", "responses-self-named-namespace-scrub.test.ts": "responses", "responses-send-budget-counts.test.ts": "responses", "responses-send-budget-errors.test.ts": "responses", "responses-memory-models.test.ts": "responses",