Conversation
…sification + required RecordedAt/InstallerVersion/ActiveAtInstall Pre-PR-23 blocker #1. Strengthens prior-authority records so PR-24 restore-enforcement can rely on them without inheriting weak semantics. **Scope-locked per repair contract:** - schema additions (recorded_at, installer_version, *bool active_at_install) - 5-state classification (NoRecord / Malformed / Incomplete / UsableActive / UsableInactive) - backward-safe degradation of old weak records to Incomplete - render/JSON symmetry — PriorActiveAtInstall field + render line - tests + contract/doc updates only - NO restore execution, NO lifecycle mutation, NO signature/checksum framework, NO unrelated refactors ## Schema additions (prior.go) ```go type PriorRecord struct { SchemaVersion string FirewallType string RecordedAt *time.Time // NEW — required for usable InstallerVersion string // NEW — required for usable ActiveAtInstall *bool // CHANGED from bool — tri-state: // nil = record writer did not commit // &true = prior was active // &false = prior was explicitly inactive } ``` ## 5-state classification | State | Condition | |---|---| | NoRecord | no artifact on disk | | RecordMalformed | JSON does not parse (was folded into Incomplete before) | | RecordIncomplete | parses but required field missing/invalid | | RecordUsableActive | all required + ActiveAtInstall=&true | | RecordUsableInactive | all required + ActiveAtInstall=&false | `PriorRecordState.IsUsable()` helper returns true for both Usable* variants — RestoreAuthorized uses it. `IncompleteReason` enum provides machine-consumable reason codes: Unreadable, SchemaMismatch, MissingFirewallType, UnknownFirewallType, MissingRecordedAt, MissingInstallerVersion, MissingActiveAtInstall. ## Backward-safety Older records from before PR-P2-1 that lack recorded_at / installer_version / explicit active_at_install are intentionally reclassified as RecordIncomplete. Migration-style silent upgrade is forbidden. Test `TestProbe_OldStyleRecord_DegradesToIncomplete` falsifies this path directly. > **Migration note:** Older prior-authority records may now classify > as Incomplete by design. This is intentional safety tightening, not > a functional regression. Records produced by the install-side writer > that lands alongside PR-23 will carry all required fields. ## Plan integration (plan.go) - `Plan.RestoreAuthorized` now uses `PriorState.IsUsable()` — both Usable variants authorize, active/inactive is separate dimension - new `Plan.PriorIncompleteReason` surfaces typed reason in JSON - new `Plan.PriorActiveAtInstall *bool` surfaces the tri-state (nil = unknown, &true/&false = explicit) — PR-24 uses this to decide whether restoration needs a second confirmation prompt - new Render line `Prior firewall at install : active|inactive` only emitted when record is usable — no defaulted values - new warning when restore requested on UsableInactive record ## Tests Added (uninstall_test.go): - `TestProbe_RecordUsableActive` (rename of TestProbe_RecordUsable) - `TestProbe_RecordUsableInactive` — active_at_install=false path - `TestProbe_RecordMalformed_BadJSON` — split from Incomplete - `TestProbe_RecordIncomplete_MissingRecordedAt` - `TestProbe_RecordIncomplete_MissingInstallerVersion` - `TestProbe_RecordIncomplete_MissingActiveAtInstall` - `TestProbe_OldStyleRecord_DegradesToIncomplete` — backward-safety - `TestBuildPlan_Restore_UsableInactive_AuthorizedButWarned` - All existing tests updated: fixtures carry all 5 required fields; JSON strings updated to `record_usable_active` Every Incomplete* test also asserts the specific IncompleteReason (not just the state) so regressions attribute cleanly. ## Doc update (contract.md) Added "PR-P2-1 hardening" section under the prior-authority record definition: describes the 5 states, what "usable" now means, explicit backward-safety rule. ## Non-goals (strict scope lock) - no restore execution - no lifecycle mutation - no signature/checksum framework - no unrelated refactors Refs: internal/installer/uninstall/contract.md §"Pre-PR-23 blockers" Authorization: locked repair contract (pre-PR-23 Phase 2 item #1) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
itcmsgr
added a commit
that referenced
this pull request
Apr 20, 2026
PR-P2-1 (prior-authority record hardening) merged as 3b83403. The blocker table in internal/installer/uninstall/contract.md now shows item 1 struck through with explicit LANDED status + merge SHA. Items 2-6 remain pending; each is still its own bounded PR with micro-contract + falsifiable proof test per the approved sequencing. No code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
itcmsgr
added a commit
that referenced
this pull request
Apr 20, 2026
…uckets Per review feedback: the table previously mixed code-semantic changes with CI/gate additions, and said "all six items" when #1 is already landed. Restructured for clarity: - Landed bucket — #1 (prior-authority hardening, PR #484) - Behavioral / semantic blockers — #2 (external-firewall detection unification), #6 (payload integrity minimum checks) - Assurance / gate blockers — #3 (kernel/service snapshot CI), #4 (exec-trace CI), #5 (auto-elevate shim removal gate) Wording tightened: "PR-23 starts only after all remaining pre-PR-23 blockers merge" instead of "all six items below." Also flagged that PR-24/25/26 ordering is preferred, not dogmatic — restore enforcement may expose facts that affect artifact-removal semantics. No code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
itcmsgr
added a commit
that referenced
this pull request
Apr 20, 2026
…uckets + mark blocker #1 LANDED (#485) * docs(v1.100): mark pre-PR-23 blocker #1 LANDED (PR #484) PR-P2-1 (prior-authority record hardening) merged as 3b83403. The blocker table in internal/installer/uninstall/contract.md now shows item 1 struck through with explicit LANDED status + merge SHA. Items 2-6 remain pending; each is still its own bounded PR with micro-contract + falsifiable proof test per the approved sequencing. No code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(v1.100): split pre-PR-23 blockers into behavioral vs assurance buckets Per review feedback: the table previously mixed code-semantic changes with CI/gate additions, and said "all six items" when #1 is already landed. Restructured for clarity: - Landed bucket — #1 (prior-authority hardening, PR #484) - Behavioral / semantic blockers — #2 (external-firewall detection unification), #6 (payload integrity minimum checks) - Assurance / gate blockers — #3 (kernel/service snapshot CI), #4 (exec-trace CI), #5 (auto-elevate shim removal gate) Wording tightened: "PR-23 starts only after all remaining pre-PR-23 blockers merge" instead of "all six items below." Also flagged that PR-24/25/26 ordering is preferred, not dogmatic — restore enforcement may expose facts that affect artifact-removal semantics. No code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <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.
Pre-PR-23 blocker #1 of 6. Strengthens prior-authority records so PR-24 restore-enforcement can rely on them without inheriting weak semantics.
Migration note (required per authorization)
Records produced by the install-side writer landing with PR-23 will carry all required fields. Until then, existing fixtures / local test records without
recorded_at/installer_version/ explicitactive_at_installwill be reclassified asIncomplete— this is the explicit backward-safety path.Scope-locked (per repair contract)
recorded_at,installer_version,*bool active_at_install)NoRecord/Malformed/Incomplete/UsableActive/UsableInactive)IncompletePriorActiveAtInstallfield + render lineNot in scope:
What "usable" now means
Record is usable only if: JSON parses, schema matches, firewall type known,
recorded_atpresent + parseable,installer_versionpresent, ANDactive_at_installis explicitly committed (pointer non-nil — not just Go's zero-value false). Usable does not imply "restore/re-enable now" — PR-24 defines its own authorization rules on top.5-state classification
NoRecordRecordMalformedRecordIncompleteIncompleteReasonfor why)RecordUsableActiveactive_at_install=trueRecordUsableInactiveactive_at_install=falseIncompleteReasonenum:Unreadable/SchemaMismatch/MissingFirewallType/UnknownFirewallType/MissingRecordedAt/MissingInstallerVersion/MissingActiveAtInstall. Machine-consumable so downstream tooling doesn't have to substring-match notes.Plan integration
Plan.RestoreAuthorizednow usesPriorState.IsUsable()— bothUsable*variants authorize at this layerPlan.PriorActiveAtInstall *boolsurfaces the tri-state (nil = unknown, &true/&false = explicit)Plan.PriorIncompleteReasonsurfaces typed reason in JSONPrior firewall at install : active|inactive— only emitted when record is usable (no defaulted values)UsableInactiverecord: "restoration would re-enable a firewall the operator was not running"Tests (all in
internal/installer/uninstall/uninstall_test.go)Added:
TestProbe_RecordUsableActive(rename + tightened) +TestProbe_RecordUsableInactiveTestProbe_RecordMalformed_BadJSON(split from Incomplete)TestProbe_RecordIncomplete_MissingRecordedAt/MissingInstallerVersion/MissingActiveAtInstall— each asserts bothStateAND typedIncompleteReasonTestProbe_OldStyleRecord_DegradesToIncomplete— explicit backward-safety regression guardTestBuildPlan_Restore_UsableInactive_AuthorizedButWarnedAll existing tests updated: fixtures carry the 5 required fields; JSON assertions use
record_usable_active.Doc update
New "PR-P2-1 hardening" section in
internal/installer/uninstall/contract.mdunder the prior-authority record definition.Acceptance checklist (per repair contract §5)
active_at_install=falseis explicit and test-coveredrecorded_atandinstaller_versionare required for usableTest plan
Build & Testgreen — all unit tests pass including 8 new probe testsci-uninstall-canonizationmatrix green — all 3 modes' existing tests still pass (render/JSON/plan structural checks)🤖 Generated with Claude Code