fix(backup): make Host110 runtime receipt durable
This commit is contained in:
133
docs/proposals/AWOOOI-AG99-H110-BACKUP-RUNTIME-V9.md
Normal file
133
docs/proposals/AWOOOI-AG99-H110-BACKUP-RUNTIME-V9.md
Normal 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.
|
||||
Reference in New Issue
Block a user