draftDraft
Host-owned address or place intent exists without an active provider surface or committed Mappls identity.
Launch a Mappls widget, recover through a useful fallback, validate a narrow candidate, commit it deliberately, invalidate stale selection, and submit one durable business record.
A state is not a UI label. It determines which actor may act, what evidence exists, what may be retried, and how recovery proceeds.
draftHost-owned address or place intent exists without an active provider surface or committed Mappls identity.
widget_openOne launch generation owns the provider surface, lifecycle callbacks, focus, cancellation, and timeout.
fallback_activeThe provider surface is unavailable and a bounded manual or search-assisted host path remains operable.
candidate_receivedAn exact-origin or native-adapter result passed schema validation but is not yet a business selection.
selectedThe user deliberately committed a normalized Mappls Pin and label against the current host draft version.
submittedterminalHost text and committed selection form one immutable, attributable business record with an outbox event.
cancelledterminalA named actor ended the journey without submission and with a recorded reason.
Commands express intent. The aggregate validates current state and invariants, commits one new version, and emits a fact in the same transaction.
create_sessionHost applicationhost.session_createdThe external checkout/form identity maps to one aggregate across retries.
open_widgetApplication userdraftfallback_activewidget.openedPersist one launch generation and ignore every callback belonging to an older generation.
activate_fallbackPlatform adapterwidget_openwidget.fallback_activatedOne failed generation produces at most one fallback transition and focus restoration.
receive_candidatePlatform adapterwidget_openfallback_activelocation.candidate_receivedDeduplicate the terminal adapter result and bind it to session and launch generation.
accept_selectionApplication usercandidate_receivedlocation.selectedCompare aggregate version and hash the normalized candidate before committing.
edit_host_textApplication userdraftwidget_openfallback_activecandidate_receivedselectedhost.text_editedThe edit command version determines whether candidate and selection invalidation already occurred.
submitApplication userselectedhost.submittedCommit the record, audit event, processed command, and outbox entry atomically.
cancelApplication userdraftwidget_openfallback_activecandidate_receivedselectedhost.cancelledRepeated cancellation returns the terminal record without rerunning cleanup side effects.
Keep provider responses, business identity, state, events, and side-effect delivery distinct so each can be reconciled safely.
Current host draft, lifecycle state, launch generation, candidate, selection, and optimistic version.
sessionIdexternalIdstateversionlaunchGenerationhostTextApplication-owned portable place identity independent of provider UI lifetime.
schemaVersionmapplsPinlabelsourceselectedAtselectedByAttributable state transition and recovery history.
eventIdaggregateVersiontypeactoridempotencyKeyoccurredAtExactly-once-in-effect notification and downstream form processing.
outboxIdeventIdstatusattemptsnextAttemptAtA provider callback or browser message creates only a candidate, never a submitted business record.
Every browser message matches the exact reviewed origin and a versioned allow-listed schema.
Only a six-character alphanumeric Mappls Pin and bounded printable label enter durable selection state.
A host-text edit invalidates every candidate and committed selection from the previous draft version.
One launch generation produces at most one terminal adapter outcome; late callbacks are ignored.
Credentials, provider controllers, native views, bridge objects, and opaque response payloads are never persisted.
Recovery changes durable truth only through the same rules as normal operation. A timeout is an unknown outcome, not evidence that nothing happened.
The active generation reaches a typed failure without a valid terminal candidate.
Dispose it, restore focus, record the reason, and activate a useful host-owned fallback.
Exact origin or narrow schema validation fails before domain processing.
Reject without changing aggregate state and emit a safe rejection metric without storing opaque content.
Owner is inactive or result generation differs from the current session generation.
Ignore the late result and clean up its provider resources without committing state.
Host draft version changes while a candidate or selection exists.
Clear both values, return to draft, and require a new selection before submission.
Client lacks acknowledgement but retains session and idempotency identity.
Repeat the same command key or read the session; never create a second business record.
Measure state age, event health, retries, reconciliation, and sensitive-data access alongside latency and error rate.
Only explicitly indexed evidence is linked. Empty sections are not backfilled with invented endpoints or package names.
8 labs · 5 hostile scenariosmappls-app-widgetsmappls-android-sdkmappls-ui-widget-ios-distributionmappls-ui-widget-ios-distribution-basemappls-flutter-sdkmappls-react-native-sdk8 verified tests