1# Sigil appliance enrollment reset v123`sigil appliance enrollment-reset` is the stopped-service reset-all mutation4used by appliance management surfaces. It revokes every enrolled Portal5without rotating the Sigil host identity:67```bash8sigil appliance enrollment-reset \9 --config "$HOME/.config/sigil-spark/host.toml" \10 --expected-host-fingerprint '12345678…90abcdef' \11 --json12```1314The caller must first stop `sigil-host.service` and wait for it to become15inactive. The command always acquires the durable16`<state_path>/daemon-v1.lock` without waiting. When a valid private17`XDG_RUNTIME_DIR` is available, it also acquires18`$XDG_RUNTIME_DIR/sigil-spark/daemon-global-v1.lock`; an unsafe configured19runtime directory fails closed. If the variable is unset, reset remains20available from SSH or a recovery shell using only the per-state lock. A live21daemon for that state still blocks the operation. The command never stops or22starts systemd itself. This keeps service policy in the Decky backend and23prevents a reset from leaving a live remote session attached.2425Authorization writers have an explicit second level in that hierarchy:26`daemon-v1.lock` (and the global lifecycle lock when configured) is acquired27before `<state_path>/authorization-v1.lock`. The daemon holds the authorization28writer lease for its complete lifetime and serves handshakes from its validated29in-memory state. An offline reset temporarily becomes the sole writer only30after it owns the lifecycle scope. Writer-lease acquisition uses nonblocking31`flock` with a fixed 250 ms bound, so an abandoned or hung management process32cannot stall daemon startup or recovery indefinitely; terminating a crashed33owner releases the kernel lease and a retry loads the last complete atomic34state document. Live handshake contention fails closed immediately and may be35retried by Portal.3637The writer now owns one strict, bounded `authorization-v2.json` document with a38global committed revision, up to 32 peer records, unique opaque viewer handles,39per-viewer grant revisions, the invitation replay ledger, and a bounded durable40security-mutation audit. On its first sole-writer open, Sigil converts a valid41development `authorization-v1.json` in memory, atomically installs v2, syncs the42directory, and removes v1. If v2 exists, v1 is never consulted. Unknown fields,43duplicate peers or handles, unsafe storage, oversized state, and ambiguous44versions fail closed.4546The running daemon also binds47`<state_path>/authorization-admin-v1.sock`. Its parent and socket are owner-only,48the JSON request and response are bounded and strict, and no network listener49is added. `sigil invitation create`, `sigil enrollment list`, per-viewer50`sigil enrollment revoke --handle`, and `sigil enrollment set-capabilities`51use this path. A mutation is acknowledged only after the v2 document is52atomically durable, its committed revision is published, and the live registry53has applied the change. Input-grant reduction first invalidates focus and then54neutralizes all virtual input under the shared input-operation lock. Revoking a55viewer's view permission disconnects that v2 viewer. Opaque handles and coarse56grants are returned; raw peer keys and invitation bytes are not logged.5758The expected fingerprint is the redacted value returned by59`sigil appliance status`. It is an accidental-target confirmation interlock,60not a new authentication factor. Existing same-user file ownership and mode61checks remain the authority boundary.6263Success writes exactly one JSON object:6465```json66{67 "schema_version": 1,68 "operation": "enrollment_reset",69 "host_fingerprint": "12345678…90abcdef",70 "had_enrollment": true,71 "previous_epoch": 4,72 "current_epoch": 5,73 "invitations_invalidated": true74}75```7677Every successful reset-all invocation advances the authorization epoch, even78when no Portal is enrolled, because an unredeemed invitation may still exist outside79the host. The host identity stays byte-for-byte unchanged. Nonexpired replay80records remain intact, and all invitations from earlier epochs become stale.81A retry after a lost success response may advance the epoch again; that is a82safe additional invalidation.8384The legacy `sigil enrollment revoke` spelling without `--handle` remains a85strict reset-all alias. It requires `--expected-host-fingerprint` and `--json`.86With `--handle`, it performs a live reset-one operation through the daemon's87owner-only socket and retains the same host-fingerprint interlock. These scopes88are explicit: reset-one does not advance the invitation epoch; reset-all does.