You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9adb405
Browse filesBrowse the repository at this point in the historyBrowse files
fix(provenance): classify a latched-but-empty registry's file writes as unrecorded (#7084)
* fix(provenance): classify a latched-but-empty registry's file writes as unrecorded
A copilot chat whose registry latched — the recurring producer is a
workflow run that failed before exporting provenance, crossing as
value-provenance-absent — stamped every file it later wrote with the
unknown taint, which no policy relaxes. The chat then could not read
the file back: generating a document and immediately rendering it to
show the user hard-failed with "cannot be shared safely", and healed
only when a later clean turn rewrote the sidecar. Traced in
production: the refused file's terminal sidecar is exact with zero
entries — a file with no secrets in it — and the last refusal landed
under a minute before the healthy write.
The write decision now distinguishes the two states its own policy
names. A latched registry holding no active entries is an absence: no
secret plaintext was resolved or imported in that context, so none can
be in the bytes, and the only fact is that content of unrecorded
history crossed — which is what the unrecorded status states, readable
under the fail-open policy with the audit entry naming the surface.
Taint stays reserved for a registry that holds plaintext it cannot map
to this output, and for every structural refusal below (scope, derived
representations, encryption).
Also carries the fault kind as a structured field on the trace-store
display lines, so dashboards can group without parsing messages.
* fix(provenance): relax a latch to unrecorded only when no fault is on record
Review finding, accepted with a broader gate than proposed: zero active
entries alone does not prove the context never held plaintext — a
verification or decrypt fault trips while secret material is in flight,
before anything activates — so keying the absence carve-out on the
entry count alone let a fault-latched registry stamp unrecorded.
Gate it on the one centrally maintained classification of exactly this
distinction: the originating-fault reason set that already decides the
report level. A latch relaxes to unrecorded only when nothing activated
and every recorded reason says provenance was never on offer; any fault
keeps the taint. An allow-list of the single observed reason would have
re-tainted the other genuine absences — a registry born without a
catalog, a durable row nobody recorded, a client tool that never
reported.
* fix(provenance): relax to unrecorded only for the dedicated absence reasons
Second review finding, accepted: the originating-fault set assigns
report ownership, not absence semantics, and the two are not the same
split. value-provenance-filter-incomplete is warn-level because its
underlying fault already error-logs inside the staged source registry —
yet it latches precisely when real entries were decrypted in-process
and could not be narrowed to the value, plaintext in flight that never
activated. Gating the file-write relaxation on "not a fault" let that
latch stamp unrecorded.
The registry now owns a dedicated absence set with the stronger
contract membership requires: provenance was never on offer AND no
secret material transited the latching context. An absent or
declared-incomplete envelope carries no entries by schema, a registry
born without a catalog or a persisted log never handled material, a
durable-unknown latch fires before importing anything, and the
inherited markers never occur alone. The write decision relaxes only
when nothing activated and every recorded reason is in that set; an
empty reason list keeps the taint. The fault predicate from the
previous commit is superseded and removed.
0 commit comments