Keep the credential as a versioned record written whole #60

Merged
PerishFire merged 2 commits from credential-state into main 2026-08-01 07:36:05 +00:00
Owner

Plumb's home-and-state law wants machine-written records under state/,
schema-versioned, and written by writing beside and renaming. The credential
was none of those: two bare lines at the home root, truncated in place by
File::create, so a crash mid-write left half a token on disk and nothing
could tell an old shape from a corrupt one.

It is now state/pat.json carrying its schema, staged beside and renamed over,
with the mode set before any bytes are written. An unknown schema declines to
load rather than guessing. Naming the record by kind leaves room for the OIDC
session to arrive as its own record rather than sharing one file with a
credential that never expires — a refresh would otherwise rewrite the
long-lived secret on every 401.

The act read the file straight off disk, so it moved with it and now asserts
the schema too. That is what caught the change.

plumb also moved to 0.18.9 while this repository's lock still resolved 0.18.7,
which held guard at its second step.

Guard was run in full on the committed state and is clean, including all six
acts.

One law is still owed here: config::home() hand-rolls its cascade over
ENSIGN_HOME, XDG_CONFIG_HOME and $HOME instead of going through Plumb's.
That needs crates/cli to depend on Plumb and is left for its own change.

Plumb's home-and-state law wants machine-written records under `state/`, schema-versioned, and written by writing beside and renaming. The credential was none of those: two bare lines at the home root, truncated in place by `File::create`, so a crash mid-write left half a token on disk and nothing could tell an old shape from a corrupt one. It is now `state/pat.json` carrying its schema, staged beside and renamed over, with the mode set before any bytes are written. An unknown schema declines to load rather than guessing. Naming the record by kind leaves room for the OIDC session to arrive as its own record rather than sharing one file with a credential that never expires — a refresh would otherwise rewrite the long-lived secret on every 401. The act read the file straight off disk, so it moved with it and now asserts the schema too. That is what caught the change. plumb also moved to 0.18.9 while this repository's lock still resolved 0.18.7, which held guard at its second step. Guard was run in full on the committed state and is clean, including all six acts. One law is still owed here: `config::home()` hand-rolls its cascade over `ENSIGN_HOME`, `XDG_CONFIG_HOME` and `$HOME` instead of going through Plumb's. That needs `crates/cli` to depend on Plumb and is left for its own change.
Plumb's home-and-state law wants machine-written records under state/,
schema-versioned, and written by writing beside and renaming. The credential
was none of those: two bare lines at the home root, truncated in place by
File::create, so a crash mid-write left half a token and nothing could tell an
old shape from a corrupt one.

It is now state/pat.json carrying its schema, staged beside and renamed over,
with the mode set before any bytes are written. An unknown schema declines to
load rather than guessing. Naming the record by kind leaves room for the OIDC
session to arrive as its own record instead of sharing one file with a
credential that never expires.

The act read the file straight off disk, so it moved with it and now asserts
the schema too.
deps: follow plumb to stable latest
All checks were successful
guard / guard (pull_request) Successful in 3m48s
guard / guard (push) Successful in 3m35s
34880203b6
PerishFire deleted branch credential-state 2026-08-01 07:36:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
PerishLab/ensign!60
No description provided.