Skip to content

Commit e6c30f6

Browse files
itcmsgrclaude
andcommitted
docs: M88-9 evidence contract + M88-10 build status page
M88-9: docs/EVIDENCE_CONTRACT.md - Evidence states (present/absent/unknown) - Counter/set/chain/journal semantics - Correlation rules and allowed values - nft command compatibility reference - Schema version 1.88.0 M88-10: docs/BUILD_STATUS.md - 26 CI workflows in transparency table - Contract gates (G1-1, G2-3, G8-1/2/3/4, B86-1, M84-2) - Runtime test inventory - Known issues - Health policy - How to verify section Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2ffd0b9 commit e6c30f6

2 files changed

Lines changed: 224 additions & 0 deletions

File tree

docs/BUILD_STATUS.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# NFTBan — Integrity & Build Status
2+
3+
> **Policy:** Main branch is always green. Failed CI blocks merge.
4+
> No exceptions, no manual overrides for truth-critical checks.
5+
6+
**Current version:** v1.88.0
7+
**Last audit:** 2026-04-16
8+
9+
---
10+
11+
## Build & Test
12+
13+
| Workflow | What it verifies | Frequency | Status |
14+
|----------|-----------------|-----------|--------|
15+
| [Go Build & Test](https://github.com/itcmsgr/nftban/actions/workflows/ci-go.yml) | Go compilation, unit tests (race detector), module completeness (G8-1/G8-2/G8-3), schema version lock | Every PR + push | [![Go](https://github.com/itcmsgr/nftban/actions/workflows/ci-go.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ci-go.yml) |
16+
| [Bash Validation](https://github.com/itcmsgr/nftban/actions/workflows/ci-bash.yml) | Shell syntax, strict mode compliance, header spec | Every PR + push | [![Bash](https://github.com/itcmsgr/nftban/actions/workflows/ci-bash.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ci-bash.yml) |
17+
| [ShellCheck](https://github.com/itcmsgr/nftban/actions/workflows/shellcheck.yml) | Static analysis of all shell scripts | Every PR + push | [![ShellCheck](https://github.com/itcmsgr/nftban/actions/workflows/shellcheck.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/shellcheck.yml) |
18+
| [Build Packages](https://github.com/itcmsgr/nftban/actions/workflows/build-packages.yml) | RPM (el9/el10) + DEB (debian12/13, ubuntu22/24) build + install test | Every PR + push | [![Build](https://github.com/itcmsgr/nftban/actions/workflows/build-packages.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/build-packages.yml) |
19+
| [Docker](https://github.com/itcmsgr/nftban/actions/workflows/docker.yml) | Container image build | Every PR + push | [![Docker](https://github.com/itcmsgr/nftban/actions/workflows/docker.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/docker.yml) |
20+
| [Smoke Test](https://github.com/itcmsgr/nftban/actions/workflows/ci-smoke.yml) | CLI command execution, runtime anomaly checks | Every PR + push | [![Smoke](https://github.com/itcmsgr/nftban/actions/workflows/ci-smoke.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ci-smoke.yml) |
21+
22+
## Architecture & Contract Enforcement
23+
24+
| Workflow | What it verifies | Frequency | Status |
25+
|----------|-----------------|-----------|--------|
26+
| [Architecture Policy](https://github.com/itcmsgr/nftban/actions/workflows/ci-architecture.yml) | FHS spec drift, schema codegen sync, vocabulary (G1-1), schema version (G2-3), module smoke (G8-4), legacy regression blockers (B86-1/M84-2 guards) | Every PR + push | [![Architecture](https://github.com/itcmsgr/nftban/actions/workflows/ci-architecture.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ci-architecture.yml) |
27+
| [Documentation Validation](https://github.com/itcmsgr/nftban/actions/workflows/ci-docs.yml) | Markdown lint, link validation, doc completeness | Every PR + push | [![Docs](https://github.com/itcmsgr/nftban/actions/workflows/ci-docs.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ci-docs.yml) |
28+
| [Project Health](https://github.com/itcmsgr/nftban/actions/workflows/project-health.yml) | Repository health metrics, stale issues, PR hygiene | Scheduled | [![Health](https://github.com/itcmsgr/nftban/actions/workflows/project-health.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/project-health.yml) |
29+
30+
## Security (SAST + SCA + Secrets)
31+
32+
| Workflow | What it verifies | Frequency | Status |
33+
|----------|-----------------|-----------|--------|
34+
| [CodeQL](https://github.com/itcmsgr/nftban/actions/workflows/codeql.yml) | Go semantic code analysis (GitHub Advanced Security) | Every PR + push | [![CodeQL](https://github.com/itcmsgr/nftban/actions/workflows/codeql.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/codeql.yml) |
35+
| [Semgrep](https://github.com/itcmsgr/nftban/actions/workflows/semgrep.yml) | Pattern-based security rules (Go + Shell) | Every PR + push | [![Semgrep](https://github.com/itcmsgr/nftban/actions/workflows/semgrep.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/semgrep.yml) |
36+
| [Secure Go](https://github.com/itcmsgr/nftban/actions/workflows/secure-go.yml) | gosec + staticcheck + govulncheck + Trivy | Every PR + push | [![SecureGo](https://github.com/itcmsgr/nftban/actions/workflows/secure-go.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/secure-go.yml) |
37+
| [OSV-Scanner](https://github.com/itcmsgr/nftban/actions/workflows/osv-scanner.yml) | Google OSV vulnerability database scan | Every PR + weekly | [![OSV](https://github.com/itcmsgr/nftban/actions/workflows/osv-scanner.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/osv-scanner.yml) |
38+
| [Gitleaks](https://github.com/itcmsgr/nftban/actions/workflows/gitleaks.yml) | Secret/credential detection in commits | Every PR + push | [![Gitleaks](https://github.com/itcmsgr/nftban/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/gitleaks.yml) |
39+
| [Fuzz Tests](https://github.com/itcmsgr/nftban/actions/workflows/fuzz.yml) | Automated fuzz testing for parser robustness | Nightly | [![Fuzz](https://github.com/itcmsgr/nftban/actions/workflows/fuzz.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/fuzz.yml) |
40+
| [Dependency Review](https://github.com/itcmsgr/nftban/actions/workflows/dependency-review.yml) | PR-level dependency diff analysis | Every PR | [![DepReview](https://github.com/itcmsgr/nftban/actions/workflows/dependency-review.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/dependency-review.yml) |
41+
| [Socket Supply Chain](https://github.com/itcmsgr/nftban/actions/workflows/socket-supplychain.yml) | Typosquatting and malicious package detection | Every PR | [![Socket](https://github.com/itcmsgr/nftban/actions/workflows/socket-supplychain.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/socket-supplychain.yml) |
42+
43+
## Compliance & Supply Chain
44+
45+
| Workflow | What it verifies | Frequency | Status |
46+
|----------|-----------------|-----------|--------|
47+
| [OSSRA Remediation](https://github.com/itcmsgr/nftban/actions/workflows/ossra-remediation.yml) | License compliance (go-licenses), SPDX headers, dependency freshness (libyear), URL validation (Lychee) | Every PR + push | [![OSSRA](https://github.com/itcmsgr/nftban/actions/workflows/ossra-remediation.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/ossra-remediation.yml) |
48+
| [OpenSSF Scorecard](https://github.com/itcmsgr/nftban/actions/workflows/scorecard.yml) | OpenSSF security health score | Scheduled | [![Scorecard](https://github.com/itcmsgr/nftban/actions/workflows/scorecard.yml/badge.svg)](https://github.com/itcmsgr/nftban/actions/workflows/scorecard.yml) |
49+
| [SLSA Go Releaser](https://github.com/itcmsgr/nftban/actions/workflows/slsa-go-releaser.yml) | SLSA Level 3 provenance attestation | On release ||
50+
51+
---
52+
53+
## Contract Gates (v1.84+)
54+
55+
These are **blocking** — a PR cannot merge if any gate fails.
56+
57+
| Gate | What it enforces | Since | Workflow |
58+
|------|-----------------|-------|----------|
59+
| G1-1 | No banned terms in CLI output (vocabulary discipline) | v1.84 | ci-architecture.yml |
60+
| G2-3 | Schema version: Go source = CLI expectation | v1.84 | ci-architecture.yml |
61+
| G8-1 | Every CORE module in ModuleHealthMap + JSON | v1.85 | ci-go.yml (Go tests) |
62+
| G8-2 | Every config directory has a classification | v1.85 | ci-go.yml (Go tests) |
63+
| G8-3 | IPv6 parity: no IPv4-only evaluator checks | v1.85 | ci-go.yml (Go tests) |
64+
| G8-4 | Cross-surface module consistency (validator = health) | v1.85 | ci-architecture.yml |
65+
| B86-1 | No ModuleTruth reintroduction | v1.86 | ci-architecture.yml |
66+
| M84-2 | No legacy fallback reintroduction | v1.86 | ci-architecture.yml |
67+
| M87-1 | Evidence schema version lock (1.88.0) | v1.87 | ci-go.yml (Go tests) |
68+
| M87-2 | Correlation enum restricted to allowed values | v1.87 | ci-go.yml (Go tests) |
69+
| M87-3 | EvidenceSnapshot golden JSON must not drift | v1.87 | ci-go.yml (Go tests) |
70+
| M88-1 | Journal evidence must not affect truth authority | v1.88 | ci-go.yml (Go tests) |
71+
72+
## Host Runtime Gate (pre-release)
73+
74+
| Test | What it verifies | File |
75+
|------|-----------------|------|
76+
| CLI runtime smoke | 27 CLI commands execute without bash errors | test_cli_runtime.sh |
77+
78+
This gate runs on deployed hosts before release tagging.
79+
It catches runtime failures (bad array subscript, unbound variable, syntax error)
80+
that cannot be detected in CI containers without nftables/systemd.
81+
82+
## Runtime Tests (host-deployed)
83+
84+
These require a deployed system and are not part of PR CI:
85+
86+
| Test | What it verifies | File |
87+
|------|-----------------|------|
88+
| G2-1 | Truth consistency: validator status = health status | test_truth_consistency.sh |
89+
| G7-3 | Exit code contract: 0=PROTECTED, 1=DEGRADED, 2=DOWN | test_exit_code_consistency.sh |
90+
| G8-4 | Module list: validator JSON = health JSON | test_module_smoke.sh |
91+
92+
---
93+
94+
## Known Issues
95+
96+
| Issue | Severity | Status |
97+
|-------|----------|--------|
98+
| gosec SARIF alerts on installer G104 | LOW | Dismissed as false positive (pre-existing, not PR-related) |
99+
100+
---
101+
102+
## Health Policy
103+
104+
- **Main is always green.** Failed CI blocks merge.
105+
- **No manual overrides** for truth-critical checks (G1-1, G2-3, G8-*).
106+
- **Failing badge = working system.** It proves CI is active and catching issues.
107+
- **Every release is CI-gated.** No tag without green pipeline.
108+
- **Evidence over claims.** Click any badge to see full run logs.
109+
110+
---
111+
112+
## How to Verify
113+
114+
```bash
115+
# On any deployed host:
116+
nftban-validate --json | jq '.status' # Kernel truth
117+
nftban health --json | jq '.status' # CLI agrees
118+
nftban metrics evidence # Evidence snapshot
119+
nftban metrics evidence-json | jq '.correlation' # Correlation diagnostic
120+
```
121+
122+
All outputs are verifiable against the [contract rules](docs/CONTRACT_RULES.md).

docs/EVIDENCE_CONTRACT.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# NFTBan Evidence Contract (v1.88)
2+
3+
Evidence is an observability layer over kernel enforcement.
4+
It answers: "what is actually happening?" — not "what should be happening?"
5+
6+
## Position in Architecture
7+
8+
| Layer | Role | Authority |
9+
|-------|------|-----------|
10+
| Kernel | Enforcement | Source of truth |
11+
| Validator | Interpretation | Health authority |
12+
| Evidence | Observability | No authority |
13+
14+
**Evidence MUST NOT influence status, exit codes, or protection decisions.**
15+
16+
## Evidence States
17+
18+
Every evidence datum is one of:
19+
20+
| State | Meaning |
21+
|-------|---------|
22+
| Present | Confirmed by kernel/journal data |
23+
| Absent | Confirmed not present |
24+
| Unknown | Collection failed — absence not known |
25+
26+
Evidence MUST NOT guess or infer missing data.
27+
Failure MUST NOT be collapsed into absence.
28+
29+
## Counter Semantics
30+
31+
- Counter > 0 = positive enforcement evidence
32+
- Counter = 0 = neutral (not failure)
33+
- Counter unavailable (nil) = unknown
34+
- Shared counters are family-level only; no source attribution
35+
36+
## Set Semantics
37+
38+
- Exists=true, Count>=0 = collected successfully
39+
- Exists=false, Unknown=false = confirmed absent
40+
- Unknown=true = collection failure
41+
42+
## Chain Semantics
43+
44+
- Same three-state model as sets
45+
46+
## Journal Evidence (v1.88)
47+
48+
- Bounded: 15m window, 500 lines, 3s timeout
49+
- Exec failure = Unknown (not absence)
50+
- Empty output with exit 0 = no events (not failure)
51+
- LoginMon: bans and login_failed events from nftband journal
52+
53+
## Correlation
54+
55+
Correlation compares kernel evidence against validator interpretation.
56+
It is **diagnostic only**.
57+
58+
### Allowed values
59+
60+
| Value | Meaning |
61+
|-------|---------|
62+
| match | Evidence agrees with validator |
63+
| mismatch | Evidence contradicts validator |
64+
| warning | Suspicious but explainable |
65+
| expected_limitation | Not provable (portscan) |
66+
| unknown | Insufficient evidence |
67+
68+
### Rules
69+
70+
- Unknown evidence → unknown correlation (never guessed)
71+
- Correlation MUST NOT derive PROTECTED/DEGRADED/DOWN
72+
- Correlation MUST NOT influence exit codes
73+
- Default fallthrough → unknown (not match)
74+
75+
## Evidence Schema
76+
77+
Version: 1.88.0
78+
79+
```json
80+
{
81+
"schema_version": "1.88.0",
82+
"collected_at": "...",
83+
"truth_authority": "kernel",
84+
"kernel": { "counters", "sets", "chains" },
85+
"external": { "loginmon_active", "loginmon_bans", "loginmon_events" },
86+
"validator": { "status", "modules", "findings" },
87+
"correlation": { "module": "result" }
88+
}
89+
```
90+
91+
## nft Command Compatibility
92+
93+
Safe everywhere:
94+
- `nft -j list counters` (global)
95+
- `nft list table <family> <table>`
96+
- `nft list set <family> <table> <name>` (singular)
97+
- `nft -j list ruleset` (global)
98+
99+
Broken on v1.0.x-v1.1.x:
100+
- `nft list counters <family> <table>`
101+
- `nft list chains <family> <table>`
102+
- `nft list sets <family> <table>`

0 commit comments

Comments
 (0)