feat(core): workspace recovery and Sokar artifact manifests (PR 4/9) #655

Merged
toasterson merged 4 commits from feat/core-workspace-recovery into main 2026-10-16 07:10:32 +00:00
Owner

Core relocation must reconstruct cognitive state from Postgres, while only explicitly reviewed non-derived, non-secret files may come from Sokar. This PR adds optional artifact recovery and offline legacy staging; it does not enable them, deploy, import production data, extract the wk01 archive, or change volumes/manifests.

  • Keep the existing full-Agent PG wake/WAL/residency path. Required-authority mode now refuses missing/retired/mismatched identities at admission and control-plane join without minting a row. This tightening applies to every require_authoritative = true deployment, independently of artifact config. The opted-in artifact path rechecks the physical residency session after downloads before admitting the workspace. The opted-in artifact path rechecks the physical residency session after downloads before admitting the workspace.
  • Close a recovery gap found by exact cold-wake testing: relational symbols now retain created_at and typed source metadata. Older rows remain explicitly unknown (0/null), requiring ledger reconciliation with retained sources.
  • Add versioned, bounded Sokar manifests under a separate artifacts/ tree. Reject unsafe/DB/archive/credential paths, unknown files, symlinks, divergent trees and hash/length mismatches. Warm validation does not download or rewrite files. Publication reads every object back, then CAS-publishes its digest/manifest through the physical PG residency session and current epoch. Interrupted uploads cannot advance the pointer; exact lost-ack retries reconcile.
  • Add akh-workspace-recover: an exact-file disposition ledger gates legacy loading into a new, isolated SQLite stage. Verify every typed component by readback, exercise cold wake/full resume, and report post-resume differences. Offline authority comparison is read-only and includes recovery boundaries and ordered WAL tail. It accepts no production URL and never grants production acceptance.
  • Preserve the houses importer's old-symbol compatibility and refuse nonempty artifact-pointer tables requiring separate object verification. No new ESO stores, roles, credentials or registry/placement changes. Talos #208 is merged; #212 remains open. Re-read its eventual merged artifacts before PR6.

Runbook: scripts/platform-storage/CORE-WORKSPACES.md. No actual archived identity is certified here; all 15 require the operator disposition ledger and later GO. Full resume intentionally refreshes tool-fact timestamps and continuity observations, which remain visible in the staging report. Unknown legacy metadata remains a hold. Older snapshot writers would discard the new symbol fields on delete/reinsert: prefer config-only rollback; otherwise quiesce writers and retain a verified typed export first.

Validation (lean local target, only changed crates):

  • cargo test --locked -p akhomed-store -p sokar-client -- --test-threads=1.
  • cargo test --locked -p akh-medu --features postgres --lib snapshot::tests: 53 passed.
  • scripts/platform-storage/test-postgres.py --workspace-only: real disposable PG fencing/CAS/readback, cold recovery, required-authority refusal, existing provenance/allocator recovery, artifact HTTP fixtures, and offline CLI staging/refusals/read-only comparison.
  • Houses importer tests: 13 passed; leaf-crate clippy with -D warnings passed; cargo fmt --all -- --check and git diff --check.
  • Observed unpinned test tooling: postgres:latest = PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2), digest sha256:74935e72241653ca55e0414067e6d8763aceb8a810eb51b452253ec3dcfc4336; uv selected Python 3.12.14 and psycopg 3.3.6. No provider/image build inputs changed or new pins added.

Local timing flake: shared_layout_contends_but_per_akh_snapshots_do_not once failed at host_store while acquiring a connection with its existing 100 ms deadline during concurrent compilation. Its actual contention assertions had not run. Serial retry passed the full changed leaf-crate suites (63 tests passed; environment-gated tests reported separately); no timeout or assertion changes. No sweep-timing or analogy test changes.

Review fixes:

  • Share the required-authority identity check between admission and join. Required authority never calls ensure_akh; database-read errors explicitly release the held residency session before returning.
  • Comparison scratch now uses a private system temporary directory with RAII cleanup, including wake/resume/readback errors and future cancellation. Read-only authority directory/DB comparison and cleanup after a forced cold-wake failure are covered.
  • Reject SQLite/redb magic headers and PEM prefixes during object readback and warm validation, even for notes.txt. This complements operator classification; it is not a general secret scanner.
  • Runbook now states the independent required-authority behavior change, requires migrate_on_start = true for the older-binary rollback guard, explains the silent metadata-loss risk when that guard is disabled, and carries the fleet gate: never run mixed akhomed versions against one akhomed DB; the first image bump including #655 rolls all houses together.

Fix validation (same lean local target; no Docker/image build or full sweep):

  • cargo test --locked -p akh-medu --features postgres --bin akh-workspace-recover: 2 passed.
  • cargo test --locked -p akh-medu --features postgres --lib workspace_recovery: 3 passed; disposable-Postgres integration test remains environment-gated, not rerun for these fixes.
  • cargo test --locked -p akh-medu --features server --bin akhomed authoritative_house_refuses_local_fallback_and_missing_snapshot: 1 passed, including missing/retired/mismatched join refusal and successful existing-identity join.
  • cargo clippy --locked -p akh-medu --features server --lib --bin akh-workspace-recover -- -D warnings, formatting and diff checks passed.
  • Including --bin akhomed in strict clippy reports seven pre-existing warnings in unchanged code: unnecessary_map_or (line 1511), too_many_arguments (5172), and collapsible_if (5315/5316, 6304/6305, 6444). No lint allowances or unrelated cleanup were added; the daemon regression test passes.

CI diagnosis (run 4295): the full Forgejo UI log for test-akh-medu showed renamed_database_and_pem_content_are_refused_cold_and_warm failing its warm-path assertion (3947 passed, 1 failed, 22 ignored). This was a real test-fixture regression, not the sweep/analogy flake. The fixture inherited the runner umask and could create a group-writable directory; ownership validation then correctly refused before the magic-header check. The old binary reproduces the exact failure under umask 0002. The test-only fix explicitly creates the fixture directory as 0700, matching production restore, and prints the actual refusal on assertion failure. All three local workspace-recovery tests pass under umask 0002 (PG integration remains environment-gated locally); formatting/diff checks pass. No production code, timeouts, or assertions were weakened.

test-session-platform failed at the same assertion in the disposable PG harness; its rendered Forgejo UI log was interleaved, so the original Solstice step log was checked to confirm this. No separate regression was found there. Both failures are addressed by the same fixture fix.

CI: run 4298 is green on 20d233d85d544e727748a023aa8d3c009de51ad6: all 14 jobs succeeded, including both previously failing test jobs and every platform-image job. Operator reviews/merges; no self-merge. No deployment, production import or volume switch.

Core relocation must reconstruct cognitive state from Postgres, while only explicitly reviewed non-derived, non-secret files may come from Sokar. This PR adds optional artifact recovery and offline legacy staging; it does not enable them, deploy, import production data, extract the wk01 archive, or change volumes/manifests. - Keep the existing full-Agent PG wake/WAL/residency path. Required-authority mode now refuses missing/retired/mismatched identities at admission and control-plane join without minting a row. This tightening applies to every `require_authoritative = true` deployment, independently of artifact config. The opted-in artifact path rechecks the physical residency session after downloads before admitting the workspace. The opted-in artifact path rechecks the physical residency session after downloads before admitting the workspace. - Close a recovery gap found by exact cold-wake testing: relational symbols now retain `created_at` and typed `source` metadata. Older rows remain explicitly unknown (`0`/null), requiring ledger reconciliation with retained sources. - Add versioned, bounded Sokar manifests under a separate `artifacts/` tree. Reject unsafe/DB/archive/credential paths, unknown files, symlinks, divergent trees and hash/length mismatches. Warm validation does not download or rewrite files. Publication reads every object back, then CAS-publishes its digest/manifest through the physical PG residency session and current epoch. Interrupted uploads cannot advance the pointer; exact lost-ack retries reconcile. - Add `akh-workspace-recover`: an exact-file disposition ledger gates legacy loading into a **new, isolated SQLite stage**. Verify every typed component by readback, exercise cold wake/full resume, and report post-resume differences. Offline authority comparison is read-only and includes recovery boundaries and ordered WAL tail. It accepts no production URL and never grants production acceptance. - Preserve the houses importer's old-symbol compatibility and refuse nonempty artifact-pointer tables requiring separate object verification. No new ESO stores, roles, credentials or registry/placement changes. Talos #208 is merged; #212 remains open. Re-read its eventual merged artifacts before PR6. Runbook: `scripts/platform-storage/CORE-WORKSPACES.md`. No actual archived identity is certified here; all 15 require the operator disposition ledger and later GO. Full resume intentionally refreshes tool-fact timestamps and continuity observations, which remain visible in the staging report. Unknown legacy metadata remains a hold. Older snapshot writers would discard the new symbol fields on delete/reinsert: prefer config-only rollback; otherwise quiesce writers and retain a verified typed export first. Validation (lean local target, only changed crates): - `cargo test --locked -p akhomed-store -p sokar-client -- --test-threads=1`. - `cargo test --locked -p akh-medu --features postgres --lib snapshot::tests`: 53 passed. - `scripts/platform-storage/test-postgres.py --workspace-only`: real disposable PG fencing/CAS/readback, cold recovery, required-authority refusal, existing provenance/allocator recovery, artifact HTTP fixtures, and offline CLI staging/refusals/read-only comparison. - Houses importer tests: 13 passed; leaf-crate clippy with `-D warnings` passed; `cargo fmt --all -- --check` and `git diff --check`. - Observed unpinned test tooling: `postgres:latest` = PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2), digest `sha256:74935e72241653ca55e0414067e6d8763aceb8a810eb51b452253ec3dcfc4336`; uv selected Python 3.12.14 and psycopg 3.3.6. No provider/image build inputs changed or new pins added. Local timing flake: `shared_layout_contends_but_per_akh_snapshots_do_not` once failed at `host_store` while acquiring a connection with its existing 100 ms deadline during concurrent compilation. Its actual contention assertions had not run. Serial retry passed the full changed leaf-crate suites (63 tests passed; environment-gated tests reported separately); no timeout or assertion changes. No sweep-timing or analogy test changes. Review fixes: - Share the required-authority identity check between admission and join. Required authority never calls `ensure_akh`; database-read errors explicitly release the held residency session before returning. - Comparison scratch now uses a private system temporary directory with RAII cleanup, including wake/resume/readback errors and future cancellation. Read-only authority directory/DB comparison and cleanup after a forced cold-wake failure are covered. - Reject SQLite/redb magic headers and PEM prefixes during object readback and warm validation, even for `notes.txt`. This complements operator classification; it is not a general secret scanner. - Runbook now states the independent required-authority behavior change, requires `migrate_on_start = true` for the older-binary rollback guard, explains the silent metadata-loss risk when that guard is disabled, and carries the fleet gate: never run mixed akhomed versions against one akhomed DB; the first image bump including #655 rolls all houses together. Fix validation (same lean local target; no Docker/image build or full sweep): - `cargo test --locked -p akh-medu --features postgres --bin akh-workspace-recover`: 2 passed. - `cargo test --locked -p akh-medu --features postgres --lib workspace_recovery`: 3 passed; disposable-Postgres integration test remains environment-gated, not rerun for these fixes. - `cargo test --locked -p akh-medu --features server --bin akhomed authoritative_house_refuses_local_fallback_and_missing_snapshot`: 1 passed, including missing/retired/mismatched join refusal and successful existing-identity join. - `cargo clippy --locked -p akh-medu --features server --lib --bin akh-workspace-recover -- -D warnings`, formatting and diff checks passed. - Including `--bin akhomed` in strict clippy reports seven pre-existing warnings in unchanged code: `unnecessary_map_or` (line 1511), `too_many_arguments` (5172), and `collapsible_if` (5315/5316, 6304/6305, 6444). No lint allowances or unrelated cleanup were added; the daemon regression test passes. CI diagnosis (run 4295): the full Forgejo UI log for `test-akh-medu` showed `renamed_database_and_pem_content_are_refused_cold_and_warm` failing its warm-path assertion (3947 passed, 1 failed, 22 ignored). This was a real test-fixture regression, not the sweep/analogy flake. The fixture inherited the runner umask and could create a group-writable directory; ownership validation then correctly refused before the magic-header check. The old binary reproduces the exact failure under umask `0002`. The test-only fix explicitly creates the fixture directory as 0700, matching production restore, and prints the actual refusal on assertion failure. All three local workspace-recovery tests pass under umask `0002` (PG integration remains environment-gated locally); formatting/diff checks pass. No production code, timeouts, or assertions were weakened. `test-session-platform` failed at the same assertion in the disposable PG harness; its rendered Forgejo UI log was interleaved, so the original Solstice step log was checked to confirm this. No separate regression was found there. Both failures are addressed by the same fixture fix. CI: [run 4298](https://code.aopc.cloud/toasterson/akh-medu/actions/runs/4298) is green on `20d233d85d544e727748a023aa8d3c009de51ad6`: all 14 jobs succeeded, including both previously failing test jobs and every platform-image job. Operator reviews/merges; no self-merge. No deployment, production import or volume switch.
feat(core): recover typed workspaces and fence Sokar manifests
Some checks failed
CI / check-seshat (pull_request) Successful in 5m55s
CI / check-akh-medu (pull_request) Successful in 8m8s
CI / publish-chart (pull_request) Successful in 3m37s
CI / test-sokar (pull_request) Successful in 13m15s
CI / platform-images-home (pull_request) Has been cancelled
CI / platform-images-core (pull_request) Has been cancelled
CI / platform-images-daemons (pull_request) Has been cancelled
CI / platform-images-fleet (pull_request) Has been cancelled
CI / platform-images-collect (pull_request) Has been cancelled
CI / test-session-platform (pull_request) Has been cancelled
CI / docker-akh-transcripts (pull_request) Has been cancelled
CI / docker-sokard (pull_request) Has been cancelled
CI / docker-seshd (pull_request) Has been cancelled
CI / test-akh-medu (pull_request) Has been cancelled
360c28c1d6
fix(core): recheck residency after artifact recovery
Some checks failed
CI / test-sokar (pull_request) Successful in 14m17s
CI / docker-sokard (pull_request) Has been cancelled
CI / docker-akh-transcripts (pull_request) Has been cancelled
CI / publish-chart (pull_request) Has been cancelled
CI / platform-images-home (pull_request) Has been cancelled
CI / platform-images-core (pull_request) Has been cancelled
CI / platform-images-daemons (pull_request) Has been cancelled
CI / platform-images-fleet (pull_request) Has been cancelled
CI / platform-images-collect (pull_request) Has been cancelled
CI / test-session-platform (pull_request) Has been cancelled
CI / check-seshat (pull_request) Has been cancelled
CI / check-akh-medu (pull_request) Has been cancelled
CI / test-akh-medu (pull_request) Has been cancelled
CI / docker-seshd (pull_request) Has been cancelled
5095a3a792
fix(core): fence joins and isolate recovery comparison scratch
Some checks failed
CI / test-sokar (pull_request) Successful in 9m23s
CI / check-seshat (pull_request) Successful in 16m57s
CI / docker-seshd (pull_request) Successful in 7m55s
CI / publish-chart (pull_request) Successful in 1m50s
CI / check-akh-medu (pull_request) Successful in 14m15s
CI / test-akh-medu (pull_request) Failing after 15m49s
CI / docker-akh-transcripts (pull_request) Successful in 11m12s
CI / test-session-platform (pull_request) Failing after 31m7s
CI / platform-images-home (pull_request) Has been skipped
CI / platform-images-core (pull_request) Has been skipped
CI / platform-images-daemons (pull_request) Has been skipped
CI / platform-images-fleet (pull_request) Has been cancelled
CI / platform-images-collect (pull_request) Has been cancelled
CI / docker-sokard (pull_request) Has been cancelled
ce0e465926
test(core): make artifact fixture independent of runner umask
All checks were successful
CI / check-seshat (pull_request) Successful in 8m42s
CI / check-akh-medu (pull_request) Successful in 6m57s
CI / docker-seshd (pull_request) Successful in 7m25s
CI / publish-chart (pull_request) Successful in 51s
CI / test-sokar (pull_request) Successful in 21m53s
CI / docker-sokard (pull_request) Successful in 13m38s
CI / test-session-platform (pull_request) Successful in 35m8s
CI / test-akh-medu (pull_request) Successful in 37m47s
CI / docker-akh-transcripts (pull_request) Successful in 33m22s
CI / platform-images-daemons (pull_request) Successful in 1m12s
CI / platform-images-home (pull_request) Successful in 2m56s
CI / platform-images-core (pull_request) Successful in 8m9s
CI / platform-images-fleet (pull_request) Successful in 11m31s
CI / platform-images-collect (pull_request) Successful in 5m59s
20d233d85d
toasterson deleted branch feat/core-workspace-recovery 2026-10-16 07:10:34 +00:00
Sign in to join this conversation.
No reviewers
No labels
follow-up
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
toasterson/akh-medu!655
No description provided.