FA-8551 / Form submission / Open access
Submission state transitions: Editing keeps a stale completed submission state · case 01
Editing keeps a stale completed submission state.
ROOT CAUSE
The edit operation uses `if event == 'edit': return (state, errors)` where the contract requires `if event == 'edit': return ('idle', {})`.
VERIFIED REPAIR
Implement the edit operation as `if event == 'edit': return ('idle', {})`.
Unsuccessful approach: Clearing state without errors retains messages for old values.
Case contract
A duplicate pending submit preserves pending; invalid submit retains errors; success clears errors; failure installs result errors; editing resets status and stale errors.
Why this case matters
A deterministic model of submission state transitions; this isolates one interface invariant without requiring a browser.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(state, errors, event, result):
if event == 'submit':
if state == 'submitting': return (state, errors)
if errors: return ('invalid', errors)
return ('submitting', {})
if event == 'success': return ('succeeded', {})
if event == 'failure': return ('failed', result)
if event == 'edit': return (state, errors)
return (state, errors)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('duplicate', solve('submitting', {}, 'submit', None), ('submitting', {}))
check('invalid', solve('idle', {'a':'required'}, 'submit', None), ('invalid', {'a': 'required'}))
check('valid', solve('idle', {}, 'submit', None), ('submitting', {}))
check('success', solve('submitting', {'old':'stale'}, 'success', None), ('succeeded', {}))
check('failure', solve('submitting', {'old':'stale'}, 'failure', {'a':'conflict'}), ('failed', {'a': 'conflict'}))
check('edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
check('parameterized failure details', solve('submitting', {}, 'failure', {'field':str(N)}), ('failed',{'field':str(N)}))
for repetition in range(N):
check('repeat edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| duplicate | ['submitting', {}] | ['submitting', {}] | Passed |
| invalid | ['invalid', {'a': 'required'}] | ['invalid', {'a': 'required'}] | Passed |
| valid | ['submitting', {}] | ['submitting', {}] | Passed |
| success | ['succeeded', {}] | ['succeeded', {}] | Passed |
| failure | ['failed', {'a': 'conflict'}] | ['failed', {'a': 'conflict'}] | Passed |
| edit | ['failed', {'a': 'stale'}] | ['idle', {}] | Failed |
| parameterized failure details | ['failed', {'field': '1'}] | ['failed', {'field': '1'}] | Passed |
| repeat edit | ['failed', {'a': 'stale'}] | ['idle', {}] | Failed |
SHA-256 / da6baebc864f1ebb62b03cec437262f34ade262ab78ff7b0016d620f5e8c77cb
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(state, errors, event, result):
if event == 'submit':
if state == 'submitting': return (state, errors)
if errors: return ('invalid', errors)
return ('submitting', {})
if event == 'success': return ('succeeded', {})
if event == 'failure': return ('failed', result)
if event == 'edit': return ('idle', errors)
return (state, errors)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('duplicate', solve('submitting', {}, 'submit', None), ('submitting', {}))
check('invalid', solve('idle', {'a':'required'}, 'submit', None), ('invalid', {'a': 'required'}))
check('valid', solve('idle', {}, 'submit', None), ('submitting', {}))
check('success', solve('submitting', {'old':'stale'}, 'success', None), ('succeeded', {}))
check('failure', solve('submitting', {'old':'stale'}, 'failure', {'a':'conflict'}), ('failed', {'a': 'conflict'}))
check('edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
check('parameterized failure details', solve('submitting', {}, 'failure', {'field':str(N)}), ('failed',{'field':str(N)}))
for repetition in range(N):
check('repeat edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| duplicate | ['submitting', {}] | ['submitting', {}] | Passed |
| invalid | ['invalid', {'a': 'required'}] | ['invalid', {'a': 'required'}] | Passed |
| valid | ['submitting', {}] | ['submitting', {}] | Passed |
| success | ['succeeded', {}] | ['succeeded', {}] | Passed |
| failure | ['failed', {'a': 'conflict'}] | ['failed', {'a': 'conflict'}] | Passed |
| edit | ['idle', {'a': 'stale'}] | ['idle', {}] | Failed |
| parameterized failure details | ['failed', {'field': '1'}] | ['failed', {'field': '1'}] | Passed |
| repeat edit | ['idle', {'a': 'stale'}] | ['idle', {}] | Failed |
SHA-256 / 54d1d3cf758b8bb7e63412f4c7597dbb83d1c03ec7019abb014af44bb4e84fc1
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(state, errors, event, result):
if event == 'submit':
if state == 'submitting': return (state, errors)
if errors: return ('invalid', errors)
return ('submitting', {})
if event == 'success': return ('succeeded', {})
if event == 'failure': return ('failed', result)
if event == 'edit': return ('idle', {})
return (state, errors)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('duplicate', solve('submitting', {}, 'submit', None), ('submitting', {}))
check('invalid', solve('idle', {'a':'required'}, 'submit', None), ('invalid', {'a': 'required'}))
check('valid', solve('idle', {}, 'submit', None), ('submitting', {}))
check('success', solve('submitting', {'old':'stale'}, 'success', None), ('succeeded', {}))
check('failure', solve('submitting', {'old':'stale'}, 'failure', {'a':'conflict'}), ('failed', {'a': 'conflict'}))
check('edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
check('parameterized failure details', solve('submitting', {}, 'failure', {'field':str(N)}), ('failed',{'field':str(N)}))
for repetition in range(N):
check('repeat edit', solve('failed', {'a':'stale'}, 'edit', None), ('idle', {}))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| duplicate | ['submitting', {}] | ['submitting', {}] | Passed |
| invalid | ['invalid', {'a': 'required'}] | ['invalid', {'a': 'required'}] | Passed |
| valid | ['submitting', {}] | ['submitting', {}] | Passed |
| success | ['succeeded', {}] | ['succeeded', {}] | Passed |
| failure | ['failed', {'a': 'conflict'}] | ['failed', {'a': 'conflict'}] | Passed |
| edit | ['idle', {}] | ['idle', {}] | Passed |
| parameterized failure details | ['failed', {'field': '1'}] | ['failed', {'field': '1'}] | Passed |
| repeat edit | ['idle', {}] | ['idle', {}] | Passed |
SHA-256 / 5ad8ee64f343ea64fbbdd31ec11c45c4cc012cf35d29cd5f2de66069961cbd08
Verification & scope
This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:38:22.371447+00:00.
Case digest / a56cd55159de60f73186af4b91f1c1dccb9a0312f923894fccf82f545ec3e4d1