You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(editor): serialise save and seal — the threading fix could seal an unvalidated register
A second adversarial review, aimed at the previous round's fixes, found
that ThreadingHTTPServer (added there so a long 1Password pull could not
block Save or Cancel) turned the register file into shared mutable state.
setup.sh validates the register and encrypts it in two separate passes.
A /save arriving between them was invisible to the validator: /seal still
returned ok, the ceremony still showed three shares, and the owner still
walked away with a printed, share-split Executor File containing a
register that never held their assets. Measured: 238 bytes against a
2646-byte control.
- One RLock now spans the whole of /save and the whole of /seal, plus
/load and the dedup scan that read the same file. The browser disables
Save for the duration too.
- Each save writes its own temp name and unlinks it on failure. Two
concurrent saves used to share target + ".tmp" and race os.replace, so
the winner renamed the LOSER's bytes into place and returned 200 to
the wrong request.
- The suite proves the invariant by timing, and the test was checked for
teeth: with the lock neutered it fails, sealing a 208-byte invalid
register.
- setup.sh gains a timeout; one 1Password pull at a time.
Also from the same review:
- The honesty gate could not be cleared. Judging "untouched action" field
by field left an owner who rewrote the note but kept an action that was
simply right warned forever — and notify-only is right for most of a
real vault, so a 563-item import would have made the warning permanent
noise, which is how a gate teaches people to click through it.
Engagement is now per card: the first edit to any field clears it.
- \b was the wrong boundary for vault names: "_" is a word character, so
Work_Vault and Teams matched nothing and defaulted to TICKED — pulling
a colleague's accounts into a personal estate register. Bounded on
letters now, with an optional trailing s. Homework and Framework stay
ticked.
- Declining the gate said nothing, so the button looked broken; the
zero-match screen claimed items did not exist when they were merely
hidden; the wizard's "transfer" wording named a beneficiary the wizard
never asks for.
Suite 166 -> 169 pass / 0 fail (167/0 under expect), shellcheck clean.
Spec §12.2 records the round.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments