Runtime

Reliable Orchestration of an OpenAI-Backed Daily Brief Workflow

Report summary

InternationalIntelligence.org should treat the OpenAI Responses API as a subordinate asynchronous execution service , not as the authority for the Daily Brief’s publication state. The publication system’s own durable supervisor—implemented in its database and advanced through compare-and-swap transi

Status
Research archive item
Category
Runtime
Length
8,895 words
Reading time
41 minutes
Report type
architecture

Key topics

  • Runtime
  • Privacy
  • Semantic Systems
  • Research Archive
  • Strategy
  • Audit
  • Architecture
  • Governance

Research provenance

Archive status
Research archive item
Content identity
sha256:f8d0530864328408d612bfa38d9655cae7e2c6f2a410bb568b4bb2867a4e1ffb

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

Source availability: 48 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

Executive Recommendation

InternationalIntelligence.org should treat the OpenAI Responses API as a subordinate asynchronous execution service, not as the authority for the Daily Brief’s publication state. The publication system’s own durable supervisor—implemented in its database and advanced through compare-and-swap transitions—must remain the sole authority for process identity, revision, stage, accepted evidence, composition eligibility, and publication readiness.

The supplied project brief correctly reframes the problem from basic API connectivity to distributed-workflow correctness: the essential challenge is whether the site can create, persist, retrieve, validate, reconcile, consume, retry, and clean up provider operations without duplicate jobs, lost results, stale-worker commits, or indefinite stalls.

The recommended architecture has the following defining properties:

RequirementRecommended rule
State authorityThe local supervisor owns the Daily Brief state. Provider statuses are observations about one subordinate operation.
Active-operation limitAt most one locally authorized provider operation may exist for the current process revision and stage.
Creation safetyCommit an immutable request contract and pending-create outbox record before issuing the provider POST.
Duplicate preventionUse a stable local fingerprint, a database uniqueness constraint, an operation generation, and a fencing token.
Ambiguous POST handlingA create timeout after transmission becomes CREATE_ACCEPTANCE_UNKNOWN; do not automatically issue a replacement POST.
PollingPoll only when a durable next_poll_at has arrived and a worker owns a valid lease. Browser requests remain read-only.
CompletionA provider completed status is not success. Output, schema, evidence, citations, editorial constraints, and stage invariants must all pass locally.
CommitAccept a stage result through one compare-and-swap database transaction, exactly once.
RetryRetry only after classifying whether the prior operation definitely failed, may still exist, or reached a provider terminal state.
EvidenceCopy required source and citation evidence into local durable storage before provider deletion.
Degraded modeKeep the last verified edition visibly labeled as the last verified edition; expose a delayed-publication state and never fabricate a replacement.
OperationsUse bounded, auditable commands such as “reconcile current operation,” “request cancellation,” and “authorize replacement generation,” never generic “run again.”

The core invariant should be expressed directly in code, database constraints, tests, and operator procedures:

No provider response may publish, advance, overwrite, or invalidate a Daily Brief unless it is attached to the current process ID, expected revision, current stage, live operation generation, and valid fencing token, and its result passes the stage’s local acceptance contract.

Scope and key questions

This report assumes no access to the site’s source code, private prompts, credentials, provider response bodies, account identifiers, or hosting environment. It therefore specifies an implementation-neutral PHP production design based on documented OpenAI behavior and conservative distributed-systems assumptions.

The key questions are:

  1. What does the current OpenAI platform officially guarantee for background Responses, retrieval, statuses, web-search evidence, structured outputs, request correlation, cancellation, deletion, webhooks, and retries?
  2. Which workflow properties must InternationalIntelligence.org implement locally because the provider does not document them?
  3. How should the system handle an API POST that may have succeeded even though the client did not receive the response identifier?
  4. How can research, supplemental research, and composition be made independently retryable without losing accepted work?
  5. What validation, cost, privacy, and operational controls are required before the workflow can be trusted for unattended publication?

The recommended delivery priority is:

  1. Build the local supervisor, immutable contracts, operation reservations, and compare-and-swap transitions.
  2. Make ambiguous creation a first-class state.
  3. Add deterministic provider fixtures and crash-point testing.
  4. Implement evidence-preserving research and composition contracts.
  5. Add polling, webhooks, cancellation, and deletion only after the authority model is correct.
  6. Run isolated live probes before connecting the orchestrator to publication state.

Official OpenAI Capability Baseline and Recent Developments

Current capability summary

The following findings were checked against current official OpenAI documentation on August 1, 2026. “Documented” means the behavior appears in the official API reference or platform guide. “Engineering consequence” is this report’s recommendation and is not an OpenAI guarantee.

CapabilityOfficially documented finding, verified August 1, 2026Engineering consequence
Responses APIThe Responses API creates response objects whose output can contain messages, tool calls, reasoning items, and other item types. Response objects are retrievable by ID.Do not assume output[0] is the final message. Iterate and type-check every output item.
Background modeSetting background: true starts asynchronous execution. The client retrieves the response object and polls while its status is queued or in_progress; leaving those states is terminal for the provider operation.Persist the returned provider ID before scheduling any poll. Provider terminality is distinct from local acceptance.
Response statusesThe documented response-status enum is queued, in_progress, completed, incomplete, failed, and cancelled.Map all six statuses explicitly. Unknown future statuses must fail closed into quarantine, not be treated as success.
RetrievalA response can be retrieved with GET /v1/responses/{response_id}. Official background examples poll the response by ID.A provider ID is a critical durable identifier, but not an authority token.
CancellationThe platform documents POST /v1/responses/{response_id}/cancel for cancelling a background response.Cancellation is a request that can race with completion. Always retrieve again before deciding the local outcome.
DeletionThe API documents DELETE /v1/responses/{response_id} and returns a deletion result.Delete only after evidence, output, usage, and incident-correlation data required by local policy have been preserved.
Web searchWeb-search output can contain a web_search_call item and a message whose text includes URL-citation annotations. The action can describe search, page opening, or text finding.Research acceptance must require both usable message data and independently inspectable tool/source evidence.
Full source listThe web-search guide documents a sources collection and the include: ["web_search_call.action.sources"] option, which can expose consulted sources beyond inline citations.Store source evidence separately from the generated candidate JSON. Inline citations alone are insufficient for auditability.
Citation presentationOpenAI’s web-search guide says citations presented to end users should be visible and clickable.Preserve citation annotations and URL/title relationships through research, composition, rendering, and localization.
Structured OutputsThe Responses API supports JSON Schema through text.format, with type: "json_schema" and strict: true; supported strict schemas use a subset of JSON Schema.Use strict provider schemas, then run a separate local schema validator. Do not equate schema conformity with editorial correctness.
Incomplete outputOfficial examples check for response.status === "incomplete" and inspect incomplete_details, including output-token exhaustion.Treat truncation as a provider terminal result requiring controlled replacement, not as parseable partial success.
Refusals and absent messagesOfficial Structured Outputs examples inspect message items, distinguish refusals, and handle missing parsed output rather than assuming a completed response contains usable JSON.“Completed” means execution ended, not that the publication contract was satisfied.
Tool-choice controlsThe current Responses reference documents required tool selection and allowed-tool controls. It also documents a max_tool_calls limit applying across built-in tool calls.Primary research can require web search and cap built-in calls. Composition should omit tools or explicitly disallow them.
Request identifiersOpenAI returns an x-request-id for API requests and recommends logging it. Clients may send an X-Client-Request-Id, an ASCII value up to 512 characters, for correlation; OpenAI documents it as useful when a timeout prevents receipt of the server request ID.Use both IDs for diagnostics. Neither should be treated as a documented create-idempotency key.
MetadataResponses support bounded string metadata fields attached to an object.Include only non-sensitive correlation tags. Do not depend on metadata to recover an unknown response ID.
Response listing/searchThe current Responses endpoint index documents create, retrieve, delete, input-item listing, input-token counting, cancellation, and compaction, but no general response-list or response-search endpoint. This is an inference from the documented endpoint surface, not a promise that no internal capability exists.Never design ambiguous-POST recovery around “find the response by fingerprint” unless OpenAI later documents such an endpoint.
Create idempotencyThe current official materials consulted document request correlation but do not document an idempotency guarantee for POST /v1/responses.Treat create as a potentially non-idempotent external side effect. A repeated POST may create duplicate billable work.
WebhooksOpenAI documents response-completion webhooks, signature verification, and retrieval of the response by the ID in the event.A webhook is a notification, not a stage commit. Persist it, deduplicate it, and run the same fenced reconciliation path used by polling.
Webhook retries and duplicatesFailed webhook delivery can be retried for up to 72 hours with exponential backoff, and duplicate events can occur; the webhook ID can be used for deduplication.Webhook processing must be at-least-once safe and tolerate old events arriving after a process revision has advanced.
Error classesOfficial documentation identifies authentication, authorization/region, rate-limit or quota, server, and overload classes, including HTTP 401, 403, 429, 500, and 503.Map protocol errors to durable workflow decisions; never collapse them into one generic “API failed” state.
Rate-limit retryOpenAI recommends honoring Retry-After where present, otherwise using exponential backoff with jitter and bounded attempts; failed requests can count against rate limits.Persist the provider’s retry eligibility, use one retry controller, and open a circuit breaker during storms.
Storage and retentionThe current data-control documentation states that Responses have a default application-state retention period and that background processing requires temporary storage for polling; exact compatibility with an organization’s retention configuration must be checked against its current data-control settings.InternationalIntelligence.org must not use provider retention as its evidence archive. Copy required evidence locally before cleanup.
Forward compatibilityOpenAI states that backward-compatible API changes can add fields and that opaque identifier formats may change.Reject unknown fields inside the publication payload schema, but tolerate unknown top-level provider fields in the transport decoder. Never parse meaning from ID prefixes.

Recent capability timeline

timeline
    title OpenAI capabilities relevant to the Daily Brief workflow
    2024-08-06 : Structured Outputs announced
               : Exact schema adherence introduced for supported strict schemas
    2025-03-11 : Responses API introduced
               : Built-in web search introduced with the new API
    2025-05-21 : Background mode added to Responses
               : Longer-running asynchronous work became directly retrievable
    2026-08-01 : Current documentation baseline verified
               : Retrieve, cancel, delete, webhooks, citations, request IDs, and current status handling reviewed

OpenAI announced Structured Outputs on August 6, 2024, while explicitly noting that schema correctness does not eliminate mistakes within field values. The Responses API and built-in web search were announced on March 11, 2025, and background mode was announced among additional Responses capabilities on May 21, 2025.

Actors and trust boundaries

ActorLegitimate authorityMust not be allowed to do
Daily Brief supervisorOwn process ID, revision, target date, stage, accepted artifacts, publication eligibility, and terminal outcomeDelegate publication authority to a provider status
Scheduler or cronFind eligible local work and attempt to acquire a leaseUnconditionally create or poll on every invocation
Provider-operation workerExecute one fenced external action for one reserved operationCommit after its lease or process revision becomes stale
OpenAI Responses APIExecute the submitted response operation and report provider status/outputAdvance the publication workflow directly
Web-search toolReturn search actions, source evidence, and citationsDefine which events are editorially acceptable
Webhook receiverAuthenticate, deduplicate, and durably record notificationsPerform publication in the HTTP request thread
Database/outboxPreserve authoritative transitions, uniqueness, leases, and audit recordsContain credentials, full prompts, or unrestricted raw provider bodies in ordinary logs
OperatorApprove bounded recovery actions under auditTrigger an unconstrained “run everything again” action
Public browserRead bounded status and published contentCreate, poll, cancel, reconcile, or delete provider work
Publisher/rendering layerPublish only a locally committed and approved editionRead provider output directly as publishable content

Documented guarantees versus local obligations

The provider documents mechanisms for creating, retrieving, cancelling, deleting, and receiving completion notifications for responses. It does not thereby guarantee exactly-once job creation, exactly-once webhook delivery, exactly-once local consumption, recovery of an unknown response ID after an ambiguous POST, editorial usefulness, evidence sufficiency, bilingual parity, or preservation of accepted research across retries. Those are application-level obligations.

The appropriate methodology is therefore a combination of:

  • immutable command contracts;
  • a transactional outbox;
  • database-enforced uniqueness;
  • leases with fencing tokens;
  • compare-and-swap revision transitions;
  • explicit ambiguous-outcome states;
  • idempotent result consumption;
  • source-evidence validation;
  • reconciliation instead of blind replay;
  • deterministic fault injection;
  • bounded operator actions.

Authority Model and Durable Provider Lifecycle

Supervisor state model

A Daily Brief process should have one durable supervisor row, for example:

daily_brief_process
  process_id
  target_date
  locale_set
  revision
  stage
  stage_status
  active_operation_id
  accepted_research_revision
  accepted_evidence_digest
  composition_revision
  publication_status
  health_code
  last_meaningful_progress_at
  next_action_code
  created_at
  updated_at

Recommended process stages are:

RESEARCH_PRIMARY
RESEARCH_ASSESS
RESEARCH_SUPPLEMENTAL
RESEARCH_ACCEPTED
COMPOSITION
COMPOSITION_VALIDATE
READY_FOR_EDITORIAL
READY_TO_PUBLISH
PUBLISHED
DELAYED
QUARANTINED
ABANDONED

DELAYED and QUARANTINED should be overlays or explicit states with a preserved resumable stage. They must not erase accepted research.

A provider operation belongs to one stage attempt:

provider_operation
  operation_id
  process_id
  expected_process_revision
  stage_code
  operation_generation
  request_fingerprint
  contract_version
  request_payload_digest
  provider_response_id_encrypted_or_restricted
  provider_state
  local_state
  create_attempt_count
  poll_attempt_count
  validation_attempt_count
  worker_fence
  lease_owner
  lease_expires_at
  create_started_at
  provider_accepted_at
  last_polled_at
  next_poll_at
  terminal_observed_at
  result_digest
  result_commit_key
  cancel_requested_at
  delete_requested_at
  quarantine_reason
  cost_ceiling
  token_ceiling

The process row answers, “What is the publication doing?” The operation row answers, “What happened to this one external execution?” A provider operation must never answer the first question by itself.

Core invariants

The database should enforce these invariants wherever its engine permits:

InvariantEnforcement
One active operation for the current stagePartial unique index on active operations by process_id, expected_process_revision, and stage_code; otherwise a reservation table with a unique key
No duplicate logical requestUnique key on process_id, revision, stage, contract version, fingerprint, and operation generation
Monotonic process revisionEvery stage transition uses UPDATE ... WHERE process_id=? AND revision=? AND stage=?
Stale worker cannot commitEvery operation mutation checks the current fencing token and expected process revision
One local result commitUnique result_commit_key plus an atomic artifact-insert/process-advance transaction
Provider ID cannot silently moveProvider ID is immutable after first durable attachment; a conflicting ID quarantines the operation
Publication requires validated artifactsDatabase-level publication precondition or service-layer transaction checks evidence and composition acceptance records
Cleanup cannot precede preservationDeletion eligibility depends on a durable evidence_preserved_at and terminal commit or abandonment record

Request fingerprint and reservation design

A request fingerprint must identify the semantic and operational contract, not incidental JSON formatting. Compute it from a canonical serialization of:

process_id
target_date
expected_process_revision
stage_code
contract_version
model_policy_version
prompt_template_version or prompt digest
schema_version
canonical evidence-input digest
tool configuration
allowed domains, if any
maximum tool calls
input-token ceiling
maximum output tokens
language requirements
editorial policy version
cost ceiling

Use a construction such as:

request_fingerprint =
    SHA-256(
        "daily-brief-response-v1" ||
        canonical_json(immutable_contract)
    )

The canonicalizer must define UTF-8 normalization, object-key ordering, numeric formatting, array ordering, null treatment, and line-ending normalization. Do not include worker ID, start time, attempt number, transport timeout, or provider request ID in the fingerprint; those describe execution, not the requested result.

operation_generation distinguishes an explicitly authorized replacement from the same logical request. Generation zero is the first creation. Generation one is permitted only after generation zero is conclusively terminal, safely abandoned under policy, or overridden by an audited operator action. The fingerprint stays stable; the generation changes.

Before the network call, durably record:

FieldPurpose
Process ID and suffixAssociate external work with one Daily Brief
StagePrevent a research response from being consumed as composition
Expected revisionReject workers and results from superseded process state
Request fingerprintDeduplicate the logical contract
Contract versionMake validation reproducible
Operation generationDistinguish an authorized replacement
Attempt numberBound transport attempts
Creation start timeDetect stuck or ambiguous creates
Worker identity and fenceReject stale completion
Client request IDCorrelate with OpenAI support and local logs
Cost ceilingPrevent retries from exceeding the process budget
Payload digestDetect mutation between reservation and POST
Redacted request summarySupport operations without retaining the prompt

The X-Client-Request-Id should be derived from a random operation identifier plus generation, not from private text. OpenAI documents it as a correlation aid, including for timeouts, but not as a create-idempotency mechanism.

Suggested bounded provider metadata, where supported by the current request schema, is:

{
  "workflow": "daily_brief",
  "process_suffix": "7F3A91",
  "stage": "research_primary",
  "revision": "12",
  "operation_generation": "0",
  "fingerprint_prefix": "b42a1e5d",
  "contract_version": "research-2026-08"
}

Do not place target article text, private prompts, full process IDs, account identifiers, sensitive URLs, or personal information in metadata. Although metadata may aid interpretation of a response that is later discovered, the current documented Responses endpoint surface does not provide a general lookup-by-metadata operation, so it cannot be the primary ambiguous-creation recovery mechanism.

Complete provider lifecycle

The table below defines the required treatment of every lifecycle step. Codes are illustrative bounded enums.

Lifecycle stepLocal preconditionsExternal callPrincipal ambiguityRequired durable write and idempotencyStale-worker check and recoveryPublic representationPrivate diagnostic
Build immutable stage contractCurrent process/revision/stage; accepted inputs frozenNoneInput may change while being assembledStore canonical contract, schema version, evidence digest, token/tool/cost ceilings; immutable after reservationRe-read process revision before reservation; discard draft if changedPREPARINGCONTRACT_BUILT, digests, versions
Compute fingerprintCanonical contract completeNoneDifferent serialization could create false differencesStore SHA-256 fingerprint and canonicalizer versionRecompute and compare before dispatch; quarantine on mismatchPREPARINGFINGERPRINT_COMPUTED
Reserve operationNo live operation for current revision/stageNoneAt-least-once scheduler may raceTransactionally insert operation and attach it to process; unique active-operation constraintCompare process ID, revision, stage, and active slotRESERVEDOP_RESERVED, fence
Persist pending createReservation valid and budget availableNoneCrash before or after network callInsert outbox/pending-create row in same transaction as reservationOutbox consumer checks fence and revisionCREATE_PENDINGOUTBOX_READY
Create provider responseValid lease; pending create; no provider ID; create eligibility reachedPOST /v1/responses with background modeProvider may accept while response to client is lostBefore call write CREATE_STARTED, client request ID, timestamps, attempt; after clear success write provider ID and observed status atomicallyRe-check fence after call before attachment; stale result is quarantined, not attached to current processSUBMITTINGHTTP class, x-request-id, timing, redacted cURL result
Persist accepted stateResponse ID returned and reservation still currentNoneCrash after response received but before commitStore provider ID once, accepted time, provider status, next poll time; immutable IDIf current process changed, store as orphan/quarantined operationQUEUED or PROCESSINGPROVIDER_ID_ATTACHED
Poll when eligibleProvider ID; state queued/in-progress; due time; valid lease; not quarantinedGET /v1/responses/{id}Timeout leaves status unknown but does not create a new jobStore poll start, result, next eligibility, request ID; poll key by operation and sequenceCheck fence before call and before applying result; stale poll may update restricted operation history but not process stateQUEUED, PROCESSING, or DELAYEDPOLL_OK, POLL_TIMEOUT, provider status
Interpret statusRetrieved object belongs to expected IDNoneNew or unknown status may appear in futureMap all known statuses; unknown values become quarantined transport recordsVerify operation remains active for current process before scheduling next actionBounded provider-state codeSTATUS_UNKNOWN with redacted snapshot digest
Retrieve output and sourcesTerminal provider state or completion webhookUsually same retrieval GET; optionally input-item/source retrieval documented for relevant tool outputCompleted object may lack usable message, sources, or citation annotationsPreserve normalized provider envelope digest, output items, usage, source evidence, and citation graph in restricted storageOld operation can preserve evidence but cannot feed current stage without operator-approved reconciliationVALIDATINGCounts and digests, not raw public logs
Validate strict local contractEvidence copied; correct contract/schema availableNoneStrict provider schema may still contain unusable facts or unsupported claimsWrite immutable validation report with every rule outcomeValidation keyed to operation ID, fingerprint, contract version, and result digestVALIDATING, EVIDENCE_DEFICIT, or OUTPUT_REJECTEDRule-level failure codes
Commit result exactly onceValidation accepted; operation current; process revision/stage unchangedNoneDuplicate worker or crash during commitSingle transaction inserts accepted artifact, marks operation consumed, advances process revision, and writes event; unique commit keyCompare-and-swap process revision and worker fenceNext stage codeRESULT_COMMITTED
Preserve evidence before cleanupProvider output accepted or incident retention requiredNoneProvider object may later expire or be deletedCopy source URLs/titles/dates, citation mappings, hashes, candidate records, validation report, and minimum diagnostic identifiersEvidence records are versioned and immutableEvidence counts onlyEVIDENCE_PRESERVED
Cancel or deleteCancellation/deletion policy satisfied; no concurrent commitCancel POST or delete requestCancellation may race with completion; deletion may erase unretrieved evidenceRecord intent before call and result after; use one cancellation/deletion command per operation generationRetrieve/reconcile after cancel; deletion blocked without evidence-preservation flagCANCELLING, CANCELLED, or unchanged published stateCANCEL_REQUESTED, DELETE_CONFIRMED
Record bounded audit eventEvery meaningful transitionNoneLogs can leak secrets or become unboundedAppend structured event with enums, IDs or suffixes, hashes, timestamps, actor, and transition resultEvents reference process revision and operation fenceSelected bounded fieldsFull authorized correlation fields, redacted by policy

Normal completion sequence

sequenceDiagram
    participant C as Cron/Scheduler
    participant S as Local Supervisor
    participant D as Database/Outbox
    participant W as Fenced Worker
    participant O as OpenAI Responses
    participant V as Local Validator

    C->>S: Find eligible process
    S->>D: Reserve operation under revision R
    D-->>S: Operation O, fence F
    S->>D: Persist immutable contract and pending-create
    W->>D: Acquire lease for O/F
    W->>O: POST background response
    O-->>W: response_id + queued/in_progress
    W->>D: Attach response_id, set next_poll_at
    loop Only when eligible
        W->>D: Acquire poll lease and verify R/F
        W->>O: GET response_id
        O-->>W: queued/in_progress/completed
        W->>D: Persist observation and next eligibility
    end
    W->>O: GET final response if needed
    O-->>W: output + tool/source evidence
    W->>D: Preserve output and evidence
    W->>V: Validate schema, claims, citations, stage rules
    V-->>W: Accepted
    W->>D: CAS commit under R/F and advance revision
    D-->>W: Exactly-once commit succeeded

Stale-worker rejection

sequenceDiagram
    participant W1 as Old Worker
    participant W2 as New Worker
    participant D as Database
    participant O as OpenAI
    participant S as Supervisor

    W1->>D: Acquire lease with fence 41
    W1->>O: GET response
    Note over W1,O: W1 is delayed
    S->>D: Advance or replace operation
    D-->>S: New fence 42
    W2->>D: Acquire current lease, fence 42
    W1->>D: Attempt to persist or commit with fence 41
    D-->>W1: Rejected as stale
    W1->>D: Record bounded stale-worker event
    W2->>D: Continue current reconciliation

Crash after provider completion

sequenceDiagram
    participant W1 as Worker Before Crash
    participant O as OpenAI
    participant D as Database
    participant W2 as Recovery Worker
    participant V as Validator

    W1->>O: GET response
    O-->>W1: completed + output
    W1->>D: Persist terminal observation and raw-artifact digest
    Note over W1: Process crashes before stage commit
    W2->>D: Acquire new fenced lease
    W2->>D: Read completed, unconsumed operation
    W2->>O: Retrieve again only if required artifacts absent
    W2->>D: Preserve missing evidence
    W2->>V: Run deterministic validation
    V-->>W2: Accepted
    W2->>D: CAS exactly-once result commit

Ambiguity, Polling, Retry, and Reconciliation

Ambiguous create-POST analysis

The most dangerous failure is:

  1. the local worker sends POST /v1/responses;
  2. OpenAI accepts and creates background work;
  3. the client times out or loses the connection before receiving the response ID.

The local system cannot safely conclude either that the operation exists or that it does not exist. Because the current documented Responses API does not expose a general response-list or search-by-metadata endpoint, and because the official request-ID mechanism is documented for correlation rather than create idempotency, the application must not invent an automatic lookup or blindly repeat the POST.

What can be recovered

MechanismWhat it can doWhat it cannot safely do
x-request-idCorrelate a response when the server header was receivedHelp when the header itself was lost
X-Client-Request-IdCorrelate local logs with OpenAI support when a timeout prevented receipt of the server request IDProve that no provider response was created; prevent duplicate creation
Stable fingerprintDetect an attempted duplicate inside the local systemLocate an unknown response through an undocumented provider query
Provider metadataHelp identify a response after its ID becomes knownReliably find an unknown response without a documented list/search endpoint
Outbox recordProve that the local system intended and began one creationProve whether the remote server accepted it
WebhookPotentially reveal a completed response ID later, after signature verification and deduplicationGuarantee arrival, immediate delivery, or simple correlation to the unknown operation
LogsEstablish timing, bytes sent, transport phase, request IDs, and worker identityConvert an ambiguous network result into proof of non-creation
Operator reconciliationEscalate with the client request ID; wait for a webhook; inspect permitted account tooling; authorize a replacementEliminate the possibility of an orphan if the provider offers no discoverable record
CancellationStop work once the response ID is knownCancel an unidentified response
Safe abandonmentPrevent the uncertain operation from influencing current publication statePrevent unidentified provider work from incurring already-started cost

Required policy

A create attempt should enter one of three outcome classes:

Outcome classExamplesReplacement POST policy
Definitely not dispatchedLocal contract failure, budget rejection, database failure before network call; reliably detected DNS/connect failure before request bytes could be sentMay retry the same generation under the existing reservation
Provider response identifiedSuccessful create response includes a provider response IDPoll/reconcile that ID; never create a second live operation for the stage
Acceptance unknownTimeout after connection, broken connection after possible body transmission, malformed or truncated success response, process crash during POST, or uncertain 5xx pathDo not automatically create a replacement; enter CREATE_ACCEPTANCE_UNKNOWN

For CREATE_ACCEPTANCE_UNKNOWN:

  1. Freeze the active-operation slot.
  2. Record the transport phase, elapsed time, cURL error class, client request ID, payload digest, worker fence, and create-start timestamp.
  3. Wait through a configurable reconciliation window.
  4. Accept a valid signed webhook that identifies a response and can be safely correlated.
  5. Permit an operator to request reconciliation, which schedules a fenced local action but does not create work.
  6. Escalate to OpenAI support with X-Client-Request-Id when warranted.
  7. After the maximum ambiguity age, move to SAFE_ABANDONED_UNKNOWN or retain quarantine.
  8. Create generation n+1 only through a separate policy decision that acknowledges possible duplicate cost and prevents generation n from ever committing to the current process.
  9. If the old response later appears, preserve the diagnostic event and quarantine or delete it after safe evidence handling; never let it become a second authority.

This policy trades some availability for protection against duplicate cost and conflicting results. That is appropriate for an unattended publication workflow whose source material must remain auditable.

Ambiguous POST sequence

sequenceDiagram
    participant W as Worker
    participant D as Local Database
    participant O as OpenAI
    participant H as Webhook Receiver
    participant R as Reconciler
    participant P as Operator

    W->>D: Persist pending-create, fingerprint, client request ID
    W->>O: POST background response
    O--xW: Connection lost after possible acceptance
    W->>D: Mark CREATE_ACCEPTANCE_UNKNOWN
    D-->>W: Block replacement creation
    alt Signed webhook later arrives
        O-->>H: response.completed with response ID
        H->>D: Deduplicate and store event
        R->>D: Acquire fenced reconciliation lease
        R->>O: GET response ID
        O-->>R: Response object
        R->>D: Correlate or quarantine
    else No response ID becomes discoverable
        P->>D: Request bounded reconciliation
        R->>D: Inspect logs, age, client request ID
        R-->>P: Still ambiguous
        P->>D: Authorize safe abandonment/replacement generation
        D->>D: Fence old generation; reserve generation n+1
    end

Polling policy

OpenAI’s guide demonstrates polling while a response is queued or in_progress. The guide’s example cadence is illustrative; production cadence, ownership, jitter, age limits, and duplicate prevention remain application responsibilities.

Recommended policy:

ParameterResearch operationComposition operationRationale
Initial delay after accepted create5 seconds3 secondsAvoid immediate duplicate GET after create
Minimum cadence5 seconds5 secondsPrevent tight loops
Backoff sequence without progress5, 10, 20, 40, 60 seconds5, 10, 20, 40, 60 secondsBounded load
Maximum cadence60 seconds60 secondsPreserve eventual observation without excessive delay
JitterRandom ±20%, persisted in next_poll_atSameDesynchronize multiple processes
State-change behaviorReset next delay to 10 seconds after meaningful state changeSameObserve active progress more closely
Default maximum response age30 minutes20 minutesEngineering default; tune from measured production latency
Polls per worker cycleExactly oneExactly onePrevent loops monopolizing PHP worker time
Poll lease30 seconds, renewable only before network callSameBound ownership
No-progress warning10 minutes7 minutesExpose delay before hard age limit
Hard terminal policyRequest cancellation, then quarantine/reconcileSameDo not create a replacement while the old operation may still run

A response is poll-eligible only when all of the following are true:

provider_response_id is present
provider_state is queued or in_progress
local_state is not quarantined, consumed, deleted, or terminally abandoned
now >= next_poll_at
process_id and expected_revision still match the active supervisor
operation_id is still the supervisor's active operation
cost and age limits have not been exceeded
no valid poll lease is held
no cancellation transition is currently being reconciled

The worker must:

  1. atomically acquire a lease and increment the fencing token;
  2. re-read process revision and active operation;
  3. write a POLL_STARTED event;
  4. perform at most one provider GET;
  5. write the observation and a durable next eligibility time;
  6. release or let the lease expire;
  7. never call the provider again in the same cycle merely because the response remains queued.

A browser request must only read a materialized public-status projection. It must not create an outbox command, acquire a workflow lease, issue a provider GET, or invoke reconciliation.

An operator’s “reconcile” action should only create a unique local command such as:

RECONCILE_OPERATION(process_id, revision, operation_id, requested_reason)

The scheduler consumes that command under the ordinary lease and fencing rules. Repeated clicks deduplicate against the command’s unique active key.

Cancellation/completion race

The cancellation endpoint is documented, but asynchronous cancellation can race with ordinary completion. The local system should not decide the stage result solely from the HTTP result of the cancellation call.

sequenceDiagram
    participant P as Operator/Policy
    participant D as Database
    participant W as Worker
    participant O as OpenAI
    participant V as Validator

    P->>D: Persist CANCEL_REQUESTED
    W->>D: Acquire cancellation lease and verify fence
    W->>O: POST cancel response_id
    par Provider may complete
        O->>O: Finish response
    and Cancellation may apply
        O->>O: Process cancellation
    end
    O-->>W: Cancellation-call result
    W->>O: GET response_id for authoritative observed state
    O-->>W: completed or cancelled/other terminal status
    alt completed and operation still locally eligible
        W->>D: Preserve result and evidence
        W->>V: Validate
        V-->>W: Accepted or rejected
        W->>D: CAS commit only if process still allows it
    else cancelled or locally superseded
        W->>D: Record terminal cancellation/quarantine
    end

Retry and reconciliation matrix

The values below are recommended production defaults, not provider guarantees. “Attempt” means a bounded attempt of that specific action, not a new provider response unless explicitly stated.

ConditionClassification and actionAttempts, backoff, next eligibilityMay create a new response? Duplicate preventionPublic / private codeTerminal condition and required event
DNS failureTransport failure before connection; retry create or retrieval if client confirms no request transmission3 attempts: 5s, 20s, 60s with ±20% jitterSame reserved generation only; no new reservationPROVIDER_UNREACHABLE / NET_DNSTerminal for current cycle after 3; NETWORK_RETRY_EXHAUSTED
TLS failureConfiguration/security failure; stop and alert1 automatic attempt; next eligibility operator-controlledNoPROVIDER_SECURITY_ERROR / NET_TLS_VERIFYQuarantine until certificate/CA issue corrected; TLS_FAILURE
Connection failureRetry only when transport layer establishes request bytes were not sent3 attempts: 5s, 20s, 60sSame reservation; otherwise classify as ambiguousPROVIDER_UNREACHABLE / NET_CONNECTExhaustion produces delayed state and CONNECT_RETRY_EXHAUSTED
Client timeout before headersPotentially ambiguous create; retrieval GET can safely be repeatedCreate: one attempt enters ambiguity. GET: up to 5 retriesCreate replacement prohibited; GET allowed for known IDSUBMISSION_UNCERTAIN / POST_TIMEOUT_PRE_HEADERSCreate enters CREATE_ACCEPTANCE_UNKNOWN; event records transport phase
Client timeout after possible provider acceptanceAmbiguous external side effect; reconcile/quarantineNo automatic create retry; reconciliation at 1, 5, 15 minutes, then hourly until age limitOnly audited new generation after safe-abandonment decisionSUBMISSION_UNCERTAIN / POST_ACCEPTANCE_UNKNOWNSAFE_ABANDONED_UNKNOWN or attached discovered response; event required
HTTP 400Contract/configuration error; stop automatic retries1Only after contract/configuration changes and new revision or contract versionREQUEST_INVALID / provider code plus schema/payload digestTerminal operation; CREATE_REJECTED_400
Authentication failureCredentials/configuration incident1, then circuit openNoPROVIDER_AUTH_ERROR / HTTP_401_AUTHTerminal until credentials repaired; AUTH_FAILURE
Authorization failureAccess, region, project, or policy incident1, then operator actionNoPROVIDER_ACCESS_ERROR / HTTP_403_AUTHZTerminal until entitlement/configuration changes; AUTHZ_FAILURE
Model access failureConfiguration/model-policy failure1No silent model fallback; new operation only after approved model-policy revisionMODEL_UNAVAILABLE / MODEL_ACCESS_DENIEDQuarantine; MODEL_POLICY_FAILURE
Tool access failureResearch contract cannot be satisfied1No tool-free research fallback; retry after entitlement/tool policy correctedRESEARCH_TOOL_UNAVAILABLE / WEB_SEARCH_ACCESS_DENIEDResearch stage blocked; TOOL_ACCESS_FAILURE
Rate limitRetryable capacity condition unless documentation/error says quota or billing action requiredHonor Retry-After; otherwise 10s, 30s, 90s, 5m; maximum 4 per action and 15m totalSame known GET/cancel action; create retry only if prior rejection is unambiguousPROVIDER_THROTTLED / HTTP_429_RATEOpen circuit after budget; RATE_LIMIT_EXHAUSTED
Quota, billing, or spend limitNon-transient account condition1NoPROVIDER_BUDGET_BLOCKED / HTTP_429_QUOTAOperator/account action required; QUOTA_BLOCK
Provider 5xx with complete error responseProvider fault; for GET retry; for POST conservatively assess ambiguityGET: 5s, 20s, 60s, 3m, 10m. POST: at most one replay only if transmission and non-creation are established; otherwise ambiguityNew response normally prohibited until reconciledPROVIDER_ERROR / HTTP_5XXCircuit opens after bounded window; PROVIDER_5XX_EXHAUSTED
Background response queuedNormal nonterminal stateNext poll in persisted 5–10s, then backoffNoQUEUED / RESP_QUEUEDAge limit or provider transition; PROVIDER_STATE_OBSERVED
Background response processingNormal nonterminal stateNext poll in 10–60s according to scheduleNoPROCESSING / RESP_IN_PROGRESSAge limit or provider transition; event only on meaningful change
Response older than allowed ageStalled/over-ageRequest cancellation once; reconcile after 5s, 30s, 2mNot until old generation terminal or safely abandonedPROVIDER_STALLED / MAX_RESPONSE_AGEQuarantine after cancel/reconciliation budget; AGE_LIMIT_EXCEEDED
Completed with missing outputProvider terminal, local validation failureRetrieve once more after 5s only to rule out transient retrieval inconsistency; then rejectReplacement generation allowed if attempt budget remainsOUTPUT_UNUSABLE / COMPLETED_NO_MESSAGERejected operation; VALIDATION_MISSING_OUTPUT
Completed with invalid structured outputLocal contract failureNo reparse loop; one deterministic parse and schema reportNew generation allowed within stage-attempt budgetOUTPUT_INVALID / SCHEMA_VALIDATION_FAILEDReject and preserve validation report
Research with too few usable sourcesEditorial/evidence deficitCreate supplemental research, not full primary replay; maximum 2 supplemental roundsYes, as a new supplemental-stage operation with deficit-specific fingerprintEVIDENCE_DEFICIT / SOURCE_COUNT_OR_QUALITY_DEFICITOperator review after supplemental budget; RESEARCH_DEFICIT_RECORDED
Composition with unsupported claimsSemantic validation failureNo publication; retry composition with explicit validation feedback, maximum 2 replacementsYes, composition-only; accepted research remains immutableCOMPOSITION_REJECTED / UNSUPPORTED_CLAIMQuarantine after attempt budget; validation event with claim IDs
Cancellation racing with completionReconciliation raceCancel once; immediately retrieve, then at 5s and 30s if still nonterminalNoCANCELLING / CANCEL_COMPLETION_RACEAccept valid completion only if still locally eligible; otherwise quarantine
Local crash after provider completionRecoverable local interruptionNew worker resumes from durable terminal observation; retrieve only if evidence absentNoRECOVERING / CRASH_AFTER_TERMINAL_OBSERVATIONExactly-once commit or deterministic rejection; RECOVERY_RESUMED
Provider ID attached to old process revisionStale resultPreserve restricted record; do not consumeNo for old revision; current revision follows its own reservationSTALE_RESULT_IGNORED / PROVIDER_ID_REVISION_MISMATCHQuarantined orphan; STALE_PROVIDER_RESULT
Provider completes after operator quarantineLate terminal resultRetrieve only if incident/evidence policy requires; never auto-unquarantineNo automatic replacement interactionQUARANTINED / LATE_COMPLETION_AFTER_QUARANTINEOperator may inspect; event records no-commit decision
Provider response deleted before evidence extractionIrrecoverable evidence lossStop; do not infer output from logsNew research generation only under explicit recovery policyEVIDENCE_LOST / DELETED_BEFORE_PRESERVETerminal incident; PREMATURE_DELETE
Repeated polls with no meaningful state changeStalled but not yet terminalIncrease to 60s maximum cadence; emit one warning, not one per pollNoPROCESSING_DELAYED / NO_PROGRESS_WINDOWAge limit triggers cancellation/quarantine; summarized event
Provider status failedProvider terminal failureClassify error; no more pollingReplacement allowed if failure is retryable and process budget permitsPROVIDER_FAILED / RESP_FAILED_<CODE>Terminal operation; PROVIDER_TERMINAL_FAILURE
Provider status incompleteProvider terminal incomplete resultInspect incomplete_details; reject partial publication payloadReplacement allowed with adjusted bounded output/input contractOUTPUT_INCOMPLETE / RESP_INCOMPLETE_<REASON>Terminal operation; preserve reason and validation event
Provider status cancelledProvider terminal cancellationStop polling; reconcile local cancellation intentReplacement only if current process still needs the stageCANCELLED / RESP_CANCELLEDTerminal operation; PROVIDER_CANCELLED
Unknown provider statusForward-compatibility conditionNo retry loop based on guesses; quarantine and alertNo until code supports the statusPROVIDER_STATE_UNKNOWN / raw enum hash or bounded valueOperator/software update required; UNKNOWN_PROVIDER_STATUS
Duplicate webhookExpected at-least-once notificationAcknowledge after dedupe; no repeated retrieval if already reconciledNoNo public change / WEBHOOK_DUPLICATEDedupe event by webhook ID
Webhook older than current revisionStale notificationAuthenticate, store minimal event, reject workflow effectNoNo public change / WEBHOOK_STALE_REVISIONSTALE_WEBHOOK_IGNORED

OpenAI recommends honoring Retry-After, otherwise using bounded exponential backoff with jitter, and warns that failed requests can consume rate-limit capacity. The application should therefore use one durable retry controller rather than stacking SDK retries, PHP wrapper retries, cron retries, and proxy retries.

Stage Contracts and Validation

Why staged work is more recoverable

A single “research the world, choose stories, write both languages, attach citations, and publish” response has one large failure domain. A late composition defect can force expensive research repetition; partial evidence cannot be safely retained; source deficiencies are difficult to distinguish from prose defects; and a retry may select an entirely different event set.

The staged model creates durable checkpoints:

DesignRecovery characteristics
One giant requestAny failure can invalidate all work; retries repeat web search and composition; difficult to distinguish research, evidence, schema, and language failures
Primary research → supplemental research → compositionAccepted candidates survive composition failure; supplemental work targets measured deficits; composition retries consume only validated local evidence; each stage has a smaller schema and cost ceiling
Provider-linked chain using prior response state as sole memoryRecovery depends on provider retention and opaque prior state
Locally materialized stage artifactsEvery stage can be reconstructed, validated, versioned, and replayed independently

The strongest design does not rely on previous_response_id as the only connection between stages. Instead, the system materializes validated research locally and supplies a bounded evidence package to composition.

Primary-research contract

The primary-research request should satisfy all of the following:

Contract dimensionRequirement
PurposeDiscover and characterize candidate events; do not produce publication prose
Tool policyWeb search configured and required; maximum built-in tool calls explicitly bounded where supported
Output formatStrict JSON Schema
Candidate countMinimum target and hard maximum, for example 8–16 candidates
Event identityModel emits a proposed canonical event key; server assigns the durable local candidate ID
ClaimsAtomic claim records with stable claim IDs
SourcesExplicit source records and claim-to-source references
EvidenceWeb-search tool items, consulted-source list, and URL-citation annotations preserved
Time scopeExplicit target date and allowable chronology window
Geography/topicsRequested coverage dimensions and exclusions encoded in the contract
Publication proseProhibited
Unsupported entriesRejectable independently without invalidating all otherwise valid candidates
Tool-call ceilingFor example, no more than 12 built-in calls, subject to model/tool support
Output-token ceilingFor example, 10,000–12,000 tokens; tune from measured candidate volume
Unknown fieldsDisallowed inside the stage schema
External eventsCandidate IDs cannot be fabricated as references to unpublished prior local state

Illustrative schema shape:

{
  "contract_version": "primary-research-2026-08",
  "target_date": "YYYY-MM-DD",
  "candidates": [
    {
      "proposed_event_key": "canonical-short-key",
      "event_date": "YYYY-MM-DD",
      "chronology_precision": "day",
      "headline_fact": "Neutral factual description, not publication prose",
      "regions": ["region-code"],
      "topics": ["topic-code"],
      "claims": [
        {
          "claim_id": "claim-local-within-candidate",
          "claim": "One independently verifiable proposition",
          "source_refs": ["src-1"],
          "support_type": "direct"
        }
      ],
      "sources": [
        {
          "source_ref": "src-1",
          "title": "Source title",
          "publisher": "Publisher",
          "url": "https://example.invalid/",
          "published_at": "YYYY-MM-DD",
          "source_type": "primary"
        }
      ],
      "selection_signals": {
        "international_significance": "high",
        "novelty": "medium",
        "corroboration": "multiple_sources"
      }
    }
  ]
}

The server—not the model—should assign a stable candidate_id after normalization, for example from a process-scoped canonical event key plus collision-safe sequence. A model-provided identifier is input data, not a database authority.

A primary-research response passes only if:

  1. at least one usable web_search_call is present;
  2. required source details were retrieved through documented source inclusion or citation annotations;
  3. each accepted claim maps to at least one retrieved source;
  4. candidate and tool-call ceilings were respected;
  5. the strict local schema passes;
  6. every candidate is independently accept/rejectable;
  7. no publication-ready English or Spanish prose appears in fields intended only for neutral evidence.

The OpenAI web-search guide documents both tool-call output and URL-citation annotations, as well as inclusion of a broader source list.

Supplemental-research contract

Supplemental research must be a delta operation, not an implicit restart.

Its input includes:

accepted candidate IDs and evidence digests
rejected candidate IDs and rejection reasons
explicit deficit vector
remaining candidate/source/tool/cost budget
target date and unchanged editorial policy

Recommended deficit codes:

Deficit codeMeaningPermitted supplemental action
REGION_GAPRequired geographic distribution is not metSearch only for the specified missing region or rebalance candidates
CORROBORATION_GAPA retained candidate lacks sufficient independent supportSearch for corroboration or authoritative primary evidence for that candidate
CHRONOLOGY_GAPEvent date, sequence, or freshness is unclearSearch only for timeline clarification
TOPIC_GAPRequired topic category is absentSearch for candidates in the named category
SOURCE_QUALITY_GAPExisting source is derivative, weak, or inaccessibleSeek an official or higher-quality source
CITATION_BINDING_GAPClaim cannot be mapped to retrieved evidenceObtain evidence for the named claim or mark it unsupported
LANGUAGE_SOURCE_GAPEvidence interpretation requires language-specific clarificationObtain an authoritative source or translation basis; do not rewrite the whole brief

Supplemental output must contain only:

{
  "contract_version": "supplemental-research-2026-08",
  "addressed_deficits": ["CORROBORATION_GAP"],
  "candidate_patches": [],
  "new_candidates": [],
  "unresolved_deficits": []
}

Merging rules:

  1. accepted candidate records remain immutable;
  2. additions are stored as versioned evidence patches;
  3. removing an accepted claim requires an explicit invalidation decision and reason;
  4. candidate identity is resolved locally before merge;
  5. duplicates merge evidence rather than create new candidate IDs;
  6. unresolved deficits remain visible to the supervisor;
  7. a second supplemental round receives only remaining deficits;
  8. full primary research can be repeated only after a documented contract-level reason, such as a target-date change, broad evidence corruption, or editorial-policy revision.

Safe supplemental-research sequence

sequenceDiagram
    participant A as Research Assessor
    participant D as Local Database
    participant S as Supervisor
    participant O as OpenAI
    participant V as Validator

    A->>D: Read accepted candidates and evidence
    A->>D: Write explicit deficit vector
    S->>D: Reserve supplemental operation under current revision
    S->>O: POST deficit-only research contract
    O-->>S: Background response ID
    S->>D: Attach ID and poll by eligibility
    O-->>S: Completed delta output + source evidence
    S->>D: Preserve delta evidence
    S->>V: Validate patches, new candidates, citations
    V-->>S: Accepted delta and unresolved deficits
    S->>D: Merge additively; retain prior accepted candidates
    D->>D: Advance revision without resetting primary research

Composition contract

Composition receives only locally validated evidence. It should not receive open-ended instructions to “research anything missing.”

Contract dimensionRequirement
InputAccepted event IDs, approved claims, source/citation graph, ordering and editorial constraints
Web searchNormally unavailable; omit the tool or explicitly disallow tool use
New eventsProhibited
New factual claimsProhibited unless directly derivable and mapped to supplied claim IDs
Event identityEnglish and Spanish records use the same stable event IDs
Citation identityCitation IDs remain attached to the same claims/events in both languages
SchemaStrict, versioned JSON Schema
Language parityEvent set, material facts, dates, numbers, names, confidence qualifications, and citation set must match
Research preservationComposition failure changes no accepted research row
Retry scopeComposition only; no new research unless validation identifies a genuine evidence deficit and returns the supervisor to supplemental research

Illustrative output:

{
  "contract_version": "composition-2026-08",
  "edition": {
    "target_date": "YYYY-MM-DD",
    "events": [
      {
        "event_id": "evt-...",
        "citation_ids": ["cit-..."],
        "english": {
          "headline": "...",
          "summary": "...",
          "analysis": "..."
        },
        "spanish": {
          "headline": "...",
          "summary": "...",
          "analysis": "..."
        }
      }
    ]
  }
}

Composition acceptance requires:

output_event_ids == approved_event_ids
english_event_ids == spanish_event_ids
output_citation_ids ⊆ supplied_citation_ids
every factual sentence maps to one or more approved claim IDs
no tool-call output exists
no URL appears unless it is in the approved source set
all required language fields are present
dates, amounts, percentages, proper nouns, and qualification levels agree across languages

Composition retry without new research

sequenceDiagram
    participant S as Supervisor
    participant D as Local Evidence Store
    participant O1 as Composition Attempt A
    participant V as Validator
    participant O2 as Composition Attempt B

    S->>D: Freeze validated evidence package E
    S->>O1: Compose from E, tools disabled
    O1-->>S: Structured bilingual composition
    S->>V: Validate schema, claims, citations, parity
    V-->>S: Reject unsupported claim C
    S->>D: Record composition failure; keep E unchanged
    S->>O2: Retry composition from same E with bounded failure codes
    O2-->>S: Corrected structured composition
    S->>V: Revalidate against E
    V-->>S: Accepted
    S->>D: Commit composition exactly once

Structured-output and evidence validation

Structured Outputs improve syntactic reliability but do not remove the need for local validation. OpenAI’s own Structured Outputs materials distinguish schema adherence from truth or semantic correctness, and its examples explicitly handle incomplete responses, refusals, missing messages, and absent parsed output.

Validation should be layered:

LayerChecksFailure result
TransportHTTP and content-type validity; correct response ID; bounded body sizeRetry retrieval or quarantine
Provider stateKnown status; terminality; error/incomplete detailsPoll, reject, or reconcile
Output-item extractionLocate intended message; distinguish tool calls, refusals, and other itemsMISSING_USABLE_MESSAGE
Text extractionExactly one expected JSON payload or SDK-parsed object; no accidental concatenationAMBIGUOUS_OUTPUT_TEXT
JSON parsingValid UTF-8 and JSON; no trailing proseINVALID_JSON
SchemaContract version, required fields, types, enums, limits, additionalProperties: falseSCHEMA_MISMATCH
IdentityCandidate/event/claim/source IDs unique and correctly scopedDUPLICATE_ID or FOREIGN_ID
Tool evidenceRequired research call present; tool-call count within ceilingWEB_SEARCH_MISSING or TOOL_LIMIT_EXCEEDED
Citation graphEvery citation points to a retrieved source; every accepted claim has supportCITATION_ORPHAN or CLAIM_UNSUPPORTED
Source qualityMinimum usable source count, dates, publisher, accessibility, and independence rulesSOURCE_DEFICIT
EditorialRelevance, timeliness, duplication, prohibited content, balanced selectionEDITORIAL_REJECT
Composition groundingOutput contains no event, claim, number, or attribution outside approved evidenceUNSUPPORTED_COMPOSITION
Language paritySame events, material facts, citations, uncertainty, and ordering requirementsLANGUAGE_PARITY_FAILURE
PublicationRendering limits, escaping, link safety, and edition completenessPUBLICATION_CONTRACT_FAILURE

Specific detections:

DefectDetection method
Truncated outputstatus === "incomplete"; inspect incomplete_details.reason, including output-token exhaustion; never accept partial JSON.
Missing outputNo message item with required output content after iterating all output items
Tool execution without usable messageOne or more tool-call items exist but no acceptable message payload
Invalid JSONStrict parser failure after extracting the intended output content; no repair-by-regex in production
Schema mismatchLocal JSON Schema validator against the exact stored contract version
Unknown fieldsadditionalProperties: false in provider and local schemas; report exact JSON Pointer
Missing required fieldsLocal validator reports field path and requirement
Duplicate candidate IDsSet uniqueness check after Unicode normalization and case policy
Citation lossOutput claim references citation ID absent from composition input or research evidence
Citation URL not in evidenceCanonicalized citation URL lacks an exact source record or approved redirect relationship
Structurally valid but editorially unusableDeterministic editorial rules plus an explicitly versioned human/editorial assessment gate
Too few usable sourcesCount only sources that pass source-type, accessibility, date, independence, and claim-support rules
Unsupported composition claimSentence- or proposition-level claim cannot map to approved claim IDs
Language parity failureCompare event-ID sets, citation-ID sets, dates, numbers, named entities, negation, confidence, and material propositions across languages

URL normalization must be conservative. It may lowercase the scheme and host, remove a default port, and apply documented redirect mappings captured during retrieval. It should not silently equate unrelated paths, strip semantically meaningful query parameters, or convert a citation to a publisher homepage.

The local validation report should be immutable and machine-readable:

{
  "validation_version": "daily-brief-validation-2026-08",
  "operation_id": "op-...",
  "result_digest": "sha256:...",
  "accepted": false,
  "failures": [
    {
      "code": "CITATION_ORPHAN",
      "path": "/candidates/3/claims/1/source_refs/0",
      "entity_id": "claim-3-1",
      "detail_class": "SOURCE_REF_NOT_RETRIEVED"
    }
  ],
  "counts": {
    "candidates_received": 12,
    "candidates_accepted": 9,
    "sources_retrieved": 22,
    "sources_usable": 16
  }
}

The report should not contain full article text or unrestricted source URLs in ordinary operational logs.

Cost, Cleanup, Observability, and Operational Testing

Cost and denial-of-wallet protections

The system should impose limits before reservation, before POST, after every provider observation, and before replacement generation.

Recommended initial ceilings:

ControlSuggested initial policy
Active provider workOne active provider operation per process; global installation cap set from service tier and budget
Primary-research generationsOne normal generation; one replacement only after conclusive terminal failure or audited safe abandonment
Supplemental roundsMaximum two
Composition generationsMaximum three total
Provider create attemptsOne network transmission per generation unless failure is proven pre-dispatch
Poll actionsOne GET per eligible worker cycle
Built-in tool callsPrimary research maximum 12; supplemental maximum 6, using current max_tool_calls support where applicable
Input sizeStage-specific token and byte ceiling before API call
Output sizeStage-specific max_output_tokens; reject requests whose expected schema cannot fit
Research contextCandidate summaries and evidence digests, not an ever-growing transcript
Composition contextOnly approved evidence needed for selected events
Per-process budgetHard currency or normalized-cost ceiling computed using the price policy in force at dispatch
Per-day budgetGlobal cap plus warning threshold and circuit breaker
Browser-triggered workZero
Operator commandsOne active command of each type per operation; cooldown and audit
Rate-limit stormOpen a circuit after bounded failures; do not let every cron process retry independently
Stale processNo work after target/revision deadline without explicit policy
Full-research resetProhibited after partial success unless a documented reset reason is recorded

Before submission, use the documented token-counting capability where applicable, or a locally maintained conservative estimator, to reject oversized inputs. The request reference also documents token usage in response objects, which should be persisted as bounded accounting fields.

A process budget can be reserved rather than merely observed:

available_process_budget
    >= reserved_max_cost_for_new_operation

The reservation is released or reconciled when actual usage is known. Unknown-acceptance operations retain their reserved maximum until safely abandoned or discovered; otherwise ambiguity could be exploited to exceed the budget through repeated replacements.

Repeated browser refreshes must not affect provider cost. Repeated cron invocations see either:

not yet eligible
lease already held
operation already reserved
provider job already active
budget exhausted
terminal result awaiting validation

and perform no duplicate external side effect.

When provider or local workflow health degrades, the site may:

  • display that the current edition is delayed;
  • display the date of the last verified edition;
  • keep accepted research and deficits;
  • offer one bounded operator command;
  • resume from the last durable stage.

It must not relabel yesterday’s edition as today’s, invent a placeholder Daily Brief, omit a delay indicator, or publish unvalidated partial provider output.

Cleanup, cancellation, and deletion rules

Cancellation and deletion have different meanings:

ActionMeaningSafe use
CancelAsk the provider to stop a background operationOver-age operation, operator quarantine, obsolete process revision, or budget shutdown; reconcile afterward
DeleteRemove the provider response object through the documented delete endpointOnly after local preservation and policy eligibility
QuarantinePrevent an operation from affecting publicationAmbiguity, stale revision, unknown status, suspicious output, or incident investigation
Abandon locallyDeclare that the current process will never accept the operationUnknown acceptance beyond policy limit; does not imply remote cancellation
Purge local raw artifactApply local data-retention policyOnly after keeping required normalized evidence, hashes, audit records, and publication artifacts

OpenAI documents both cancellation and deletion endpoints. Neither should be used as a substitute for local state transitions.

Deletion eligibility should require all of:

provider_response_id is known
provider state is terminal or local policy expressly permits cleanup
no poll, validation, commit, cancellation, or incident lease is active
required output is preserved locally
required tool/source evidence is preserved locally
citation graph is preserved locally
validation report is preserved locally
usage and request-correlation fields are preserved
result has been committed, rejected, quarantined, or abandoned
minimum operational retention has elapsed
no open incident or operator hold exists

The deletion command should be written before the network call. If deletion succeeds, record provider_deleted_at. If deletion is uncertain, do not assume the object is gone; a subsequent authorized deletion check or delete retry may be appropriate because deleting an identified object is fundamentally different from repeating a create, but the implementation must still interpret documented responses and avoid unbounded retries.

Redacted diagnostics and public status

Public status should be generated from a dedicated projection rather than directly from provider objects.

Illustrative public payload:

{
  "process_suffix": "7F3A91",
  "revision": 12,
  "target_date": "2026-08-01",
  "stage_code": "RESEARCH_SUPPLEMENTAL",
  "provider_state_code": "PROCESSING",
  "health_code": "EVIDENCE_DEFICIT",
  "last_meaningful_progress": "2026-08-01T14:32:10-05:00",
  "next_eligible_cycle": "2026-08-01T14:33:05-05:00",
  "evidence_counts": {
    "candidates_accepted": 7,
    "sources_usable": 14
  },
  "deficit_codes": ["REGION_GAP"],
  "next_action": "WAIT_FOR_SUPPLEMENTAL_RESEARCH"
}

Public values must use bounded enums and counts. They must not disclose whether a specific provider account, project, region, credential, or private endpoint is in use.

Private diagnostic events may include:

full internal process and operation IDs
provider response ID in a restricted field
x-request-id
X-Client-Request-Id
request fingerprint
contract and schema versions
worker identity and fencing token
HTTP status class
cURL error class
attempt and poll sequence
latency
provider status and error code
token usage and estimated cost
result and evidence digests
redacted validation failure paths

They must redact or omit:

API credentials
Authorization headers
private prompts and full provider inputs
raw provider response bodies from ordinary logs
sensitive source URLs
account and project IDs
private filesystem paths
hostnames and IP addresses unless operationally required
personal information
cookies and session identifiers
database credentials
full webhook secrets or signatures

Use field-level allowlisting rather than a best-effort blacklist. Store sensitive artifacts, when operationally necessary, in a separate restricted evidence store with retention, encryption, and access auditing.

Suggested event envelope:

{
  "event_type": "PROVIDER_STATE_OBSERVED",
  "occurred_at": "2026-08-01T19:32:10Z",
  "process_id": "internal-reference",
  "process_revision": 12,
  "operation_id": "internal-reference",
  "operation_generation": 0,
  "worker_fence": 42,
  "stage_code": "RESEARCH_PRIMARY",
  "from_state": "QUEUED",
  "to_state": "IN_PROGRESS",
  "provider_request_id": "restricted",
  "client_request_id": "restricted",
  "fingerprint_prefix": "b42a1e5d",
  "actor_type": "WORKER",
  "diagnostic_code": "POLL_OK"
}

Operator tooling

Operator actions should be commands with explicit eligibility checks:

Operator actionEffectMust not do
Reconcile current operationSchedule one fenced retrieval or state assessmentCreate a replacement
Request cancellationPersist cancellation intent for the identified operationAssume cancellation succeeded
Quarantine operationFence it from committing and preserve evidenceDelete it immediately
Release quarantineRequire current revision, validation status, and reasonSilently reattach a stale operation
Authorize replacement generationIncrement generation under budget after explicit ambiguity acknowledgmentReuse the old generation’s authority
Retry compositionReserve a composition-only operation from the same accepted evidence digestRepeat research
Request supplemental researchSupply explicit deficits and remaining budgetDiscard retained candidates
Hold cleanupPrevent deletion during investigationChange publication state
Mark process delayedExpose clear delayed statusPublish stale content as current
Abandon processTerminal local decision with reasonPretend remote work was cancelled

Every write action should require authentication, authorization, CSRF protection where applicable, an idempotent command key, reason code, actor identity, and audit event.

Deterministic no-network fixtures

A no-network provider adapter should implement the same interface as the live adapter:

interface ResponseProvider
{
    public function create(CreateContract $contract, RequestContext $context): CreateObservation;
    public function retrieve(string $responseId, RequestContext $context): RetrieveObservation;
    public function cancel(string $responseId, RequestContext $context): CancelObservation;
    public function delete(string $responseId, RequestContext $context): DeleteObservation;
}

The fixture adapter should be scriptable by operation and call number:

{
  "create": [
    {"result": "timeout_after_send"},
    {"result": "must_not_be_called"}
  ],
  "webhook": [
    {"after_virtual_seconds": 30, "event": "response.completed", "response_id": "resp-fixture-1"}
  ],
  "retrieve": [
    {"status": "completed", "fixture": "valid_primary_research"}
  ]
}

Required fixtures include:

Fixture familyCases
TransportDNS, TLS, connect failure, timeout before send, timeout after send, truncated HTTP response
Protocol400, 401, 403, 429 with and without Retry-After, quota 429, 500, 503
Provider statusesqueued, in-progress, completed, incomplete, failed, cancelled, unknown
Output shapemissing message, multiple messages, refusal, tool-only output, invalid JSON, valid JSON with trailing prose
Schemaunknown field, missing required field, wrong enum, oversized array, duplicate IDs
Evidenceno web-search call, source list missing, orphan citation, unsupported claim, insufficient independent sources
Compositionnew event, new URL, changed number, missing citation, English/Spanish event mismatch, confidence mismatch
Concurrencyduplicate cron, duplicate webhook, two workers, expired lease, stale fence, old process revision
Crash pointsbefore POST, during POST, after create response, after provider completion, after evidence persistence, during result commit
Cleanupcancel/completion race, duplicate cancel, deletion before preservation blocked, delete uncertainty
Costbudget exhaustion, tool-call cap, token ceiling, repeated operator click, rate-limit storm

Property-based or state-machine tests should continuously assert:

active_provider_operations(process, current_revision, current_stage) <= 1
published(process) implies validated_composition_exists(process)
accepted_composition evidence_digest == accepted_research evidence_digest
stale_fence cannot mutate supervisor
result_commit_count(operation) <= 1
provider_create_count(fingerprint, generation) <= 1
replacement_generation > prior_generation
deleted(operation) implies evidence_preserved(operation)
browser_request_provider_call_count == 0

Minimal isolated live-probe strategy

A live probe should exercise real OpenAI behavior without touching publication state.

Recommended design:

AttributeRule
IsolationSeparate process namespace, tables or schema, credentials or project where operationally feasible, and no publication foreign keys
PromptTiny non-sensitive fixed request
Structured outputMinimal strict schema such as {probe_id, status, checked_at}
BackgroundEnabled to verify create and retrieval
Web searchA separate bounded probe, not every probe run, to verify tool/source/citation retrieval
Tool limitOne or two calls
Output limitVery small
BudgetHard daily cap and per-probe maximum
TriggerInternal scheduler only; no public endpoint
ValidationVerify status transitions, strict schema, request IDs, source evidence, and webhook signature path
Cancellation probeRun periodically against an intentionally slow or cancellable test only if the chosen model reliably permits it; do not manufacture uncontrolled cost
Deletion probeDelete only the probe response after evidence capture
ReportingEmit health metrics and redacted diagnostics; never publish probe output
Failure behaviorOpen probe-specific alert; do not automatically create publication jobs

A probe sequence is:

reserve probe
create one background response
persist response ID
wait until eligible
retrieve at most once per cycle
validate provider status and schema
preserve minimal evidence
optionally verify webhook correlation
delete after retention condition
record result

A green live probe proves that the selected API path currently works. It does not prove the publication supervisor is correct; deterministic workflow tests and chaos tests must establish that.

Production Acceptance Criteria and Source Record

Production acceptance gates

The workflow should not be enabled for unattended publication until all of the following are demonstrated in a production-like environment.

AreaAcceptance criterion
AuthorityNo provider status, webhook, or browser request can directly advance publication state
ReservationConcurrent scheduler invocations produce one active operation for a process revision/stage
Ambiguous createA timeout after possible POST acceptance produces no automatic duplicate POST
CorrelationEvery external action stores a client request ID and any received server request ID
Stale-worker safetyA worker holding an old fencing token cannot attach a response ID, schedule a poll, preserve a current artifact, or commit
Provider ID integrityA response ID cannot be reassigned to another operation, process, revision, or stage
PollingAt most one GET occurs per eligible server cycle; cadence and jitter are durable
Status handlingAll six documented response statuses have tested transitions; unknown status fails closed
WebhooksSignatures are verified, duplicate webhook IDs are deduplicated, and stale events cannot affect current state
Completion validationA completed response with missing message, refusal, invalid JSON, schema defect, or unsupported evidence cannot advance
Research evidenceAccepted claims map to retrieved sources; inline citations and consulted sources are preserved
Supplemental researchExisting accepted candidates survive and only named deficits are researched
CompositionNo new events or sources can enter; English and Spanish event and citation sets match
Exactly-once commitA crash at every transaction boundary produces zero or one accepted artifact, never two
CostPer-operation, per-process, and per-day ceilings are enforced before creation
Denial-of-walletBrowser refreshes, repeated cron runs, duplicate webhooks, and operator double-clicks do not create duplicate work
Rate limitsRetry-After is honored; one circuit breaker prevents a retry storm
Cancellation raceEither a valid eligible completion is accepted exactly once or the operation is cancelled/quarantined; no ambiguous mixed state
Evidence preservationDeletion is impossible before required evidence and diagnostics are durably copied
Degraded modeThe site clearly distinguishes a delayed current edition from the last verified edition
PrivacyStructured logs pass automated tests for credentials, headers, prompts, account IDs, private paths, sensitive URLs, and personal information
Recovery timeEvery nonterminal local state has a defined next eligible time or bounded operator action
TerminalityEvery retry path has a maximum attempt count, maximum elapsed time, and explicit terminal state
AuditabilityEvery authority-changing transition records process revision, operation generation, fence, actor, reason, and result
Probe isolationLive-probe failure or success cannot alter Daily Brief publication state
RunbookOperators can identify whether to wait, reconcile, cancel, quarantine, authorize replacement, retry composition, request supplemental research, or abandon
PhaseDeliverableExit condition
Supervisor foundationProcess/revision model, operation reservation, fingerprints, outbox, unique constraints, fencesConcurrency tests prove one active operation and stale-worker rejection
Fake-provider integrationDeterministic fixture adapter and complete transition suiteEvery retry-matrix row has an automated test
Research artifact modelCandidate, claim, source, citation, deficit, and validation recordsInvalid evidence cannot become accepted research
Composition modelEvidence-only input and bilingual strict outputUnsupported claims and parity defects are rejected
Live transportReal create/retrieve with isolated probeRequest IDs, statuses, evidence, and retention behavior observed
Webhooks and cancellationSigned, deduplicated notification ingestion; cancel/retrieve reconciliationDuplicate and race tests pass
CleanupEvidence-first deletion policyPremature deletion is structurally blocked
Shadow productionRun Daily Brief workflow without publishingResults remain deterministic under crashes and duplicate schedules
Supervised publicationHuman approval after local validationOperational metrics remain within cost and latency ceilings
Unattended eligibilityAutomatic publication only if editorial policy permits and every gate is greenIncident rollback and delayed-mode behavior verified

Final architectural judgment

The OpenAI platform currently provides the necessary primitives for this workflow: asynchronous Responses, retrieval, explicit statuses, structured schemas, built-in web search with source and citation information, request correlation, webhooks, cancellation, and deletion.

Those primitives are sufficient only when surrounded by a local orchestration system that assumes:

network results can be ambiguous
schedulers and webhooks are at least once
workers can become stale
provider completion is not local success
external creation is not safely repeatable without proof
every result must be reconciled to current authority
every accepted artifact must be committed exactly once
every cleanup operation must follow evidence preservation

The decisive production feature is therefore not another API connectivity test. It is a durable state machine in which the site can explain, for every provider operation:

why it was authorized
which immutable contract it represents
whether creation is known or ambiguous
who currently owns reconciliation
when another call is eligible
which evidence was recovered
why the output was accepted or rejected
whether it advanced the current process revision
what cost was consumed or reserved
when and why it may be cancelled or deleted

When those answers are durable, bounded, and testable, the Daily Brief can recover from timeouts, crashes, duplicate schedules, webhook replays, stale workers, provider delays, malformed output, and composition defects without fabricating content or losing accepted research.

Official sources

  • OpenAI API reference, Responses endpoints, request identifiers, compatibility guidance, and response object behavior.
  • OpenAI background-mode guide, including asynchronous creation and retrieval-based polling.
  • OpenAI web-search guide, including search-call output, citation annotations, and source inclusion.
  • OpenAI Structured Outputs guide and launch announcement.
  • OpenAI error-code and rate-limit guidance.
  • OpenAI webhook guide, including response completion, signature verification, retries, and duplicate-event handling.
  • OpenAI cancellation and deletion references.
  • OpenAI data-control documentation for Responses retention and background-processing storage considerations.
  • OpenAI announcements for the Responses API, web search, and background mode.