运维(08-28-production-arm-backup-transfer-incident): 固化只读调查合同

这个提交包含在:
2026-08-28 13:26:37 +08:00
父节点 a1c59e2a78
当前提交 573c46fbe7
共修改 10 个文件,包含 1153 行新增和 2 行删除
@@ -2865,6 +2865,37 @@ current shared mapping -> fine-grained stages + mutation listeners
- Read-only investigation output is an allowlist of status/category/count/age
and capacity fields. Never print unit command lines, raw JSON, raw journal,
remote identities, paths, run ids, webhook data or diagnostic stderr.
- Before classifying an off-host transport failure, validate the newest source
batch with the same manifest schema/status, exact three-file set, run-id
pairing, byte-count and SHA-256 contract used by the receiver. Report only
whether a complete local recovery point exists, its age/count/aggregate
bytes and one of `production_single_point` or `no_proven_recovery_point`.
Off-host staleness alone does not distinguish those two materially different
production risks.
- Inspect cleanup semantics as executable ordering, not a remembered claim.
Source publication must precede transfer; local pruning must follow verified
off-host finalize and success-state publication; generation staging must be
protected by an exit cleanup. Also report current valid/invalid/staging
counts so repeated transfer failures cannot silently consume source space.
- A retained `last-error.log` may provide an rsync code only when the matching
safe run summary says `phase_offhost_transfer_failed`. Never parse a log from
another phase or substitute service exit `1`. If the wrapper did not persist
transfer start/end clocks, emit `NOT_AVAILABLE`; service duration, mtime and
conversation time are not transfer-duration evidence.
- A read-only inspector must prevalidate every output as a fixed key plus an
enum/integer value. Malformed manifests, unreadable files and unexpected
runtime exceptions collapse to stable categories without a traceback,
because tracebacks can expose absolute paths even when normal output is
redacted.
- If existing read-only state cannot converge on a cause, stop expanding the
read surface. The next step is a separately approved, single-attempt
observational retransmit with frozen input, fixed telemetry, bounded timeout
and no automatic retry. It is a diagnostic write, not part of read-only
authority.
- After a transport repair, one fresh atomic batch may unlock a blocked restore
drill, but incident closeout requires two consecutive natural schedules.
Each cycle records source and receiver capacity plus receiver partial count
and aggregate bytes; a manual run does not replace either natural sample.
### 4. Validation & Error Matrix
@@ -2886,6 +2917,15 @@ current shared mapping -> fine-grained stages + mutation listeners
- Path cannot be traversed by the approved account -> `ACCESS_DENIED`; request
separate read authority only if the unresolved field materially changes the
decision.
- Complete source batch valid + off-host point stale -> production has a local
recovery point but remains a single point; prefer the next safe natural run
unless a separately approved transition run is justified.
- No source batch passes the complete contract -> `no_proven_recovery_point`;
raise the transition-recovery-point priority, but do not trigger a backup
until root cause, capacity and stop conditions are approved.
- `last-error.log` contains rsync-like text but the safe last-run phase is not
`offhost_transfer` -> exit code remains `NOT_AVAILABLE` rather than attaching
stale diagnostics to the current failure.
### 5. Good/Base/Bad Cases
@@ -2915,6 +2955,13 @@ current shared mapping -> fine-grained stages + mutation listeners
rsync codes `23/30/12/11/255`; assert the incident summary preserves code and
elapsed-time evidence separately from wrapper exit `1` and does not output
file names.
- Fixture one complete source batch, no complete source batch, checksum/size
corruption and malformed manifest. Assert the risk classification and
transition recommendation change without emitting paths, run ids, artifact
names, raw diagnostics or tracebacks.
- Mechanically mutate the wrapper ordering so pruning appears before transfer;
the cleanup/retention contract must turn false. A prose claim that failure
retains data is not sufficient regression evidence.
- Sensitive scan the probe and assert raw `ExecStart`, journal, JSON, paths,
remote identities and run ids cannot appear in stdout.
- Every root probe must self-remove its fixed entry/sudoers and an independent
@@ -2928,6 +2975,8 @@ current shared mapping -> fine-grained stages + mutation listeners
timer active -> backup healthy
state path test returned false -> state missing
partial count > 0 -> finalize failed
off-host stale -> assume one complete backup still exists on production
service exit 1 -> call it the rsync exit code and use service duration
```
#### Correct
@@ -2939,4 +2988,6 @@ derive unit identity from installer -> timer trigger + service Result/exit
-> partial proves initial SSH acceptance; compare byte offset + rsync code + duration
-> dead-man decision + dedup state + sent flag
-> safe scheduler/source/transfer/finalize/alert conclusion
-> validate the source batch first and classify single-point vs no proven point
-> bind retained diagnostics to the safe failure phase; unavailable clocks stay unavailable
```