Append-only. Every set, unset, lock and
unlock with its actor, scope, reason and time. Revert is not a delete — it replays an
earlier value as a new change, so the revert is itself in the history.
| When | Operation | Value | Actor & reason | |
|---|---|---|---|---|
| 2026-08-09 14:22 | set | weekly → daily | a.riveraorg Acme Corp · "reverting the EU rollout, too slow for support" | |
| 2026-08-02 09:05 | set revert of #2 | hourly → weekly | j.okafororg Acme Corp · "restoring the value from 2026-07-02" | |
| 2026-07-28 16:40 | lock | hourly 🔒 | platform-opsportal Acme Portal · "pinned during the incident window" | |
| 2026-07-19 11:12 | unset | override removed — resolved from portal Acme Portal (weekly) | a.riveraorg Acme Corp · "tracking the portal default again" | |
| 2026-07-02 08:31 | set | — → weekly | j.okafororg Acme Corp · "aligning with EU digest policy" |
The dialog shows the current value, the target value, and that a new entry will be written. It carries a reason field, because an unexplained revert is the change people most want explained later.
The trail records that it changed, never what it was — an audit log holding secret values is a secret store with worse access control. Neither the old nor the new value appears, and "Revert to this" is absent, not disabled: there is no stored plaintext to revert to. Reveals are themselves audited entries.
| When | Operation | Value | Actor & reason |
|---|---|---|---|
| 2026-08-10 10:04 | reveal | [redacted — value not stored in the audit trail] | a.riveraportal Acme Portal · "rotating provider credentials" |
| 2026-07-14 13:50 | set | [redacted] → [redacted] | j.okaforportal Acme Portal · "quarterly rotation" |
| 2026-05-02 09:00 | set | — → [redacted] | j.okaforportal Acme Portal · "initial provisioning" |
Not an error and not a gap in the record — the key has simply never been written at this scope. It names where the value does come from, so the reader knows where to look next.
notifications.retry.maxAttempts has never been set, unset or locked at org Acme Corp. Its value comes from the definition default (5).
View the resolution chain| When | Operation | Value | Actor & reason | |
|---|---|---|---|---|
Kept apart deliberately: E is retryable and says the record is intact; F is a decision and offers no retry. A compliance reviewer must never read "history unavailable" and wonder whether the trail was lost.
Anticipated contract (FF-EPIC-18-S2 / S3). Append-only config_value_history written
in the same transaction as the value change, so a change can never exist without its audit row. The
read and revert surfaces are not in the frozen services/config-service/openapi.yaml
today — these frames commission them, and revert is modelled as a replayed
set/unset through PUT /v1/config, never as a delete.
Every actor and scope is a typed reference — a history row names scopeType +
scopeId, never a bare id (identifier-standard).