All runbooks
evidenceuai-explorerredacted view

Sandbox Verification And Migration-Ready Evidence

Synced UAI Explorer evidence documentation from docs/evidence/sandbox-verification-2026-06-20.md.

Updated 2026-06-21·Freshness: Reference·Sensitive tokens or credentials were hidden before display.

Sandbox Verification And Migration-Ready Evidence

Date: 2026-06-20 Timezone: America/St_Johns

Supersession note: this remains the historical sandbox verification record. Production CT 121 was later cut over internally to public-safe 0.2.3 on 2026-06-21. Current production state is recorded in [REDACTED:high-entropy].md.

Scope

Final sandbox verification for UAI Explorer public-safe v1.

This evidence stops at migration-ready. It does not authorize production cutover, DNS, TLS, firewall, reverse-proxy, or NetBird exposure changes.

Environment

  • Workstation: NUC-IPEX
  • Project path: C:\Users\scott\uai-explorer
  • Proxmox host: 10.0.0.250
  • Sandbox CT: 126
  • Sandbox IP: 10.0.0.126
  • Sandbox app version after refresh: 0.2.3
  • Production CT: 121
  • Production app version observed after sandbox work: 0.1.0

Local Build Verification

Commands:

python -m py_compile server.py
python tests\test_public_safe.py
& "C:\Program Files\Git\bin\bash.exe" -n deploy-sandbox.sh

Result:

  • Pass.
  • Automated suite ran 8 tests.
  • Coverage included auth, tag authorization, code tag separation, AI API separation, redaction, path refusal, migration evidence checks, and readiness stop-line behavior.

Sandbox Deploy Verification

Command:

& "C:\Program Files\Git\bin\bash.exe" deploy-sandbox.sh

Result:

  • Pass.
  • CT 126 rebuilt as uai-explorer-sandbox.
  • CT 126 remained onboot=0.
  • CT 126 tags: do-not-public;sandbox;uai-explorer.
  • No production cutover occurred.

Health checks:

{"status":"ok","version":"0.2.1"}
{"status":"ready","version":"0.2.1","public_safe_mode":true,"data_root_exists":true,"db_exists":true,"user_count":1,"catalog_count":7,"redaction_enabled":true}

Production health after deploy:

{"status":"ok","version":"0.1.0"}

Sandbox Automated QA/QC

Command:

ssh root@10.0.0.250 "pct exec 126 -- bash -lc 'cd /opt/uai-explorer && . venv/bin/activate && python tests/test_public_safe.py'"

Result:

  • Pass.
  • 8 tests run in sandbox.

Sandbox App Refresh Verification

The existing CT 126 sandbox was refreshed non-destructively from local build 0.2.2. The refresh preserved the sandbox runtime .env, SQLite database, curated data, uploads directory, and virtual environment. No production container, DNS, TLS, firewall, reverse-proxy, or public route was changed.

Pre-refresh state:

CT 126 service: active
CT 126 server.py: VERSION = "0.2.1"
CT 126 health: {"status":"ok","version":"0.2.1"}
CT 121 health: {"status":"ok","version":"0.1.0"}

Refresh command pattern:

tar -czf "$env:TEMP\uai-explorer-refresh.tar.gz" `
  --exclude=.git --exclude=.playwright-cli --exclude=__pycache__ `
  --exclude=data --exclude=uploads --exclude=raw-survey-zone --exclude=test-data `
  server.py requirements.txt uai-explorer.service README.md AGENTS.md `
  UAI_EXPLORER_RULES.md static docs tests
scp -o ProxyJump=root@10.0.0.103 "$env:TEMP\uai-explorer-refresh.tar.gz" `
  root@10.0.0.250:/tmp/uai-explorer-refresh.tar.gz
ssh -J root@10.0.0.103 root@10.0.0.250 "pct push 126 /tmp/uai-explorer-refresh.tar.gz /tmp/uai-explorer-refresh.tar.gz"
ssh -J root@10.0.0.103 root@10.0.0.250 "pct exec 126 -- rsync -a --delete --exclude=.env --exclude=data --exclude=uploads --exclude='*.sqlite3' --exclude=venv /tmp/uai-explorer-refresh/ /opt/uai-explorer/"
ssh -J root@10.0.0.103 root@10.0.0.250 "pct exec 126 -- bash -lc 'cd /opt/uai-explorer && . venv/bin/activate && pip install --no-cache-dir -r requirements.txt && systemctl restart uai-explorer'"

Post-refresh checks:

CT 126 service: active
CT 126 server.py: VERSION = "0.2.2"
CT 126 preserved: ENV_PRESENT, DATA_PRESENT, UPLOADS_PRESENT, DB_PRESENT
CT 126 health: {"status":"ok","version":"0.2.2"}
CT 126 readiness: ready, public_safe_mode=true, catalog_count=7,
raw_survey_zone_mounted=false, raw_survey_mounts_detected=0
CT 121 health: {"status":"ok","version":"0.1.0"}

Served UI checks:

/              200, contains "Collection Shelf"
/js/app.js     200, contains "collection-shelf" and "0.2.2"
/css/style.css 200, contains collection shelf styles

In-container automated QA/QC after refresh:

ssh -J root@10.0.0.103 root@10.0.0.250 "pct exec 126 -- bash -lc 'cd /opt/uai-explorer && . venv/bin/activate && python -m py_compile server.py tests/test_public_safe.py && python tests/test_public_safe.py'"

Result:

  • Pass.
  • 12 tests run in CT 126 after the sanitized-export worker tooling was packaged into the sandbox.
  • Coverage included public-safe refusals for legacy filesystem, raw download, upload endpoints, context-note redaction, and the raw survey mount readiness guard.
  • The sandbox package includes tools/sanitize_survey_export.py and tests/test_sanitized_export.py.
  • Generated sanitized export artifacts were not copied into CT 126; the sandbox remains a curated app/runtime surface, not a raw or generated export mirror.

Live authenticated smoke after refresh used the sandbox runtime credential from .env without printing it.

Observed result:

login_status 200
me_status 200 role admin
catalog_status 200 catalog_count 7
content_status 200
ai_context_status 200 has_audit True
audit_status 200 audit_count 5
readiness_status 200 migration_ready True
public_safe_refusal /api/tree 403
public_safe_refusal /api/raw?path=README.md 403
public_safe_refusal /api/uploads 403

The admin readiness evidence rows were updated through the app API after the refresh. The readiness endpoint returned migration_ready=true and kept production_cutover at not-authorized.

Live HTTP Smoke

Authenticated live smoke was run inside CT 126 against http://127.0.0.1:8080 using the sandbox runtime credential from .env without printing the credential.

Observed result:

{
  "login_status": 200,
  "me_status": 200,
  "role": "admin",
  "catalog_status": 200,
  "catalog_count": 7,
  "content_status": 200,
  "ai_context_status": 200,
  "audit_status": 200,
  "readiness_status": 200,
  "migration_ready_before_manual_evidence": false
}

Interpretation:

  • Auth works.
  • Catalog is seeded.
  • Redacted content path works.
  • AI context endpoint works for admin/AI surface.
  • Audit is writing.
  • Readiness correctly required manual sandbox evidence before being marked migration-ready.

Browser QoL Evidence

Browser checks confirmed:

  • Login screen rendered.
  • Authenticated catalog rendered seeded documentation.
  • Reader rendered metadata, redaction state, document content, and context notes area.
  • Admin panel rendered user and catalog management surfaces.
  • AI Context rendered AI-visible entries and context packets with audit IDs.
  • Final readiness panel rendered Migration ready.
  • Final readiness panel kept production_cutover at not-authorized.
  • Browser console returned no warnings or errors during the final readiness panel check.

Responsive check previously captured against the same frontend shell:

{
  "viewportWidth": 390,
  "bodyScrollWidth": 390,
  "documentScrollWidth": 390,
  "hasHorizontalOverflow": false,
  "sidebarPosition": "fixed",
  "sidebarTransform": "matrix(1, 0, 0, 1, -280, 0)",
  "topbarDisplay": "flex",
  "mainWidth": 390
}

Note: the final backend readiness patch did not change frontend layout or CSS. The final in-app browser mobile retry was interrupted by tooling metadata, so the evidence above is the retained mobile layout record.

Rollback Rehearsal

Sandbox-only rollback rehearsal:

  • Snapshot created: migration-ready-20260620-081634
  • Snapshot description: UAI Explorer 0.2.1 sandbox migration readiness rollback rehearsal baseline
  • Marker file created after snapshot.
  • CT 126 rolled back to the snapshot.
  • Marker file was absent after rollback.
  • CT 126 returned healthy on 0.2.1.
  • CT 121 remained healthy on 0.1.0.

Current 0.2.2 sandbox-only rollback rehearsal:

  • Snapshot created: mr022g-20260620-191542
  • Snapshot description: UAI Explorer 0.2.2 sandbox readiness with raw survey mount guard
  • Marker file created after snapshot.
  • CT 126 rolled back to the snapshot.
  • CT 126 required an explicit pct start 126 after rollback.
  • Marker file was absent after rollback and restart.
  • CT 126 returned healthy on 0.2.2.
  • CT 121 remained healthy on 0.1.0.
  • Proxmox emitted thin-pool overcommit/free-space warnings during snapshot creation. The app rollback rehearsal still passed, but the storage warning should be treated as a lab maintenance risk.
  • After the snapshot, CT 126 was refreshed with tool-only sanitized-export support and verified with the 12-test suite. A new snapshot was not created for that tool-only refresh because of the Proxmox thin-pool warning.
  • CT 126 was later refreshed again with the selected artifact redaction worker, its tests, and updated runbooks/evidence. In-container py_compile and unittest discovery passed with 14 tests. A new snapshot was not created for this tool/documentation refresh because the same Proxmox thin-pool warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with START_HERE_AI.md, the device survey worker, its tests, and NUC-IPEX survey evidence. In-container py_compile and unittest discovery passed with 16 tests. A new snapshot was not created for this tool/documentation refresh because the same Proxmox thin-pool warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with the MacBook-Air survey evidence and the updated device survey worker target/access-outcome fields. In-container py_compile and unittest discovery passed with 16 tests. A new snapshot was not created for this documentation/tool refresh because the same Proxmox thin-pool warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with the device survey index, lab storage/device visibility evidence, and sandbox storage preflight guidance. In-container py_compile and unittest discovery passed with 16 tests. A new snapshot was not created because the Proxmox thin-pool/VG free-space warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with the repeatable device survey index builder, its tests, updated runbooks, and regenerated survey index. In-container py_compile and unittest discovery passed with 18 tests. A new snapshot was not created because the Proxmox thin-pool/VG free-space warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with START_HERE_UAI_LAB.md, the device AI start-here refresh runbook, and matching evidence. In-container py_compile and unittest discovery passed with 18 tests. A new snapshot was not created because the Proxmox thin-pool/VG free-space warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with the lab node identity survey, regenerated device survey index, and updated START_HERE_UAI_LAB.md reflecting the classified HomeLab nodes. In-container py_compile and unittest discovery passed with 18 tests. A new snapshot was not created because the Proxmox thin-pool/VG free-space warning remains a lab maintenance risk.
  • CT 126 was later refreshed again with the Proxmox storage review evidence, storage maintenance runbook, regenerated device survey index, and updated START_HERE_UAI_LAB.md reflecting the storage policy blocker. In-container py_compile and unittest discovery passed with 18 tests. A new snapshot was not created because storage policy now requires operator approval before snapshot-heavy work.
  • CT 126 was later refreshed again with the completion audit and operator decision brief. In-container py_compile and unittest discovery passed with 18 tests. A new snapshot was not created because the audit confirms the remaining work requires operator decisions or external device availability.
  • CT 126 was later refreshed again with the content promotion packet, content promotion workflow, helper, and tests. In-container py_compile and unittest discovery passed with 20 tests. A new snapshot was not created because remaining content promotion requires operator private selection.
  • CT 126 was later refreshed again with the 0.2.3 UX/auth polish: the dashboard now treats the content promotion packet as the next operator workflow, MacBook-Air as surveyed metadata, Zenbook as closed survey metadata, and CT 126 as current. Browser boot uses a non-error session probe. In-container py_compile and unittest discovery passed with 21 tests. A new snapshot was not created because storage and production cutover still require operator approval.
  • CT 126 was later refreshed again with the catalog import approval gate, tools/prepare_catalog_import.py, tests/test_prepare_catalog_import.py, and updated content-promotion workflow docs. In-container py_compile and unittest discovery passed with 24 tests. A new snapshot was not created because real catalog import still requires operator-selected raw candidates, private approval, and production/cutover authority.
  • CT 126 was later refreshed again with approved catalog staging, tools/stage_approved_catalog.py, tests/test_stage_approved_catalog.py, and updated workflow docs. In-container py_compile and unittest discovery passed with 27 tests. A new snapshot was not created because production catalog import still requires operator authority and the Proxmox storage maintenance decision remains open.
  • CT 126 was later refreshed again with explicit staged catalog import, tools/import_staged_catalog.py, tests/test_import_staged_catalog.py, and updated workflow docs. In-container py_compile and unittest discovery passed with 30 tests. A new snapshot was not created because real catalog content selection and production import authority still require operator approval.
  • CT 126 was later refreshed again with the generated finish status packet, tools/build_finish_status_packet.py, tests/test_build_finish_status_packet.py, and updated first-read docs. In-container py_compile and unittest discovery passed with 33 tests. A new snapshot was not created because the packet is a handoff/evidence refresh and production authority is still not granted.
  • CT 126 was later refreshed again with the generated operator decision intake packet, tools/build_operator_decision_packet.py, [REDACTED:high-entropy].py, and updated first-read docs. In-container py_compile and unittest discovery passed with 36 tests. A new snapshot was not created because the packet is an intake/evidence refresh and production authority is still not granted.
  • CT 126 was later refreshed again with the operator decision response validator, [REDACTED:high-entropy].py, [REDACTED:high-entropy].py, a defer-all response template, and validation output. In-container py_compile and unittest discovery passed with 41 tests. A new snapshot was not created because the validation result grants no production, storage, raw-content, or catalog-apply authority.
  • CT 126 was later refreshed again after closing Zenbook as a UAI Explorer survey follow-up. The refresh updated status docs, dashboard copy, packet generators, and decision validators so Zenbook is no longer an open decision. In-container py_compile and unittest discovery passed with 42 tests. A new snapshot was not created because this was a documentation/status correction and storage policy still requires operator approval before snapshot-heavy work.

Snapshot listing:

`-> migration-ready-20260620-081634 2026-06-20 08:16:35     UAI Explorer 0.2.1 sandbox migration readiness rollback rehearsal baseline
 `-> mr022-20260620-190655      2026-06-20 19:06:57     UAI Explorer 0.2.2 sandbox migration readiness rollback rehearsal baseline
  `-> mr022g-20260620-191542    2026-06-20 19:15:43     UAI Explorer 0.2.2 sandbox readiness with raw survey mount guard
   `-> current                                          You are here!

Readiness Evidence Recorded In App

Manual evidence checks were recorded through the admin readiness API. The readiness endpoint returned:

{
  "migration_ready": true,
  "statuses": {
    "auth_enabled": "pass",
    "catalog_seeded": "pass",
    "redaction_enabled": "pass",
    "audit_enabled": "pass",
    "sandbox_deployed": "pass",
    "qa_qc_qol_evidence": "pass",
    "backup_rollback_rehearsal": "pass",
    "production_health_verified": "pass",
    "production_cutover": "not-authorized"
  }
}

After the selected redaction worker refresh, CT 126 readiness returned raw_survey_zone_mounted=false, raw_survey_mounts_detected=0, and [REDACTED:high-entropy]. The worker file and test file were present in /opt/uai-explorer, generated sanitized-exports were absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the device survey worker refresh, CT 126 readiness again returned raw_survey_zone_mounted=false, raw_survey_mounts_detected=0, and [REDACTED:high-entropy]. START_HERE_AI.md, tools/survey_device_documents.py, and tests/test_survey_device_documents.py were present in /opt/uai-explorer; generated raw-survey-zone and sanitized-exports directories were absent from the container; CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the MacBook-Air survey evidence refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 16 tests, generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the device survey index and lab storage evidence refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 16 tests, generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the device survey index builder refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 18 tests, tools/build_device_survey_index.py and tests/test_build_device_survey_index.py were present in /opt/uai-explorer, generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the device AI start-here refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 18 tests, START_HERE_UAI_LAB.md and [REDACTED:high-entropy].md were present in /opt/uai-explorer, generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the lab node identity survey refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 18 tests, [REDACTED:high-entropy].md was present in /opt/uai-explorer, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the Proxmox storage review refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 18 tests, [REDACTED:high-entropy].md and [REDACTED:high-entropy].md were present in /opt/uai-explorer, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the completion audit refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 18 tests, [REDACTED:high-entropy].md and docs/runbooks/operator-decision-brief.md were present in /opt/uai-explorer, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the content promotion packet refresh, CT 126 still returned ready on 0.2.2, in-container unittest discovery passed with 20 tests, tools/build_content_promotion_packet.py, tests/test_content_promotion_packet.py, [REDACTED:high-entropy].md, [REDACTED:high-entropy].md, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the 0.2.3 UX/auth refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 21 tests, /api/auth/session returned a non-error anonymous session state while /api/auth/me remained protected, the dashboard rendered the promotion packet, MacBook-Air surveyed state, Zenbook closed survey state, and CT 126 current state without browser console errors. Desktop and mobile Playwright checks showed no horizontal overflow. START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the catalog import approval-gate refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 24 tests, tools/prepare_catalog_import.py, tests/test_prepare_catalog_import.py, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.prepare_catalog_import and tools.redact_selected_artifacts passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the approved catalog staging refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 27 tests, tools/stage_approved_catalog.py, tests/test_stage_approved_catalog.py, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.stage_approved_catalog, tools.prepare_catalog_import, and tools.redact_selected_artifacts passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the staged catalog import refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 30 tests, tools/import_staged_catalog.py, tests/test_import_staged_catalog.py, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.import_staged_catalog, tools.stage_approved_catalog, tools.prepare_catalog_import, and tools.redact_selected_artifacts passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the finish status packet refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 33 tests, tools/build_finish_status_packet.py, tests/test_build_finish_status_packet.py, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.build_finish_status_packet, tools.import_staged_catalog, and tools.stage_approved_catalog passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the operator decision intake refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 36 tests, tools/build_operator_decision_packet.py, [REDACTED:high-entropy].py, [REDACTED:high-entropy].md, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.build_operator_decision_packet, tools.build_finish_status_packet, and tools.import_staged_catalog passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the operator decision response validation refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 41 tests, [REDACTED:high-entropy].py, [REDACTED:high-entropy].py, [REDACTED:high-entropy].json, [REDACTED:high-entropy].json, and [REDACTED:high-entropy].md were present in /opt/uai-explorer, package-style imports for tools.validate_operator_decision_response, tools.build_operator_decision_packet, and tools.build_finish_status_packet passed, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], generated raw-survey-zone and sanitized-exports directories remained absent from the container, and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

After the Zenbook status correction refresh, CT 126 returned ready on 0.2.3, in-container unittest discovery passed with 42 tests, generated raw-survey-zone and sanitized-exports directories remained absent from the container, START_HERE_UAI_LAB.md had hash [REDACTED:high-entropy], and CT 121 production health still returned {"status":"ok","version":"0.1.0"}.

Final Status

Status: migration-ready on sandbox CT 126 with UAI Explorer 0.2.3.

Not done:

  • Production cutover.
  • Public DNS/TLS/firewall/routing changes.
  • Production user/tag seeding.
  • Production data migration.

Those require a separate operator-approved cutover runbook execution.