I built an independent comparator to examine which action a visible success message actually belongs to. It accepts synthetic before-and-after observations, the original condition and a declared dispatch phase without operating a browser. An observed change is kept distinct from confirmed remote storage.
The module contains comparison rules only
Assess transition accepts before, after, condition and phase. Observations contain a tab label, text, pre-parsed route and declared boolean states. There is no page-reading callback, click, polling or retry operation. A pure function makes the comparison testable without another action.
Phase is a caller assertion of preparation, dispatch or uncertainty, not authenticated delivery evidence. Equal tab strings also do not prove ownership. A real adapter must derive trustworthy observations and journals. This module cannot create those prerequisites on its behalf.
Reject conditions already true before the operation
Text matching normalizes whitespace and case before inclusion comparison. A condition present in before is rejected rather than reused as evidence of a new success. Empty expected text is also invalid because it would trivially match every body.
If the condition appears after a prepared-only phase, the result reports presence without dispatch confirmation. A matching condition and evidence of our delivered action are different conclusions; another actor may have produced it. The example favors accurate intermediate states over an attractive success label.
Give routes and states their own comparison rules
Routes are supplied as origin, path and query parts. Origin and path are exact; required query pairs use multiset counts, allowing additional actual pairs. Two identical required pairs need two occurrences. Raw URL parsing, percent decoding and fragment comparison are deliberately outside this example.
A state expectation needs exactly one matching name, role and field before comparing the boolean value. Fields are limited to checked, expanded and selected. The resolver cannot choose a convenient one of two equal names. These are metadata comparisons; real DOM and screen validity remain adapter responsibilities.
Explore the implementation
Complete independent synthetic implementation
"""Compare supplied synthetic before/after observations. No browser or delivery."""
from collections import Counter
class OutcomeError(ValueError):pass
def _keys(value,fields):
if not isinstance(value,dict) or set(value)!=set(fields):raise OutcomeError('INVALID_FIELDS')
def _text(value,empty=False):
if not isinstance(value,str) or len(value)>20000 or (not empty and not value.strip()):raise OutcomeError('INVALID_TEXT')
def _norm(value):return ' '.join(value.strip().split()).lower()
def _pairs(value):
if not isinstance(value,list) or len(value)>1000:raise OutcomeError('INVALID_QUERY')
for pair in value:
if not isinstance(pair,list) or len(pair)!=2:raise OutcomeError('INVALID_QUERY')
_text(pair[0]);_text(pair[1],True)
return Counter(tuple(pair) for pair in value)
def _route(value):
_keys(value,['origin','path','query']);_text(value['origin']);_text(value['path']);_pairs(value['query'])
def _observation(value):
_keys(value,['tab','text','route','states']);_text(value['tab']);_text(value['text'],True);_route(value['route'])
if not isinstance(value['states'],list) or len(value['states'])>1000:raise OutcomeError('INVALID_STATES')
for state in value['states']:
_keys(state,['name','role','field','value'])
for key in ['name','role']:_text(state[key])
if state['field'] not in ['checked','expanded','selected'] or type(state['value']) is not bool:raise OutcomeError('INVALID_STATE')
def _condition(value):
if not isinstance(value,dict):raise OutcomeError('INVALID_CONDITION')
kind=value.get('kind')
if kind=='text':_keys(value,['kind','value']);_text(value['value'])
elif kind=='route':_keys(value,['kind','route']);_route(value['route'])
elif kind=='state':
_keys(value,['kind','name','role','field','value'])
for key in ['name','role']:_text(value[key])
if value['field'] not in ['checked','expanded','selected'] or type(value['value']) is not bool:raise OutcomeError('INVALID_STATE')
else:raise OutcomeError('INVALID_CONDITION')
def _matches(observation,condition):
kind=condition['kind']
if kind=='text':return _norm(condition['value']) in _norm(observation['text'])
if kind=='route':
actual,expected=observation['route'],condition['route']
return actual['origin']==expected['origin'] and actual['path']==expected['path'] and not (_pairs(expected['query'])-_pairs(actual['query']))
matches=[s for s in observation['states'] if _norm(s['name'])==_norm(condition['name']) and _norm(s['role'])==_norm(condition['role']) and s['field']==condition['field']]
return len(matches)==1 and matches[0]['value'] is condition['value']
def assess_transition(before,after,condition,phase):
"""Metadata and phase are caller assertions; this function authenticates none."""
_observation(before);_observation(after);_condition(condition)
if before['tab']!=after['tab']:raise OutcomeError('OBSERVATION_SCOPE_CHANGED')
if phase not in ['prepared','dispatched','unknown']:raise OutcomeError('INVALID_PHASE')
if _matches(before,condition):raise OutcomeError('EXPECTATION_ALREADY_TRUE')
matches=_matches(after,condition)
verified=matches and phase in ['dispatched','unknown']
state='observed_transition' if verified else 'condition_present_without_dispatch' if matches else 'not_confirmed'
return {'state':state,'condition_matches_after':matches,'verified_transition':verified,'phase':phase,'automatic_replay':False,'proves_causality':False,'starts_an_action':False}
Represent a late observed result without replay
A declared dispatched or uncertain phase followed by the original false-to-true condition reports an observed transition. Automatic replay and causal proof remain false. Reading a late result does not establish every causal relationship or remote persistence.
Twenty-one tests cover text, unique state and route matching, preexisting conditions, unconfirmed outcomes and prepared-only presence. Lookalike origin and path, repeated query counts and ordering, duplicate states, changed scope, wrong types and unknown fields have checks too. Input immutability and the absence of action creation are explicitly tested.
The selector reads five actual local records
Synthetic records show a new result, an already-true condition, an unconfirmed result, preparation-only presence and a late observed transition. Local Python generated them. The selector displays that material without reading visitor accounts or judging actual server storage.
The package procedure compares entry hashes, extracts into another folder and runs the same twenty-one tests. Both inline language selectors are checked with DOM stubs. These do not establish rendered-browser or current external-publication verification. Code execution and display of stored records retain their own scopes.
Connect the final business result in a real adapter
The public ZIP contains complete code, tests, examples, record generation and README using only the standard library, with modification and reuse permitted. It implements no durable journal, timeout, cancellation, authentication or raw-address parser. Those belong in an integration suited to the workflow.
High-impact approvals or external publications need actual service records beyond an observed transition. Another actor could create the same text, and the observation may itself be partial. I share this as a review component for questioning why a condition counts as success, not a universal success oracle.