Stateful journeys/Capture & Feedback
hybridlocation capture attempt aggregate

Consent-bound location capture evidence

Initialize and configure an entitled Location Capture SDK, acquire a bounded single or subscribed fix, preserve accuracy and timing as evidence, review weak results, and stop every native resource deterministically.

Every state means something operational

A state is not a UI label. It determines which actor may act, what evidence exists, what may be retried, and how recovery proceeds.

01
draft

Draft

The host owns a business purpose, subject or case identity, capture policy, and retention class before requesting device access.

02
permission_pending

Permission pending

The user is deciding the minimum native permission for the declared purpose and visible capture behavior.

03
ready

Ready

SDK initialization, entitlement, permission, policy validation, and one launch generation have succeeded.

04
acquiring

Acquiring

Exactly one single-shot request or bounded subscription owns timeout, accuracy, distance, packet-size, callback, and cleanup responsibility.

05
candidate

Candidate

A returned event has normalized coordinates, horizontal accuracy, event time, receipt time, policy result, and source generation, but is not yet accepted evidence.

06
review_pending

Review pending

The candidate is usable only with human review because accuracy, freshness, or policy confidence is below the automatic threshold.

07
acceptedterminal

Accepted

An actor accepted one immutable normalized fix for the declared purpose and policy version, with an audit event and retention deadline.

08
cancelledterminal

Cancelled

The user or host ended the attempt and every active SDK resource was stopped or unsubscribed.

Transitions are attributable and retry-safe

Commands express intent. The aggregate validates current state and invariants, commits one new version, and emits a fact in the same transaction.

Command & actorAllowed fromResultIdempotency strategy
create_attemptHost application
new aggregate
draftlocation_capture.attempt_created

Map one external case and capture-purpose identity to one attempt across retries.

request_permissionApplication user
draft
permission_pendinglocation_capture.permission_requested

Record one visible request per policy decision and current native authorization state.

prepare_sdkPlatform adapter
permission_pending
readylocation_capture.sdk_ready

Bind initialization and validated configuration to one launch generation without persisting credentials or SDK instances.

start_acquisitionApplication user
readyreview_pending
acquiringlocation_capture.acquisition_started

A command key starts at most one single-shot request or subscription generation.

receive_locationPlatform adapter
acquiring
candidatelocation_capture.candidate_received

Normalize and hash one qualifying terminal event per single-shot generation, or deduplicate subscribed events by bounded source identity.

queue_reviewHost application
candidate
review_pendinglocation_capture.review_queued

The evidence hash and policy version create at most one review case.

accept_evidenceApplication user
candidate
acceptedlocation_capture.evidence_accepted

Commit evidence, policy result, processed command, audit event, and outbox record atomically.

approve_weak_evidenceEvidence reviewer
review_pending
acceptedlocation_capture.weak_evidence_approved

Bind the reviewer identity and bounded justification to the immutable candidate hash.

cancel_attemptApplication user
draftpermission_pendingreadyacquiringcandidatereview_pending
cancelledlocation_capture.attempt_cancelled

Repeated cancellation returns the terminal record while stop and unsubscribe cleanup remain exactly-once-in-effect.

Persist enough to recover and explain

Keep provider responses, business identity, state, events, and side-effect delivery distinct so each can be reconciled safely.

Capture attempt

Current host-owned purpose, policy, lifecycle state, generation, and optimistic version.

attemptIdexternalIdpurposepolicyVersionstategenerationversion

Normalized location evidence

Immutable accuracy-bearing observation independent of the SDK object's lifetime.

evidenceIdlatitudelongitudehorizontalAccuracyeventTimereceivedTimesourceGenerationcontentHash

Review decision

Attributable disposition of evidence that cannot be accepted automatically.

reviewIdevidenceIdreviewerdecisionreasondecidedAt

Audit and outbox

Append-only transitions and exactly-once-in-effect downstream notification.

eventIdaggregateVersionactoridempotencyKeyoutboxStatus

Protect truth at the aggregate boundary

  1. 1

    A permission grant is not consent for every purpose; purpose, policy, and retention are recorded separately.

  2. 2

    One acquisition generation owns one callback family, timeout, stop, and unsubscribe lifecycle.

  3. 3

    Accuracy, event time, receipt time, and policy result remain attached to the normalized coordinates.

  4. 4

    A callback creates a candidate, never an accepted business decision.

  5. 5

    Weak or stale evidence cannot pass an automatic acceptance threshold by omitting quality fields.

  6. 6

    Credentials, native manager instances, full opaque payloads, and callback closures never enter durable storage.

Know what to do before it breaks

Recovery changes durable truth only through the same rules as normal operation. A timeout is an unknown outcome, not evidence that nothing happened.

Permission is denied or restricted

Detect

The native authorization result cannot satisfy the declared capture mode.

Recover

Explain the affected outcome, offer settings or a manual fallback where appropriate, and keep the attempt non-acquiring.

Initialization or entitlement fails

Detect

The documented initialize operation returns failure before the generation becomes ready.

Recover

Expose a safe configuration or entitlement error, retain no credential value, and require a deliberate retry after correction.

Acquisition times out or misses the accuracy budget

Detect

The configured deadline expires or every event remains outside policy.

Recover

Stop or unsubscribe once, preserve the quality reason, and route to review, retry, or fallback rather than fabricating a precise fix.

A callback arrives after cancellation or screen disposal

Detect

The owner is inactive or callback generation differs from the current attempt generation.

Recover

Ignore the event, perform idempotent cleanup, and do not change the terminal or newer attempt.

The app restarts during review

Detect

The immutable candidate exists but the review command lacks acknowledgement.

Recover

Reload the attempt and replay the same command key; never reacquire or duplicate evidence merely to recover workflow state.

Observe the journey, not merely HTTP status

Measure state age, event health, retries, reconciliation, and sensitive-data access alongside latency and error rate.

  • Initialization and configuration outcomes by SDK platform and released version
  • Permission denied, restricted, and settings-return rate
  • Time to first event and time to policy-acceptable event
  • Accuracy and freshness distributions without high-cardinality coordinate labels
  • Single-shot, subscription, timeout, stop, unsubscribe, and late-callback counts
  • Automatic acceptance, review, retry, fallback, and cancellation rate
  • Idempotency replay and optimistic version conflict rate
  • Outbox backlog, retry, and dead-letter age

Contracts, repositories, workshops, tutorials, and runnable evidence

Only explicitly indexed evidence is linked. Empty sections are not backfilled with invented endpoints or package names.