Commit Graph

2 Commits (25bcab345dabbdabd4e2b74faa865caf56771de2)

Author SHA1 Message Date
nexxo 5094f70c19 Say which slot the value in force is really coming from
Mode test, dns.token only in the :live slot, HETZNER_DNS_TOKEN also in the
.env — the state this installation is in the moment the migration runs:

  get()      -> "live-token-value"   (the stored live row is in force)
  source()   -> "environment"        -> card reads "Aus der Serverdatei"
  outline()  -> null                 -> no "Hinterlegt" block at all

So the console sent an operator to the .env to rotate a token that the
database supplies, where the edit would have had no effect. R19's dummy,
literally: a display that reads like an answer, is wrong, and stops the
next person looking.

source(), outline() and updatedAt() now ask the same one place get() does
(inForce()/fallback()), and the answer gets a THIRD value, 'stored_live'.
Not 'stored': that shows the Vergessen button, which would then have
pointed at the empty test slot. Strict entries (Stripe) still have no
fallback in either direction — pinned by its own test.

Red first (before the vault changed):

  ⨯ it names the live slot as the source when it is the one in force
    -'stored_live'
    +'environment'
  ⨯ it shows the outline and the date of the value that is actually in force

Two existing expectations moved from 'none' to 'stored_live' with the
reason written beside them: 'none' meant "nichts hinterlegt" about a
credential that was in use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:01:33 +02:00
nexxo bc6eee4dc3 Give every credential a test slot beside its live one
Each entry in the vault now stores under key:mode instead of a bare
key, and get() resolves the active mode internally — falling back
from an empty test slot to live (never the reverse) so test operation
works before anyone has filled in test credentials, but live operation
never silently reaches for a test one.

get()'s signature is unchanged on purpose: its three callers
(HttpStripeClient, StripeCheck, SshTraefikWriter) have no business
knowing which mode is active. put()/forget()/source()/outline()/
updatedAt() take an optional trailing $mode for the console, which
will use it in a later task.

SecretVaultTest's raw app_secrets queries assumed the old bare key and
needed the :live suffix plus a pinned OperatingMode — otherwise they'd
depend on whatever mode an earlier test file left in the array cache.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 10:53:17 +02:00