Repository navigation
fix(installcoord): name drifted guidance assets with content drift first - #435
Conversation
Fleet review (glm)Lens: requirements + adversarial. The diff fixes the #384 blocking finding at its named location: recordedDriftAssets checks content drift (!owned || ownerHash != slot.SHA256) before ModeDrift, so a combined content+mode drift reports ActorGuidanceContentDrift with ModeDrift as the independent flag, and mode-only drift still reports ActorGuidanceModeDrift — mirroring the conflict-stage invariant. The combined evidence-stage case is pinned by a table case asserting cause, both modes, and ModeDrift=true; mode-only and content-only cases are pinned unchanged. The refusal record is detached (defensive copy verified by mutation test), a successful preflight carries no refusal, and refusals write nothing (tree-compared). Early evidence refusals on invalid units degrade to zero named assets rather than panicking or inventing paths. No blocking findings. No findings. Verdict: ready to merge |
Post-merge QA (glm)Lens: requirements + adversarial. The diff fixes the #384 blocking finding at its named location: recordedDriftAssets checks content drift (!owned || ownerHash != slot.SHA256) before ModeDrift, so a combined content+mode drift reports ActorGuidanceContentDrift with ModeDrift as the independent flag, and mode-only drift still reports ActorGuidanceModeDrift — mirroring the conflict-stage invariant. The combined evidence-stage case is pinned by a table case asserting cause, both modes, and ModeDrift=true; mode-only and content-only cases are pinned unchanged. The refusal record is detached (defensive copy verified by mutation test), a successful preflight carries no refusal, and refusals write nothing (tree-compared). Early evidence refusals on invalid units degrade to zero named assets rather than panicking or inventing paths. No blocking findings. No findings. Verdict: clean |
Post-merge QA (deepseek)Lens: evidence + test design. The merged code implements the #384 acceptance criterion at the right level: Suggestion (1)
Question (1)
Verdict: clean |
Pull Request
Linked Issue
Refs #384
PR Type
type:featureFeaturetype:bugBug fixtype:docsDocumentationtype:refactorRefactoringtype:choreMaintenancetype:breaking-changeBreaking changeSummary
First of two PRs that replace #383, which grew to 661 lines, over the 400-line review budget. This one holds the
installcoordcore: guidance evidence names each drifted asset with its cause, and content drift takes precedence over mode drift (the #384 finding). Mode drift stays an independent flag, consistent with the conflict path.Changes
internal/installcoord/actor_guidance.go: drifted-asset reporting from feat(cli): name failing assets and drift cause on actor_guidance_unverified refusals #383, withrecordedDriftAssetschecking content drift (!owned || ownerHash != slot.SHA256) beforeModeDrift; mode-only drift still reportsmode_drift.internal/installcoord/actor_guidance_test.go: feat(cli): name failing assets and drift cause on actor_guidance_unverified refusals #383's table tests plus an evidence-stage case with both content and mode drift; every mode-drift asset must carry its observed and canonical modes.Focused Tests
Cause:0x2 ... want cause 1go test ./internal/installcoord -count=1go vet ./...;go test ./... -count=1Not tested: the CLI output of the refusal; that surface lands in the follow-up PR.
Failed or not done: none.
Warnings: the second PR (CLI and docs) depends on this one. #383 will be closed as superseded once both are open.
Runtime Harness
N/A: package change covered by package tests.
Rollback
Revert the single commit; the follow-up PR must be reverted first if it has landed.
Chain Dependencies / Out of Scope
Checklist
status:approved.type:*label is applied.