How to Log an Incomplete SOS Response With Interim cachedData

September 16, 2026
September 16, 2026
10 Minutes Read
Secretary of State APIblog main image

Executive Summary: When one Cobalt Secretary of State request produces interim cachedData and a later live result, retaining only the final response is no longer enough to explain what the workflow knew and did. A lender's operational trace should preserve both observations, their source and times, the open-request state, every interim permission or action, and the final disposition. The goal is reconstructable processing, not a claim that one log format satisfies every legal or regulatory requirement.

Why Is the Final Response Alone Insufficient?

What can happen before live completion?

The incomplete response may contain a cached business record with updatedAt. A system can display it, evaluate its age, prepare a review, or place work in a queue while the live search continues. Those events influence people and systems before the terminal result exists.

Cobalt defines 202 + Incomplete as continued processing rather than failure.[1] The trace must therefore show both useful interim data and unfinished process state.

What disappears when final data overwrites interim data?

The organization loses which record was visible, which age rule ran, why an interim action occurred, and whether the live result later differed. A final snapshot can make an earlier action appear unsupported or make a changed field look as though it was always present.

Preserve what was known at each phase, not only what was known at the end.

Cobalt's source guidance distinguishes cached and live observations.[2] Keep that provenance after completion.

Think of the trace as a timeline of claims. The cached observation claims that particular structured data existed in Cobalt's stored record at a documented update time. The process event claims the live search remained open. A policy event claims the lender permitted or withheld an action. The final observation claims what the live path returned. Keeping claims separate prevents one source from borrowing the authority of another.

Which Identities Should Connect the Trace?

What is the lender's primary correlation key?

Use one lender-owned verification request ID tied to the application, intended purpose, and attempt. Store Cobalt retryId as provider correlation beneath it. Cobalt's public SOS reference describes retryId as the handle for longer-running processing.[3]

The lender key should connect every response, policy evaluation, user action, queue event, callback, poll, and disposition without exposing customer data in general logs.

Which additional IDs improve reconstruction?

Assign immutable observation IDs, provider event or delivery IDs when available, policy-evaluation IDs, review-case IDs, artifact IDs, and business-effect IDs. Use structured links rather than repeating full payloads in each log line.

• Request ID. One logical verification attempt.

• Provider correlation. The associated retryId.

• Observation ID. One cached or live response version.

• Policy event ID. One evaluation under a named rule version.

• Effect ID. One downstream action or message.

• Disposition ID. The terminal lender outcome record.

Define cardinality too. One request can have several delivery events and observations, but only one active terminal disposition for an attempt. One observation can support several policy evaluations for different actions, while each durable effect has one purpose and idempotency key. These relationships help analysts detect impossible histories instead of merely collecting more data.

What Should the Interim Event Record Contain?

Which provider facts belong in the record?

Store top-level status and code, retryId, raw or controlled-response reference, whether cachedData was present, the cached observation ID, raw updatedAt, receipt time, request inputs or their protected reference, and delivery path. Do not invent a screenshot or live-source field for the cached phase.

Cobalt says cached timestamps support customer recency decisions.[4] Retain both the provider timestamp and customer receipt time because they answer different questions.

Which lender facts belong beside them?

Record calculated age, action evaluated, policy version, rule outcome, permitted or blocked effect, user or service actor, and next process state. Keep customer-derived facts clearly separated from provider payload fields.

{
  "requestId": "vr_1042",
  "observationId": "obs_cached_1",
  "source": "cached_interim",
  "providerStatus": "Incomplete",
  "updatedAt": 1788994658510,
  "policyVersion": "sos-interim-v3",
  "policyOutcome": "preliminary_review_allowed",
  "nextState": "live_pending"
}

This is a lender-side audit example, not the Cobalt API schema.

Include schema version and parser version with the retained response reference. If the consumer changes field mapping later, a reviewer should be able to distinguish the original provider bytes from the normalized record created at ingestion. Corrections should create new derived versions and link them to the earlier interpretation, not mutate the historical observation silently.

How Should Actions and Permissions Be Logged?

Why should permission and action be separate events?

A rule can permit an action that nobody takes, or a user can attempt an action that the server rejects. Record policy evaluation, attempted action, authorization result, and durable effect separately. This prevents a pass from being mistaken for an actual workflow change.

OWASP recommends logging the event's when, where, who, and what, including status, reason, and action.[5] Apply that structure without writing unnecessary sensitive content.

Which interim actions deserve explicit history?

Record display where policy requires it, prefill, comparison creation, review assignment, export, document request, queue prioritization, and any reversal or supersession. Name the observation version that supported the action.

If the cached record is absent or rejected by age policy, log the reason and continued live-pending state. Cobalt's cache-miss guidance says absence does not prove registry absence.[6]

Capture attempted actions even when the server blocks them, using a controlled reason code and without recording unnecessary user input. Repeated attempts can reveal stale interface state, unclear labels, or a consumer bypassing the normal transition service. The rejected event must not be confused with a completed business effect.

How Should the Final Live Result Be Recorded?

What belongs in the terminal event?

Store the live observation ID, receipt time, source, terminal provider status, request correlation, raw-response reference, artifact links, comparison outcome, prior state, next state, and terminal business effects. Keep the cached observation immutable.

Cobalt supports polling and callbacks for completing longer-running requests.[7] Both delivery paths should write the same terminal event shape.

How should cached-live variance appear?

Create a comparison event that identifies fields agreed, fields differed, rule version, review requirement, and disposition. Avoid rewriting the cached event or adding an accusation. Search paths can rank candidates differently.

If a screenshot or official document is returned, link it only to the live observation that produced it. Cobalt notes that artifact availability varies by state and lookup path.[8]

Record supersession without deletion. The final live observation may become primary for current use, while the cached observation remains historical. A relationship such as finalizes_request or supersedes_for_decision explains priority without asserting that the earlier record never existed. If values differ, link the separate comparison and review outcome.

How Should Duplicates and Retries Appear?

Should a repeated delivery create a new business event?

No. Record the repeat and its deduplication result, then return the stored outcome without repeating the effect. Preserve event identity, first-seen and last-seen times, content consistency, and the idempotency key used.

AWS recommends idempotent retry handling so repeated operations have the same state effect as one.[9] The audit trace should prove that convergence.

What if duplicate content conflicts?

Do not overwrite the earlier observation. Quarantine the event, record the conflict, block repeated business effects, and route it through the lender's exception process. A content conflict is different from a harmless repeated delivery.

Terminal state should remain monotonic. A late incomplete event can be retained for diagnostics but cannot move a completed request back to pending.

Distinguish network duplicates, provider repeats, consumer replays, and user resubmissions. They may look similar but require different controls. A network repeat can be a no-op under the same event key. An authorized user resubmission should create a new attempt linked to the original request, with a reason and separate terminal slot.

How Should Logs, Evidence, and Artifacts Be Separated?

What belongs in an application log?

Put references, timestamps, actor or service identity, state changes, reason codes, and outcomes in the operational log. Store full provider payloads, screenshots, and documents in authorized evidence storage. Do not copy credentials, tokens, or unnecessary customer data into general logs.

Use structured events with stable field names. Free text can add context, but it should not be the only place a disposition or rule version exists.

Maintain an event dictionary that defines field meaning, source, allowed values, sensitivity, and owner. Version changes to that dictionary. If status means provider status in one event and lender workflow status in another, analysts may produce a false sequence even though each event is technically valid. Prefer explicit names such as providerStatus and workflowState.

What belongs in retention and access policy?

The lender decides how long each record class is retained, who may access it, how it is protected, and how disposal is recorded. NIST describes log management as a lifecycle across generation, transmission, storage, access, and disposal.[10]

An operationally complete trace is not automatically a complete legal or regulatory record. Route requirements to the authorized owner.

Test access as part of the trace. Authorized reviewers should resolve references needed for their role, while unrelated users and services should receive a controlled denial. Record access where policy requires it, and verify that deletion or expiration removes the protected object without leaving a public link or misleading availability flag.

How Should Reconstruction Be Tested?

Which story should a reviewer be able to tell?

Starting from one request ID, a reviewer should recover the original query, incomplete status, cache presence or absence, cached source and age, policy evaluated, interim actions, delivery events, final live observation, cached-live comparison, terminal disposition, and downstream effects.

The story should remain accurate when no cached data appears, no screenshot is available, or the live result is no-match.

Run reconstruction from the stored records alone, without relying on engineer memory or application source code. Give a reviewer a request ID and ask them to produce the timeline and decisive evidence. Compare the result with the expected fixture. If manual database joins or undocumented field knowledge are required, the trace is not operationally usable.

Which failure cases belong in the test plan?

Test duplicate incomplete delivery, callback-poll race, worker crash after state commit, failed evidence storage, invalid timestamp, unauthorized access, late interim event, changed live candidate, final no-match, and terminal error. Assert both records present and records absent, especially that no secret or full payload leaks into general logs.

Include clock and ordering tests. Delay ingestion, send events from workers with different clocks, and deliver a stale response after a newer one. Preserve provider time, receipt time, and committed sequence separately so the reconstruction does not rely on sorting one imperfect timestamp. State-transition order should come from durable versioning.

The automated audit-trail guide provides broader context, while the asynchronous webhook guide covers event delivery. To review the audit event model against your architecture, schedule a demo.

Retain the reconstruction result as a versioned regression case for later schema changes.