Skip to content

Commit 680b434

Browse files
itcmsgrclaude
andcommitted
feat(v1.99 PR-18): seed apply orchestration contract
This commit establishes the PR-18 contract BEFORE any implementation code lands. Per user directive, PR-18 is judged by call-path purity, not by "it works in happy path." Pinned sentence (repeated in PR body + contract file + package doc): "PR-18 is orchestration-only: update apply may invoke the existing rebuild/lifecycle authority, but may not implement any independent apply, mutation, recovery, validation, or authority-taking behavior." Contents: - Call graph (runUpdateApply → firewall_rebuild → validator → recovery) - Canonical entry points PR-18 orchestrates (never reimplements) - 8 forbidden patterns (automatic NO-GO) - Explicit stop condition: new apply/mutation/recovery/authority logic → STOP and split to new PR No code, no behaviour change. This is the contract layer; step 1 (tests/proof skeleton) lands in the next commit, step 2 (minimal orchestration wiring) after that. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fff7c48 commit 680b434

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# PR-18 — Update Apply Orchestration Contract
2+
3+
**Status:** Draft — READY FOR IMPLEMENTATION (under strict contract enforcement)
4+
**Scope:** G3-U5 .. G3-U10
5+
**Pinned invariants:** INV-U-001 / INV-U-002 / INV-U-003
6+
7+
---
8+
9+
## Single-sentence contract
10+
11+
> PR-18 is orchestration-only: update apply may invoke the existing
12+
> rebuild/lifecycle authority, but may not implement any independent apply,
13+
> mutation, recovery, validation, or authority-taking behavior.
14+
15+
---
16+
17+
## Call graph (critical proof surface)
18+
19+
```
20+
runUpdateApply (new — orchestration only)
21+
22+
├── update.Preflight (existing — read-only, PR-16/PR-17)
23+
├── exec.Run("nftban", "firewall", "rebuild")
24+
│ │
25+
│ └── firewall_rebuild (existing — shell, cli/lib/nftban/cli/cmd_firewall.sh:1070)
26+
│ │
27+
│ ├── _firewall_rebuild_core
28+
│ ├── nftban_rebuild_recovery.sh (existing — recovery)
29+
│ └── rebuild/marker.go (existing — classification)
30+
31+
├── exec.Run("nftban-validate") (existing — validator gate)
32+
33+
└── sf.Transition(...) (existing — lifecycle state machine)
34+
```
35+
36+
**No new mutation path.**
37+
**No new validator path.**
38+
**No new recovery path.**
39+
**No new authority path.**
40+
41+
---
42+
43+
## Canonical entry points PR-18 orchestrates (never reimplements)
44+
45+
| Phase | Canonical entry | Owner |
46+
|---|---|---|
47+
| Preflight | `update.Preflight(exec, log, origin)` | PR-16 + PR-17 |
48+
| Target detection | `update.DetectVersions(exec, sourceDir, origin, log)` | PR-16 + PR-17 |
49+
| Recovery planning | `update.BuildRecoveryPlan(exec)` | PR-17 |
50+
| **Rebuild execution** | `nftban firewall rebuild``firewall_rebuild` | v1.96 (shell) |
51+
| **Recovery** | `_rebuild_*` family in `nftban_rebuild_recovery.sh` | v1.96 (shell) |
52+
| **Validator gate** | `nftban-validate --json` | v1.78+ (Go) |
53+
| **State transition** | `sf.Transition(State, Phase, reason)` | v1.73+ (installer) |
54+
55+
PR-21 will migrate `firewall_rebuild` to Go and delete the shell layer.
56+
PR-18 must not pre-empt that migration — orchestrate the shell path today.
57+
58+
---
59+
60+
## Forbidden patterns (automatic NO-GO on PR-18)
61+
62+
1. New `exec.Run("nft", ...)` call in `runUpdateApply` (nft only via rebuild)
63+
2. New `exec.WriteFile(...)` call that targets anything under `/etc/nftban/` or `/usr/lib/nftban/`
64+
3. New authority-classification call outside `authority.Classify` (which lives upstream of rebuild)
65+
4. New `systemctl` call that stops/starts external firewalls (UFW/firewalld/iptables)
66+
5. New rollback mechanism — any failure must delegate to `firewall_rebuild`'s own recovery
67+
6. Any path where `nftban-validate` is NOT called after apply
68+
7. Any path where `.conf.local` files are opened in write mode
69+
8. Any retry/loop/fallback logic that could mask a rebuild failure
70+
71+
CI enforces 1-5 via a call-path audit step; 6-8 via behavioural tests.
72+
73+
---
74+
75+
## Stop condition
76+
77+
If implementation pressure appears that requires any of:
78+
79+
- new apply logic
80+
- bypass of rebuild
81+
- direct config mutation
82+
- custom recovery
83+
- custom authority handling
84+
85+
**STOP PR-18 immediately.** Split that work into a separate design/audit PR. Do NOT solve it inside PR-18.

0 commit comments

Comments
 (0)