Commit 8b71308
test(v1.100 PR-26-code-D): add 5 dispatcher-level evidence-failure semantics tests (auditor checkpoint)
Auditor focused-audit on 849b372 flagged that PR-26-code-D's Step D
introduces a real operator-visible terminal transition:
StateRestoreExecuted + evidence write failure → StateRestoreDegraded
The 10 unit tests already covered the writer + builder + recording
invariants but did NOT pin the dispatcher-level downgrade semantics.
This commit adds 5 dispatcher-level tests to close that gap.
Tests added:
cmd/nftban-installer/restore_decide_test.go
1. PR26D_ExecutedPlusEvidenceFail_DowngradesToDegraded
fake deps return StateRestoreExecuted; writeFailExec wrapper
forces evidence WriteFileAtomic to fail. Asserts:
- sf.State == StateRestoreDegraded (downgrade fires)
- exit code == StateRestoreDegraded.ExitCode()
- sf.State != StateRestoreExecuted (no false claim)
Note: sf.FailureReason stays empty by design (Transition only
populates FailureReason on .IsFailed() states; Degraded is
success-with-warnings). The downgrade reason surfaces via
log.Result, which is the authoritative operator channel for
Degraded outcomes.
2. PR26D_FailedExecutionPlusEvidenceFail_TerminalPreserved
fake.mutateErr forces FailedExecution; writeFailExec forces
evidence-write failure. Asserts:
- sf.State == StateRestoreFailedExecution (terminal preserved)
- exit == StateRestoreFailedExecution.ExitCode()
Evidence failure is warning-only on non-Executed terminals.
3. PR26D_FailedVerificationPlusEvidenceFail_TerminalPreserved
fake.activeRet=false forces inline-verify SafeToRemove=false →
FailedVerification; writeFailExec forces evidence-write fail.
Asserts terminal + exit code unchanged from FailedVerification.
4. PR26D_ExecutedPlusEvidenceOk_PreservesExecuted
Plain MockExecutor (writes succeed). Asserts:
- sf.State == StateRestoreExecuted (no downgrade on clean write)
- exit == StateRestoreExecuted.ExitCode()
- exactly one file written under restoreEvidenceDir
- no writes outside restoreEvidenceDir
5. PR26D_NoUpdateHistoryWrite_FileScan
File-scan against restore_decide.go. Strips line-leading // per
§46.1; asserts no production-code reference to writeHistory(
or update-history.json. Pins the §19.2 layer-4 invariant stays
untouched after PR-26-code-D adds Step D.
writeFailExec wrapper (test-only):
Wraps *executor.MockExecutor and overrides only WriteFileAtomic
to fail. Avoids changing the production MockExecutor; uses the
same composition pattern as flakyCSFActiveExec (introduced in
PR-25 4B-3-csf for analogous test purposes).
Verified on lab2 (Ubuntu 24.04, go1.22.2):
- go build ./... clean
- go test ./cmd/nftban-installer/... PASS
- 5 new TestRunRestoreExecutionFromProceed_PR26D_* /
TestDispatcher_PR26D_* tests all PASS
- go test -race -count=1 cmd + restore + state PASS
- existing PR-25 + PR-26-code-A/B/C tests still PASS
No production code change. No CI workflow change. No contract
amendment needed. Restore semantics from §48.6 lock + §19.2 layer-4
invariant are both now structurally pinned by tests.
Awaiting auditor sign-off + push signal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 849b372 commit 8b71308
1 file changed
Lines changed: 207 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
948 | 948 | | |
949 | 949 | | |
950 | 950 | | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
| 1052 | + | |
| 1053 | + | |
| 1054 | + | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
0 commit comments