docs(v1.100 PR-24): contract seed v1 — authority restoration policy engine#493
Merged
docs(v1.100 PR-24): contract seed v1 — authority restoration policy engine#493
Conversation
…ngine Locks the PR-24 design surface before any implementation code lands. Per pre-commit review discipline: contract-first, not code-first. Scope: authority restoration policy engine — decision only, no execution. Three outputs: PROCEED / REFUSE / REQUIRE_EXPLICIT_INTENT. No fourth. Locked decisions captured in this seed: - Lattice v2 with top-down precedence rule (classifier hard-stops → input validity → prior-record gates → panel gates → proceed) - NoRecord + --restore → REQUIRE_EXPLICIT_INTENT (no hidden default target when operator supplies restore flag against empty record) - Legacy prior records missing ActiveAtInstall classify as Incomplete (no defaulting, no inference) - Staleness window fixed at 365 days in PR-24; configurability deferred - StateRestoreDecided explicitly constrained: policy-only, non-terminal for apply semantics, excluded from update-history.json, not evidence that restoration happened - Filesystem purity enforced by static scan + exec-trace; no syscall-level enforcement claimed - New terminal states (StateRestoreRefused, StateRestoreIntentRequired) and exit codes (ExitRefused=5, ExitIntentRequired=6) - Four new CI gates in G4-RESTORE-* namespace - Merge-blocking real-host matrix: lab2 + lab4 clean-state decision proof only; dangerous branches are fixture-only No Go code, no CI workflow changes, no state-machine changes in this commit. Implementation authorization is a separate user approval step. 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 |
Owner
Author
Review frame for PR-24 contract seed (PR #493)This PR is policy-only. It introduces no execution logic, no mutation, and no implementation scaffolding. It exists solely to freeze restoration-policy semantics before code begins. Please evaluate against these three guardrails: 1. No semantic drift
2. No scope bleed
3. Clarity on intent asymmetry
Out of scope for this PR
Approval of this PR = approval of the locked lattice + precedence + forbidden surfaces + exit semantics. Implementation will be proposed in a separate PR after explicit authorization. |
Owner
Author
|
PR ready for review. Contract seed only (policy, no implementation). Guardrails defined in top comment. |
…ntic Two wording-only edits per auditor review of PR #493. Neither changes lattice behavior; §5 top-down precedence already produces the correct outcome for the cells they describe. 1. §6 Group 5 wording updated — panel-auto handling spans Groups 3 and 4, not only Group 3. Previously Group 5's explanatory sentence only referenced Group 3; it now explicitly mentions the absolute refusal under AmbiguityOrphanNFTBan (§6 Group 4.3). 2. §6 Group 4 precedence clarifier added — one line between the Group heading and 4.1 stating: 4.1 and 4.2 match on prior state for flags {none, --restore}; 4.3 matches --panel-auto-takeover regardless of prior. Resolves a potential reader ambiguity between 4.1 and 4.3 when both flags could theoretically apply. Amendment history updated to record these as v1 auditor-wording clarifications, separate from the original three seed corrections. No Go code, no CI changes, no state-machine changes. Still policy-only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
itcmsgr
added a commit
that referenced
this pull request
Apr 20, 2026
Implements the pure decision engine defined by the merged contract seed (PR #493). PR-24 is POLICY ONLY — no kernel, service, or filesystem mutation, no history write, no restore execution code. Scope (locked per seed §2): - internal/installer/restore/ decision engine - --mode=restore CLI dispatcher - state-machine entries: StateRestoreRefused, StateRestoreIntentRequired (terminal, non-failed, non-apply-terminal); StateRestoreDecided (non-terminal handoff marker) - exit codes: ExitRefused=5, ExitIntentRequired=6 (distinct from generic failure to enable scriptability) - 4 CI gates in G4-RESTORE-* namespace Lattice (seed §6 v2 + locked amendments): - Top-down precedence: classifier hard-stops → input validity → prior-record integrity → panel gates → proceed decisions - AuthorityNFTBan / AuthorityExternal / AmbiguityConflictExternal → REFUSE absolutely (no flag may override) - NoRecord + --restore → REQUIRE_EXPLICIT_INTENT (locked amendment: no implicit target) - NoRecord + --panel-auto-takeover + panel → PROCEED (panel-auto carries its own target) - Complete + ActiveAtInstall=false → REQUIRE_EXPLICIT_INTENT (any flag; restore semantics ambiguous between preserve-inactive and activate) - Stale / Incomplete → REQUIRE_EXPLICIT_INTENT - Orphan + --panel-auto-takeover → REFUSE (panel-auto must not fire over nftban residue) - Staleness window fixed at 365 days (seed §3.B; configurability is a deferred follow-up) Output is a closed enum of three values: PROCEED, REFUSE, REQUIRE_EXPLICIT_INTENT. No fourth output; no default branch; no fallthrough. Unreached code paths panic as contract-regression guards. Tests (internal/installer/restore/engine_test.go): - Rule-path coverage matrix — every Rule* constant must have a fixture - Determinism — reflect.DeepEqual on two back-to-back evaluations - Closed-enum output invariant - Locked-amendment guards (NoRecord + --restore in both AuthorityNone and AmbiguityOrphanNFTBan paths) - Hard-stop dominance — Group 1 refuses under every flag / prior / panel combination (4 * 5 * 2 * 3 = 120 cells per hard-stop) - Orphan + panel-auto refusal under every prior state CI gates (.github/workflows/ci-restore-canonization.yml): - G4-RESTORE-NO-IMPLICIT-EXEC — static scan for forbidden symbols (exec.*, nft/iptables/systemctl literal calls, service helpers, os.Create/WriteFile/Rename/Remove/Mkdir, rebuild/switchop/services mutation helpers) - G4-RESTORE-DECISION-CORRECTNESS — runs the full fixture matrix including rule-path coverage assertion - G4-RESTORE-REFUSAL-INTEGRITY — structural check that restore package has no executor dependency AND dispatcher does not import mutation- capable packages - G4-RESTORE-DETERMINISM — two independent test runs; normalized diff must be empty Dispatcher (cmd/nftban-installer/restore_decide.go): - Classifies authority via uninstall.Classify (single source of truth) - Probes prior-record via uninstall.Probe (PR-P2-1 hardened schema) - Reduces uninstall.PriorRecordState + 365-day window → restore.PriorState - Detects panel via detect.DetectPanel - Assembles DecisionInput; calls restore.Decide (pure) - Preflight errors (malformed record, Ambiguous invariant violation) short-circuit to ExitFatal WITHOUT emitting a lattice output — keeps the three-output space closed (seed §9) - Transitions state file to terminal (Refused / IntentRequired) or non-terminal (Decided) - history.json write skipped: IsApplyTerminal=false for all three states + main.go gate now also excludes cfg.mode=="restore" as belt-and-braces defense No real-host mutation. Decision-only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
27 tasks
5 tasks
itcmsgr
added a commit
that referenced
this pull request
Apr 27, 2026
#510) Appends the PR-25 execution contract to internal/installer/restore/ contract.md as a new "PART II — PR-25 execution contract" section (§§16-29). This is the doc-only first PR of the PR-25 two-PR split, mirroring the PR-24 PR #493 → PR #494 pattern. The implementation PR opens in a separate branch after this one merges. Origin: The contract is a faithful normalization of the locked Q1-Q5 design decisions (recorded 2026-04-20 during PR-24 freeze Day 0 via the §12 protocol: Stage 1 scope classification + Stage 2 five-field answer + LOCK/REVISE/REJECT review). The v0 staging sheet (memory/project_pr25_contract_sheet_v0.md) was reviewed and locked 2026-04-27 prior to opening this PR. Locked rule applied: "Normalize, do not expand." Every clause in §§16-29 traces back to a Q1-Q5 lock or to V1100 contract §8. No design decisions were made in this PR. Section map: - §16 Purpose - §17 Scope (Option A) + 2 named invariants - §18 TargetAuthority concretization (Q2) - §19 StateRestoreDecided downstream meaning (Q3) - §20 Panel-auto target consistency (Q4) - §21 Post-restore verification split (Q5) - §22 State terminals + exit codes (candidates) - §23 Execution shape (V1100 §8 ordered) - §24 Inputs PR-25 may consume - §25 Forbidden behaviors (consolidated) - §26 Cross-lock consistency - §27 What this contract does NOT contain (intentional) - §28 Merge-blocking real-host matrix (code phase) - §29 Reviewer checklist (code phase) Verified live code anchors (2026-04-27): - knownFirewallType set {ufw, firewalld, iptables, csf} at internal/installer/uninstall/prior.go:278-284 - writeHistory gate excluding cfg.mode == "restore" at cmd/nftban-installer/main.go:132 - Exit-code constants ExitCommitted=0/ExitFatal=4/ExitRefused=5/ ExitIntentRequired=6 at internal/installer/state/machine.go:149-155 §1-§15 (PR-24 decision contract) are untouched. Out of scope (locked): - No code in this PR. PR-25 implementation is the next PR (feat/v1.100-pr25-restore-execution). - No expansion of Q1-Q5 lock content. - PR-26 contract stays out of scope. Lifecycle completion lane (PR-25..PR-30) remains explicitly OPEN but is now mid-re-entry: contract is the first deliberate step. 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.
This PR is a contract-seed only. It introduces no execution logic, no mutation, and no policy engine implementation. Its sole purpose is to freeze PR-24 restoration-policy semantics before code begins.
Scope
internal/installer/restore/contract.md(338 lines)Purpose
Lock the PR-24 design surface before any implementation code lands. Approval of this seed is the merge gate before the code phase begins.
Locked decisions captured in the seed
Lattice (normative, §6)
Lattice v2 with top-down precedence rule:
AuthorityNFTBan,AuthorityExternal,AmbiguityConflictExternal) → alwaysREFUSE--panel-auto-takeoverwithout panel;--restore+--panel-auto-takeovertogether) →REFUSE--panel-auto-takeover)No later rule may override an earlier refusal. Earlier-rule output is final.
Locked amendments (applied during review before this commit)
NoRecord + --restore → REQUIRE_EXPLICIT_INTENT(notPROCEED).--restorecarries an implicit target; withNoRecordthe target does not exist. Applied in both Group 3.3 (AuthorityNone) and Group 4.2 (AmbiguityOrphanNFTBan).ActiveAtInstallclassify asIncomplete. No defaulting totrue, no defaulting tofalse, no inference.StateRestoreDecidedis constrained: policy-only, non-terminal for apply semantics, excluded fromupdate-history.json, not evidence that restoration happened.Output discipline (locked)
Exactly three outputs:
PROCEED/REFUSE/REQUIRE_EXPLICIT_INTENT. No fourth. No default. No "soft proceed."State-machine + exit codes (to be implemented later)
StateRestoreRefused,StateRestoreIntentRequiredExitRefused=5,ExitIntentRequired=6StateRestoreDecided(forPROCEEDhandoff only)Forbidden surfaces (locked)
nft/iptables/ip)systemctl)update-history.jsonuntouched)CI gates (to be implemented later)
Four new
G4-RESTORE-*gates: decision-correctness, refusal-integrity, no-implicit-exec, determinism.Merge-blocking real-host matrix (to be run at implementation time)
lab2(Ubuntu/DEB): cleanAuthorityNone + NoRecord→REQUIRE_EXPLICIT_INTENTlab4(AlmaLinux/RPM): sameAuthorityExternal,AmbiguityConflictExternal,AmbiguityOrphanNFTBan, weak-record, panel-driven) are fixture-only — simulating them at kernel level would violate the no-mutation gate via the test harness.Test plan
This PR has no runtime behavior to test. CI validates:
No Go build, no Go tests, no state-machine diffs should appear in this PR.
Follow-up (tracked in §15 of the seed)
ActiveAtInstallpopulation in new prior-record writesReview gate
Merging this seed indicates approval of the locked lattice, forbidden-surfaces list, state-machine contract, and exit-code contract. After merge, a separate authorization step gates the implementation PR. The implementation PR must implement exactly this contract — nothing more, nothing less.
🤖 Generated with Claude Code