fix(backup): make Host110 runtime receipt durable

This commit is contained in:
Your Name
2026-07-18 23:37:52 +08:00
parent 0b9c028400
commit 8f11ef3362
3 changed files with 767 additions and 44 deletions

View File

@@ -0,0 +1,133 @@
# AWOOOI Agent99 Host110 Backup Runtime V9
Status: proposed; owner approval required before any production apply.
This artifact supersedes V2 through V8. The following V8 identities are void
for approval and remain audit evidence only:
- candidate/revision: `0b9c0284006c8d892c4617c2bfc16869bb6637f0`
- artifact SHA-256: `ea9537613c462a07f3155263da5ad0f444bda0ba6773b49208de31b0acdef228`
- exact diff SHA-256: `0867d9221ecfa7bcbe6b073a6a02da401bbed5087b9f2bd7fa494f2953b2ef2e`
- every other proposal/content hash derived from V8 candidate bytes
No V8 hash, ref, review, or receipt grants production execution authority.
## Scope
- Agent99 runtime bundle: 19 files, guarded by one producer/consumer parity
test.
- Host110 backup payload: 18 ordered files, comprising 17 backup scripts and
`backup-health-textfile-exporter.py`.
- Host110 remote stage: 21 unique basenames, comprising the ordered 18-file
payload, fixed executor, independent verifier, and `manifest.json`.
- Fixed target: `wooo@192.168.0.110`, dispatched by Windows99 Agent99 from an
exact Gitea revision and digest manifest.
- Gitea offline backup and container lifecycle changes remain excluded;
`backup-gitea.sh` has no candidate diff from the production base.
## V8 Defects Closed
### Durable Receipt Transaction
The executor no longer captures `write_receipt` through command substitution
and cannot mask an internal failure with a later `printf`. Receipt publication
uses an exclusive temporary file, exact full-write check, file `fsync`,
temporary-byte SHA-256 readback, no-replace hard link, directory `fsync`, exact
final-byte/document/SHA-256 readback, temporary unlink, and a second directory
`fsync`. Any write, link, fsync, cleanup, or readback failure is nonzero and
removes a final path created by that failed attempt when possible.
`APPLY_COMPLETE=1` is set only after the durable verified receipt passes this
transaction. Stage and rollback prestate are never cleared before that point.
If verified receipt publication fails, the EXIT path performs rollback first,
writes a distinct failure receipt, and only removes rollback prestate after
both rollback verification and durable failure-receipt publication succeed.
Payload files, destination directories, rollback prestate files, and the
rollback directory are explicitly fsynced before their corresponding durable
claim can be published.
### Run-Owned Temporary Files
Every apply and rollback temporary destination is tracked for the exact run.
Rollback removes and reads back all tracked paths, including a failure between
`install` and `mv`. Canonical content/metadata verification plus zero hidden
residue are both required before rollback can be called verified.
### Rollback Truth
Receipt schema `agent99_host110_backup_runtime_deploy_receipt_v2` records
`rollbackAttempted`, `rollbackPerformed`, `rollbackVerified`, and
`zeroResidueVerified` independently. A partial, unknown, or residue-bearing
rollback terminates as `rollback_unverified`; only a fully restored and
zero-residue transaction may terminate as `failed_rolled_back`.
### Producer/Consumer Parity
The integration test parses both actual sources and requires the broker's 18
payload basenames to equal the executor payload in count, exact set, and exact
order. It separately requires executor, verifier, and `manifest.json`, yielding
21 unique remote-stage basenames.
## Fault-Injection Contract
The bounded local harness executes the real executor control flow against
isolated temporary destinations and covers:
- successful apply, durable receipt, verifier, and post-receipt prestate cleanup;
- receipt write, link, fsync, and final-readback failures;
- apply failure after hidden-temp installation but before canonical `mv`;
- forced temp-cleanup failure and `rollback_unverified` evidence preservation.
Every receipt fault must restore exact prestate, emit no success JSON, and
produce a durable `failed_rolled_back` receipt. A cleanup fault must preserve
`prestate.tsv`, expose rollback attempted/performed separately, and must not
claim rollback verification.
Fault hooks require an explicit test enable flag and a transformed
non-production destination. The canonical `/backup/scripts` executor can never
enable them, even if a fault environment variable is present.
## Exact Diff Serialization
Substitute the V9 Gitea live-ref SHA for `<candidate_git_sha>` and hash the
exact stdout bytes from this command:
```sh
git diff --binary --full-index \
e7e3bcf8a5a8a19c1253d73f51d9dca248af0aa3..<candidate_git_sha> |
shasum -a 256
```
The review message independently binds the Gitea live ref and Git SHA, this
tracked artifact path and bytes hash, and the serialized diff hash.
## Apply Effects
- Windows99 Agent99 runtime promotion writes the 19 runtime files plus bounded
manifest and receipt state.
- Host110 Apply writes/replaces the 18 payload paths through one exclusive,
digest-bound filesystem transaction.
- Apply does not run a backup, invoke a Gitea container lifecycle, sync Google
Drive, prune snapshots, restart a VM or service, or change a database,
network, or firewall.
## Validation
- The exact broker payload/order and 21-file stage parity test must pass.
- Success and all six fault-injection paths must execute and pass.
- Focused runtime, broker, backup, parity, Ansible, shell, and Python checks
must pass.
- Changed PowerShell must parse on Windows99 with zero errors when applicable.
- Central review must independently reproduce the live ref, artifact hash,
exact diff hash, 19/18/21 counts, and zero `backup-gitea.sh` diff.
## Rollback
- Source rollback reverts the exact V9 diff to
`e7e3bcf8a5a8a19c1253d73f51d9dca248af0aa3` without force-pushing.
- Agent99 rollback restores the prior runtime files and manifest and verifies
prior hashes independently.
- Host110 rollback restores all prior payload content, SHA-256, uid, gid, and
mode under the exclusive lock and proves zero run-owned temporary residue.
- Any canonical, metadata, receipt, or residue mismatch terminates as
`rollback_unverified`; rollback prestate remains available for diagnosis.