Skip to content

docs(v1.100 Amendment 3): G1/AmbiguityConflictExternal narrow split for orphan-CSF-on-DA — DOC SEED#522

Merged
itcmsgr merged 1 commit intomainfrom
amendment-3-doc-seed-ambiguity-conflict-external-csf-orphan
Apr 29, 2026
Merged

docs(v1.100 Amendment 3): G1/AmbiguityConflictExternal narrow split for orphan-CSF-on-DA — DOC SEED#522
itcmsgr merged 1 commit intomainfrom
amendment-3-doc-seed-ambiguity-conflict-external-csf-orphan

Conversation

@itcmsgr
Copy link
Copy Markdown
Owner

@itcmsgr itcmsgr commented Apr 29, 2026

Summary

  • Authority gap discovered during dns2 Gate B run Update nftban_init.sh #1 (2026-04-29T12:33:02Z): the classifier returns AmbiguityConflictExternal + external=csf on a real DirectAdmin host with a real CSF install where Gate A canonical takeover succeeded, because csf-residue (/etc/csf/, /usr/sbin/csf.disabled, lfd.service) is intact post-canonical-install per §17.2 invariant. The lattice correctly refused at the locked G1/AmbiguityConflictExternal row.
  • Amendment 2's G1/AuthorityNFTBan/OrphanProceed was scoped to the non-ambiguous AuthorityNFTBan classifier state. On srv3 (no real csf install) the classifier returned that. On dns2 (real csf install + canonical takeover) the classifier returns AmbiguityConflictExternal. Same operator intent, different lattice path.
  • Auditor disposition (2026-04-29) approved Option A (narrow lattice extension mirroring Amendment 2). Options B (manual residue cleanup) and C (classifier semantic patch within PR-26 scope) rejected.
  • Appends Part VI (§§62–69) to internal/installer/restore/contract.md. Doc-only. Single file. 222 insertions.

What changes

  • §62: pinned sentence + scope + invariants + new INV-AMD3-CONFLICT-EXTERNAL-CSF-NARROW
  • §63: G1/AmbiguityConflictExternal split entirely within Group 1; §5 precedence preserved
  • §64: evidence predicate (§54/§64 combined; §54 untouched, predicate scoped to §62 entry conditions; row E.2 reframed, row E.12 omitted, all other rows unchanged)
  • §65: forbidden behaviors (extends §25, §34, §38.2, §55)
  • §66: test requirements (unit tests, regression tests, CI grep gates)
  • §67: 15-row test matrix (including AMD3-13 empty-external defensive guard, AMD3-14 rule-label assertion, AMD3-15 multi-external defensive guard)
  • §68: sequencing recommendation (10 sequential gates to PR-26 final merge)
  • §69: rejected alternatives (Options B, C, D + any-pre-code-A-mutation rejection)

What is NOT changed

  • internal/installer/restore/engine.go — untouched (code-A's scope, separate PR)
  • internal/installer/restore/engine_test.go — untouched (same)
  • Any other Go file — untouched
  • .github/workflows/*.yml — untouched
  • §54 (Amendment 2's predicate) — untouched; stays scoped to AuthorityNFTBan path
  • Classifier semantic — unchanged
  • §32 11-step mutation ordering — unchanged
  • §32.1 safety-net retention — unchanged
  • §39 / §41 BLOCKING evidence — unchanged
  • INV-PR26-NEW-MUTATION-SURFACES-BOUNDED — preserved (zero new mutation surfaces)
  • INV-PR26-VERIFICATION-IS-PROOF-NOT-DECISION — unchanged
  • INV-AMD2-EXPLICIT-INTENT-IS-NARROW — unchanged

Authoring discipline

  • Auditor pre-draft review (2026-04-29) approved with Deltas 1–3 applied
  • Delta 1 applied at §62.1 (split-entirely-within-Group-1 framing)
  • Delta 2 applied at §64.1 (Amendment 3 does NOT modify §54; introduces separate §54/§64 combined predicate)
  • Delta 3 applied at §67 (15 rows including 3 added defensive-guard rows)

Test plan

  • Auditor pre-merge audit on this doc seed
  • Operator approves merge
  • After merge: open amendment-3-code-A PR implementing the §63 + §64 lattice extension
  • After code-A merges: fresh Tier 1 binary + fresh signoff + Gate B retry pre-execution audit + Gate B retry single invocation on dns2
  • After post-B auditor returns GO: PR-26 final mergeable

🤖 Generated with Claude Code

…or orphan-CSF-on-DA — DOC SEED

Authority gap discovered during dns2 Gate B run #1 (2026-04-29T12:33:02Z):
on a real DirectAdmin host with a real CSF install where Gate A canonical
takeover succeeded, the classifier returns

  Authority=AuthorityAmbiguous + Ambiguity=AmbiguityConflictExternal
  + external=csf

because csf-residue (/etc/csf/, /usr/sbin/csf.disabled, lfd.service unit-file,
etc.) is intact post-canonical-install per §17.2 invariant. The lattice
correctly refused at G1/AmbiguityConflictExternal per the locked §6 Group 1
hard-stop.

Amendment 2's G1/AuthorityNFTBan/OrphanProceed was scoped to non-ambiguous
AuthorityNFTBan; on srv3 (no real csf install) the classifier returned that;
on dns2 (real csf install + canonical takeover) the classifier returns
AmbiguityConflictExternal. Same operator intent, different lattice path.

Auditor disposition (2026-04-29) approved Option A (narrow lattice extension
mirroring Amendment 2). Options B (manual residue cleanup) and C (classifier
semantic patch within PR-26 scope) rejected.

This amendment appends Part VI (§§62–69) to internal/installer/restore/
contract.md:

  §62  pinned sentence + scope + invariants + new INV-AMD3-CONFLICT-EXTERNAL-CSF-NARROW
  §63  G1/AmbiguityConflictExternal split (entirely within Group 1; §5 precedence preserved)
  §64  evidence predicate (§54/§64 combined; §54 untouched, predicate scoped to §62 entry conditions)
  §65  forbidden behaviors (extends §25, §34, §38.2, §55)
  §66  test requirements (unit tests, regression tests, CI grep gates)
  §67  test matrix — 15 rows including AMD3-13 (empty external defensive guard),
       AMD3-14 (rule-label assertion for downstream consumers), AMD3-15 (multi-external defensive guard)
  §68  sequencing recommendation (10 sequential gates to PR-26 final merge)
  §69  rejected alternatives (Options B, C, D + any-pre-code-A-mutation rejection)

Doc-only commit. Single file. No production code change. No CI change. No
engine.go or engine_test.go edit. No §54 modification (Amendment 2's
predicate stays scoped to AuthorityNFTBan). No classifier semantic change.
No §32 ordering change. No new mutation surface. No new state terminal. No
new exit code. No host action.

Code phase opens in a separate amendment-3-code-A PR after this seed merges
and the auditor approves the code-A scope.

dns2 stays in canonical post-Gate-A state until code-A merges + fresh Tier 1
+ fresh signoff + Gate B retry pre-execution audit returns GO. The Gate B
run #1 REFUSE was non-mutating; no R-1 cleanup, no fresh Gate A run, no
snapshot rollback needed.

PR-26 final remains non-mergeable until amendment-3-code-A lands AND Gate B
retry produces StateRestoreExecuted AND post-B auditor returns GO.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@itcmsgr itcmsgr merged commit 8869392 into main Apr 29, 2026
57 checks passed
@itcmsgr itcmsgr deleted the amendment-3-doc-seed-ambiguity-conflict-external-csf-orphan branch April 29, 2026 12:53
itcmsgr added a commit that referenced this pull request Apr 29, 2026
…n-CSF split (#523)

Implements the §63 lattice extension + §64 evidence predicate from the
Amendment 3 doc seed (#522). Decision-layer only.

Lattice changes (engine.go):
  - 3 new rule constants:
    G1/AmbiguityConflictExternal/default          → REFUSE (preserves pre-Amendment-3 hard-stop)
    G1/AmbiguityConflictExternal/OrphanProceed    → PROCEED PanelNative/csf
    G1/AmbiguityConflictExternal/EvidenceMismatch → REFUSE (predicate any-false)
  - decideAmbiguityConflictExternal() function mirrors decideAuthorityNFTBan()
    in shape: Group 2 precedence preserved → quintuple-check (csf + DA + NoRecord +
    --panel-auto-takeover + --accept-orphan-nftban) → §64 predicate delegation.
  - Decide() now calls decideAmbiguityConflictExternal(in) for the
    AuthorityAmbiguous + AmbiguityConflictExternal branch (replaces the
    inline REFUSE).

Evidence predicate (types.go):
  - New ExternalIndicator string field on DecisionInput (carries the
    classifier's external-authority string; required for §62 entry condition).
  - New AllTrueAmendment3() helper on OrphanEvidence: identical to AllTrue()
    EXCEPT row E.12 (NoConflictExternal) is omitted — the §62 entry IS
    AmbiguityConflictExternal so requiring "no conflict external" is
    incompatible by construction.
  - New FailedRowIDAmendment3() helper returns AMD3-E.{N} stable IDs so
    structured logs and Code-D evidence-records distinguish which
    predicate fired.

Test matrix (engine_amendment3_test.go — new file):
  - 15-row §67 matrix (AMD3-1 through AMD3-15) including the 3 auditor-
    required defensive-guard rows: AMD3-13 empty external, AMD3-14 rule-
    label assertion ("amendment-3 orphan-intent" reason substring),
    AMD3-15 multi-external "csf,ufw".
  - TestAmd3_RuleConstants pins canonical rule strings.
  - TestAmd3_AllTrueAmendment3_OmitsE12 verifies E.12 is excluded.
  - TestAmd3_FailedRowIDAmendment3_SkipsE12 verifies row-walk skips E.12.
  - TestAmd3_NilEvidence_AMD3E0 verifies nil-receiver sentinel.

Regression updates (engine_test.go, engine_amendment2_test.go):
  - 2 pre-existing fixtures asserting the old "G1/AmbiguityConflictExternal"
    rule string updated to RuleG1AmbConflictExtDefault. Behavior unchanged
    (still REFUSE); only the rule sub-classifier name shifts. Same pattern
    as Amendment 2's AuthorityNFTBan/default rename.
  - declaredRules() in engine_test.go updated to include the 3 new sub-rule
    constants (RuleG1AmbiguityConflictExt umbrella retained for grep parity).
  - 2 sentinel fixtures added to allFixtures pinning the new
    OrphanProceed and EvidenceMismatch rules for coverage assertion
    (full §67 matrix lives in engine_amendment3_test.go).

NOT touched (in scope per operator):
  - internal/installer/uninstall/* (classifier — semantic unchanged)
  - internal/installer/restore/execute.go (mutation surface unchanged)
  - internal/installer/state/* (state machine unchanged)
  - cmd/nftban-installer/main.go (history gate unchanged)
  - cmd/nftban-installer/flags.go (flag surface unchanged)
  - .github/workflows/* (CI unchanged)
  - §32 11-step ordering (unchanged)
  - Amendment 2's §54 predicate (untouched; AllTrue() preserved for the
    AuthorityNFTBan path; AllTrueAmendment3() is a new sibling)

Test results (lab4):
  - go test ./internal/installer/restore/...    → ok
  - go test ./cmd/nftban-installer/...          → ok
  - go test ./...                                → 64 packages ok, 0 FAIL

No host action. No binary rebuild. No nftban-installer invocation.
dns2 stays in canonical post-Gate-A state.

Closes part of PR-26 final closure path: Gate B retry on dns2 unblocks
once this PR merges + fresh Tier 1 binary is built + reachability monitor
activates + pre-execution Gate B retry audit returns GO.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant