fix(libvirt): record suppressed native failures on the operator side - #1163
Open
doublewhy wants to merge 4 commits into
Open
fix(libvirt): record suppressed native failures on the operator side#1163doublewhy wants to merge 4 commits into
doublewhy wants to merge 4 commits into
Conversation
The libvirt backend deliberately collapses native errors into value-free portable diagnostics, but that left zero field observability: 25 broad except-Exception/BaseException sites discarded the native failure entirely, so a failing real-libvirt run could not be explained. Add a backend-local logger (raes_backend_libvirt._observability, named 'raes_backend_libvirt', no handlers -- silent unless the embedding application configures logging) and record every suppressed native failure at DEBUG with the enclosing operation and full exc_info before it collapses. The portable boundary is unchanged: diagnostics stay value-free and no native detail crosses it. _verify_and_finalize moves to techvault_native/_finalize.py (the existing _define.py driver-function pattern) to keep _driver.py under the 500-line cap after instrumentation. Verification: full hermetic suite green with the coverage gate; libvirt/techvault-focused tests (366) pass; ruff clean; check_repo_policy pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The PR quality gate counted the new debug lines in never-exercised exception arms as uncovered new code (74% vs the 80% floor) and flagged _verify_and_finalize's eighth parameter after the relocation. test_libvirt_failure_observability.py now forces all 25 instrumented collapse sites with raising fakes, pinning both halves of the contract per arm: the portable behavior is unchanged (value-free diagnostic, None, or empty result) and the suppressed native failure is recorded on the raes_backend_libvirt logger at DEBUG with the operation named and exc_info attached. Every instrumented line is now covered by the hermetic suite. _verify_and_finalize takes the envelope/configuration digests as one binding_digests tuple, returning the signature to seven parameters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A ruff --fix pass ran without the project working directory, so its first-party classification differed from the verify static lane and it rewrote import blocks in sixteen unrelated test modules. Those edits rode along in the coverage commit and the static lane rejects them. Restore every unrelated test module to its dev content; the only test change this branch carries is the new observability suite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sonar S9073 requires one condition per assert so a failure names the exact clause; split the eight and-joined assertions accordingly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plain-language summary
except Exception/BaseExceptionsites discarded the native failure entirely. Only 3 of 787 production files importlogging, andraes_backend_libvirthad zero logging calls, so a failing real-libvirt run in the field could not be explained.Summary
raes_backend_libvirt/_observability.py: one package logger (logging.getLogger("raes_backend_libvirt"), no handlers — silent unless the embedding application configures it) and a shared message format.deployment.py×6,techvault_native/_driver.py×6,_define.py×4,drivers/libvirt/_native.py×3,techvault_lifecycle.py×2,_initramfs.py×2,guest_certified_driver.py×1,_preflight.py×1) now binds the exception and emitsDEBUGwith the enclosing operation andexc_infobefore collapsing to its portable diagnostic. Narrow control-flow excepts (KeyError,ValueError, …) are deliberately untouched._verify_and_finalizemoves totechvault_native/_finalize.pyas a driver-taking function (the established_define.pypattern) so_driver.pystays under the 500-line cap after instrumentation.Design note
The value-free posture (native errno/strerror never crossing the portable boundary) is preserved exactly: diagnostics are unchanged, and DEBUG logs are operator-local. If a different level or logger topology is preferred, it's a two-line change in
_observability.py.Verification
tools/check_repo_policy.pypass (including the 500-line cap).🤖 Generated with Claude Code