Skip to content

fix(graph-db): log the drifting corruption verdict at error level instead of staying silent - #4574

Merged
ScriptedAlchemy merged 3 commits into
ScriptedAlchemy:masterfrom
spa5k:fix/corrupt-store-drift-visibility
Oct 27, 2026
Merged

ScriptedAlchemy merged 3 commits into
ScriptedAlchemy:masterfrom
spa5k:fix/corrupt-store-drift-visibility

Conversation

@spa5k

@spa5k spa5k commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Logging half of #4571.

Problem

recover_deterministically_corrupt_container_with refuses deletion when the verification open reports a different fault than the first verdict ("hardware-shaped", the module's words). That refusal is terminal for the container: nothing is deleted, nothing is rebuilt, and every later open repeats the verdict — with no operator-visible event. The store looks healthy from the outside; only a leftover .grafeo.corruption-lock hints at it. On one machine, three containers sat in this state for 4–10 days while callers retried forever.

Change

The drifting-fault refusal now emits one error-level event before returning:

event=store_corrupt_not_deterministic container=<path> first_fault=… second_fault=…
"…deletion refused. This store stays corrupt until an operator acts: move the medium,
 or rebuild the project store from its canonical replay authorities."

No behavior change otherwise — deletion still refuses, the typed Corrupt verdict is unchanged, and the existing corrupt-store tests (7/7) stay green. Surfacing this state in tracedecay status/doctor stays tracked in #4571.


Devin Review

A drifting fault (the second open reports different bytes than the
first) is terminal and silent: nothing is deleted, nothing is rebuilt,
and every later open repeats the verdict. Three containers sat in that
state for 4-10 days on one machine, distinguishable from healthy only
by a leftover lock file.

The refusal now logs one error-level event naming the container, both
faults, and the operator action.

Half of ScriptedAlchemy#4571; surfacing the state in status/doctor stays tracked
there.
@changeset-bot

changeset-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 93096fd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

The drifting-fault refusal now has a log-coverage assertion: the
operator event fires exactly once per decision. The comment states the
general invariant without the incident anecdote. Adds the runtime-core
test-helpers dev-dependency for the tracing capture.
@spa5k

spa5k commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Both findings addressed in 1ecd052: the drifting-fault test now asserts the store_corrupt_not_deterministic event fires exactly once (runtime-core test-helpers added as a dev-dependency for the tracing capture), and the production comment states the general invariant without the incident anecdote. Corrupt-store tests 7/7.

The drifting-corruption test links tracedecay-runtime-core as a
dev-dependency; the Bazel test targets did not carry the label, so the
unit_test binary failed with E0433.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ScriptedAlchemy
ScriptedAlchemy merged commit 0d7c88d into ScriptedAlchemy:master Oct 27, 2026
6 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants