refactor(cli): state the credential-store precedence rules as contracts

Drop the inline notes on keychain erasure and disk-vs-vault precedence in favour
of docstrings on the two functions that own those rules, and remove a stale
section header and a field note that the code already says plainly.
This commit is contained in:
mateo-berri 2026-08-19 19:11:01 -07:00
parent 0de829d3e4
commit bd322ed8a7
3 changed files with 10 additions and 5 deletions

View file

@ -98,10 +98,14 @@ class KeyringVault:
return True
def erase(self) -> bool:
"""Whether the keychain is guaranteed to hold no credential afterwards.
An uninstalled `keyring` package can never have stored one. A kill switch set after
a credential was stored leaves that entry out of reach, so erasure cannot be promised.
"""
if _import_keyring() is None:
return True
if _keyring_disabled():
# a credential stored before the kill switch was set may still be in the keychain
return False
match self.read():
case SecretUnavailable():

View file

@ -168,8 +168,12 @@ def _resolve_secret(record: CliTokenRecord, vault: SecretVault) -> CliTokenRecor
def _apply_vault_secret(record: CliTokenRecord, blob: str, vault: SecretVault) -> CliTokenRecord | None:
"""Resolve the credential when both stores hold one.
A secret still on disk is the fresher of the two, because it is only left there when the
keychain write that should have removed it failed, so it outranks the vault entry.
"""
if record.key is not None:
# a secret still on disk means the last keychain write failed: the file outranks the vault
return _migrate_file_secret(record, vault)
try:
secret: Final = CliTokenSecret.model_validate_json(blob)

View file

@ -76,7 +76,6 @@ KEYCHAIN_UNREACHABLE_MESSAGE: Final = (
)
# Token storage utilities
def context_secret_vault(ctx: click.Context) -> SecretVault:
"""Where this invocation reads and writes secret material; injectable through ctx.obj for tests"""
ctx_obj: Final[CliContextObj | None] = ctx.obj
@ -666,8 +665,6 @@ def login(ctx: click.Context, config_claude: bool):
api_key: Final = auth_result["api_key"]
user_id: Final = auth_result["user_id"]
# base_url is stored so we can verify origin before reusing the
# key on a subsequent CLI invocation.
record: Final = CliTokenRecord(
base_url=base_url.rstrip("/"),
key=api_key,