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
126rebuilt asuai-explorer-sandbox. - CT
126remainedonboot=0. - CT
126tags: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
126after 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.pyandtests/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_cutoveratnot-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
126rolled back to the snapshot. - Marker file was absent after rollback.
- CT
126returned healthy on0.2.1. - CT
121remained healthy on0.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
126rolled back to the snapshot. - CT
126required an explicitpct start 126after rollback. - Marker file was absent after rollback and restart.
- CT
126returned healthy on0.2.2. - CT
121remained healthy on0.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
126was 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
126was later refreshed again with the selected artifact redaction worker, its tests, and updated runbooks/evidence. In-containerpy_compileand 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
126was later refreshed again withSTART_HERE_AI.md, the device survey worker, its tests, and NUC-IPEX survey evidence. In-containerpy_compileand 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
126was later refreshed again with the MacBook-Air survey evidence and the updated device survey worker target/access-outcome fields. In-containerpy_compileand 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
126was later refreshed again with the device survey index, lab storage/device visibility evidence, and sandbox storage preflight guidance. In-containerpy_compileand 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
126was later refreshed again with the repeatable device survey index builder, its tests, updated runbooks, and regenerated survey index. In-containerpy_compileand 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
126was later refreshed again withSTART_HERE_UAI_LAB.md, the device AI start-here refresh runbook, and matching evidence. In-containerpy_compileand 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
126was later refreshed again with the lab node identity survey, regenerated device survey index, and updatedSTART_HERE_UAI_LAB.mdreflecting the classified HomeLab nodes. In-containerpy_compileand 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
126was later refreshed again with the Proxmox storage review evidence, storage maintenance runbook, regenerated device survey index, and updatedSTART_HERE_UAI_LAB.mdreflecting the storage policy blocker. In-containerpy_compileand unittest discovery passed with 18 tests. A new snapshot was not created because storage policy now requires operator approval before snapshot-heavy work. - CT
126was later refreshed again with the completion audit and operator decision brief. In-containerpy_compileand 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
126was later refreshed again with the content promotion packet, content promotion workflow, helper, and tests. In-containerpy_compileand unittest discovery passed with 20 tests. A new snapshot was not created because remaining content promotion requires operator private selection. - CT
126was later refreshed again with the0.2.3UX/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 CT126as current. Browser boot uses a non-error session probe. In-containerpy_compileand unittest discovery passed with 21 tests. A new snapshot was not created because storage and production cutover still require operator approval. - CT
126was 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-containerpy_compileand 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
126was later refreshed again with approved catalog staging,tools/stage_approved_catalog.py,tests/test_stage_approved_catalog.py, and updated workflow docs. In-containerpy_compileand 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
126was later refreshed again with explicit staged catalog import,tools/import_staged_catalog.py,tests/test_import_staged_catalog.py, and updated workflow docs. In-containerpy_compileand 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
126was 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-containerpy_compileand 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
126was 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-containerpy_compileand 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
126was 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-containerpy_compileand 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
126was 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-containerpy_compileand 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.