运维(08-28-production-arm-backup-transfer-incident): 固化只读调查合同
这个提交包含在:
@@ -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
|
||||
```
|
||||
|
||||
在新工单中引用
屏蔽一个用户