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
Runtime-witness persistence loses the evaluated-vs-not-evaluated distinction #331
Not looking and looking and finding nothing are different outcomes, and collapsing them is how a monitoring pipeline learns to report health it never measured.
The persistence layer then collapses exactly that distinction. A refused attach writes noruntime.json at all, so once the process has exited the durable record is:
artifact present → some evaluated outcome
artifact absent → not_evaluated
OR never invoked
OR runner died before invocation
OR the run happened but persistence failed
OR the artifact was produced and lost in transit
OR an older format nothing reads any more
Absence has too many preimages to carry meaning. The process contract distinguishes three states; the storage contract merges two of them back together and adds four more, so the guarantee the exit codes were designed to provide does not survive the end of the process.
Refusing to write a verdict that was never earned is correct and should stay. The defect is using file-absence as the representation of "not evaluated", rather than recording it.
Invariant
Absence of a record means no durable knowledge, never a semantic outcome.
Acceptance
Every attempted witness evaluation leaves a durable execution-state record.
observed observation scope required
clean observation scope required
not_evaluated reason required (refused attach, unreadable target,
usage error, ...)
error error classification required
missing record has no semantic interpretation
A clean with no recorded scope is a malformed record, not a weak one — it should take the same handling path as a schema violation, not be read as a quieter version of not_evaluated.
Scope
A representation defect in the runtime-witness lane, self-contained. It needs no new analysis capability, no change to the exit-code contract (which is right as it stands), and no change to what the witness measures — only that the state the process already computes survives into storage.
Not related to #270, which covers generating witness evidence rather than how its execution state is recorded.
Оба PR ссылались на этот issue через Refs, а не Closes, — намеренно. Изменение живёт в двух репозиториях, и автозакрытие сработало бы от первого же смерженного PR, то есть объявило бы issue решённым в момент, когда была готова ровно половина. Порядок при этом обязателен и соблюдён: сначала consumer, потом producer. В обратном порядке возникает окно, в котором producer уже пишет новую форму записи, а consumer ещё читает not_evaluated-прогон как «ничего не удержано» — то есть ровно тот дефект, который этот issue и описывает, только с более убедительным на вид артефактом.
Что теперь верно. Runtime-свидетель различает четыре состояния — observed, clean, not_evaluated, error — и verdict/retained появляются только у оценённых. Отказ атакуется по стадии, на которой он произошёл (open-target / create-runtime / walk), а refused-attach резервируется за отказом на открытии цели с наблюдаемой политикой, записываемой как policy_in_force — наблюдение, а не доказанная причина. На стороне потребителя нечитаемая запись отвергается через UnusableRuntimeRecord, а прежние выходные файлы стираются до любого пути выхода, так что отказ не оставляет стоять старое ложно-приписанное evidence.
Оставшийся хвост, если понадобится: docs/runtime-witness-operations.md § «The durable record» описывает таблицу состояний, а denied-attach gate в CI утверждает, что отказ записан, а не что артефакт отсутствует.
Activity
fix(runtime-witness): attribute a failure to the stage it happened at
fix(runtime): a run without a result must not leave the last one stan…
docs(runtime-witness): say what refused-attach records, not what it p…
Merge pull request #333: fix(runtime-witness): record the execution s…
PhysShell commentedon Aug 18, 2026
Закрываю вручную: обе половины в
main.a11ae7e7e06e6b9fОба PR ссылались на этот issue через
Refs, а неCloses, — намеренно. Изменение живёт в двух репозиториях, и автозакрытие сработало бы от первого же смерженного PR, то есть объявило бы issue решённым в момент, когда была готова ровно половина. Порядок при этом обязателен и соблюдён: сначала consumer, потом producer. В обратном порядке возникает окно, в котором producer уже пишет новую форму записи, а consumer ещё читаетnot_evaluated-прогон как «ничего не удержано» — то есть ровно тот дефект, который этот issue и описывает, только с более убедительным на вид артефактом.Что теперь верно. Runtime-свидетель различает четыре состояния —
observed,clean,not_evaluated,error— иverdict/retainedпоявляются только у оценённых. Отказ атакуется по стадии, на которой он произошёл (open-target/create-runtime/walk), аrefused-attachрезервируется за отказом на открытии цели с наблюдаемой политикой, записываемой какpolicy_in_force— наблюдение, а не доказанная причина. На стороне потребителя нечитаемая запись отвергается черезUnusableRuntimeRecord, а прежние выходные файлы стираются до любого пути выхода, так что отказ не оставляет стоять старое ложно-приписанное evidence.Оставшийся хвост, если понадобится:
docs/runtime-witness-operations.md§ «The durable record» описывает таблицу состояний, а denied-attach gate в CI утверждает, что отказ записан, а не что артефакт отсутствует.Generated by Claude Code