docs: ratify the biometric gate as a privacy shutter (ADR 0007) - #1341
Merged
Conversation
A grilling session over the gate's lock-and-unlock case space resolved five decisions that cohere as one architecture: the gate is a privacy shutter, one gate controller runs every ceremony, a freshness window replaces run-sharing, every gate-cannot-run outcome fails open with a notice, a minimal native device-auth call replaces the keychain sentinel, and a toggle enables a trigger and nothing else. ADR 0007 records the decision and its rejected alternatives; CONTEXT.md gains the gate's vocabulary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 27, 2026
zancas
added a commit
that referenced
this pull request
Aug 27, 2026
The pre-review of this PR confirmed ten findings; eleven red tests forced the behavior changes before any fix landed. The controller now always answers. runCeremony wraps its body and maps any rejection, a missing native module included, to a fail-open answer with a notice, and probeDeviceSecurity does the same, so no caller can be parked on a promise that never settles. The ceremony's stall countdown runs only while the app is observed 'active': leaving pauses it, returning re-arms it in full, and a fire over a provably-away app re-parks, so a stall is never declared over a provable live prompt. ADR 0007's accepted consequence still covers the Android biometric sheet, which does not leave 'active' and offers no proof. A ceremony ended by leaving the app is an answer, not a broken gate: iOS systemCancel and Android's no-resumed-activity token now lock like the ERROR_CANCELED that Android already reports for the same gesture, closing the ungated re-entry the review demonstrated. A stalled ceremony's native call is kept rather than abandoned, and the next trigger adopts it instead of colliding into a cancel that read as a decline; a late settlement arms the freshness window. The retry's answer now rides into the boot path as data through resolveTriggerGate, so the startApp trigger consumes it instead of running a second ceremony behind a clock coupling, and the fail-open notice shows once. The lock-notice-proceed policy lives in one enactGateAnswer helper that all four call sites share. The probe carries the platform code that refused to secure, and resetGateController gives tests sharing a module registry a seam out of the process-wide freshness memory. The tenth finding, dangling ADR 0007 citations, is a merge-order fact: the PR body now states that #1341 merges first. All 516 tests pass, with tsc, eslint, and prettier clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CONTEXT.md cited `app/simpleBiometrics.ts` as the home of these surfaces, and #1344 deletes that file whole. The vocabulary this section defines belongs to the gate controller the ADR prescribes, so the pointer follows it there, and "callers" becomes "triggers" to match the word the section itself introduces two entries down. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both sides appended a section to the end of CONTEXT.md: dev's "Price surface" from #1343 and this branch's "Biometric gate". Kept both, dev's first, so the file stays append-ordered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
juanky201271
approved these changes
Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A grilling session over the gate's lock-and-unlock case space resolved five decisions that cohere as one architecture. ADR 0007 records them with the rejected alternatives, and CONTEXT.md gains the gate's vocabulary (privacy shutter, gate controller, ceremony, trigger, freshness window, stall, device-auth call, security toggle, lock).
The decision supersedes the closed #1339's patch direction: the rewrite arc follows as a native device-auth module PR (mobile backend) and a gate-controller PR (UI) that deletes the coordination machinery.
🤖 Generated with Claude Code