12 KiB
PSD Server Survey Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Produce a non-mutating, redacted survey of the PSD server that resolves every path, owner, network boundary, credential location, and rollback prerequisite needed by Projects A and B.
Architecture: Collect bounded metadata from the terminal local to the server, retain raw output only in a protected directory, and summarize it in a redacted report. The survey makes no service, file, database, proxy, Authentik, or Git mutation.
Tech Stack: Linux utilities, Docker/Compose inspection, Git, Nginx, OpenSSL, PostgreSQL/Supabase metadata queries, Authentik metadata/API discovery, Aritmolab source inspection.
Safety contract
- Do not run
docker inspectwithout a restrictive Go template; its default output can contain secrets. - Do not run
docker compose configinto chat or a public log. Store raw output mode0600, then create a redacted derivative. - Do not print process environments, secret-file contents, private keys, cookies, tokens, password hashes, or raw OIDC claims.
- Do not reload/restart services, fetch/pull Git, log in interactively, change file modes, or make API mutations.
- When a command needs privilege, use the server's approved CyberArk/local-terminal procedure.
Task 1: Create the protected survey workspace
Files:
- Create:
/var/tmp/thothii-psd-survey.<random>/ - Create: protected
survey-report.md
Step 1: Create a private temporary root
Run:
umask 0077
PSD_SURVEY_ROOT="$(mktemp -d /var/tmp/thothii-psd-survey.XXXXXX)"
test -d "$PSD_SURVEY_ROOT"
chmod 0700 "$PSD_SURVEY_ROOT"
printf '%s\n' "$PSD_SURVEY_ROOT"
Expected: one new mode-0700 directory whose exact path is recorded in the operator journal.
Step 2: Copy the report template
Create $PSD_SURVEY_ROOT/survey-report.md from the headings in the design's Common Survey section.
Record only findings and references to protected raw files.
Task 2: Record host and Docker facts
Files:
- Create:
$PSD_SURVEY_ROOT/host.txt - Create:
$PSD_SURVEY_ROOT/docker-projects.json - Create:
$PSD_SURVEY_ROOT/docker-containers.txt
Step 1: Record bounded host metadata
Run each command with output redirected to $PSD_SURVEY_ROOT/host.txt:
date -u '+%Y-%m-%dT%H:%M:%SZ'
uname -a
cat /etc/os-release
getconf LONG_BIT
nproc
free -h
df -hT
docker version
docker compose version
Expected: no credential content and enough capacity information to judge a parallel source tree and a new five-service stack.
Step 2: Record Compose projects and bounded container identity
Run:
docker compose ls --format json > "$PSD_SURVEY_ROOT/docker-projects.json"
docker ps -a --no-trunc --format '{{json .}}' > "$PSD_SURVEY_ROOT/docker-containers.txt"
docker network ls --format '{{json .}}' > "$PSD_SURVEY_ROOT/docker-networks.txt"
docker volume ls --format '{{json .}}' > "$PSD_SURVEY_ROOT/docker-volumes.txt"
Expected: inventory only. Do not inspect full container JSON.
Step 3: Identify candidate legacy ThothII containers
Use names, images, Compose project labels, published ports, and health from the bounded inventory. For each candidate, query only these templates:
docker inspect --format '{{.Name}} {{.Config.Image}} {{index .Config.Labels "com.docker.compose.project"}} {{index .Config.Labels "com.docker.compose.project.working_dir"}}' <container>
docker inspect --format '{{json .NetworkSettings.Networks}}' <container>
docker inspect --format '{{range .Mounts}}{{.Type}} {{.Source}} -> {{.Destination}} rw={{.RW}}{{println}}{{end}}' <container>
Expected: exact source/Compose ownership and mounts without environment values.
Task 3: Survey the legacy ThothII installation
Files:
- Create:
$PSD_SURVEY_ROOT/legacy-thothii.txt - Create:
$PSD_SURVEY_ROOT/legacy-compose.redacted.yaml
Step 1: Resolve source and operator paths from evidence
Do not search broad filesystem roots. Derive paths from Compose labels, systemd units, Nginx upstreams, and known operator documentation. Record uncertainty rather than guessing.
Step 2: Record source identity without fetching
Run in the identified source tree:
git status --short --branch
git rev-parse HEAD
git remote -v
git log -5 --oneline --decorate
Expected: no mutation. Mark a dirty tree as NO-GO until the owner decides how to preserve it.
Step 3: Record lifecycle state with the legacy controller
If the old installation has a supported tht, run its bounded status, doctor, pi status, and
pi maintenance status commands. Otherwise record exact read-only Docker health and identify the
old lifecycle mechanism. Do not substitute current tht against an incompatible descriptor.
Step 4: Render and redact Compose safely
Store the raw render as mode 0600. Replace secret-bearing scalar values with [redacted] before
using the derivative in analysis. Confirm the redacted render still shows service names, networks,
ports, volumes, image/build identities, and config file paths.
Task 4: Survey Nginx, TLS, and the load balancer
Files:
- Create:
$PSD_SURVEY_ROOT/nginx.raw.txt(protected) - Create:
$PSD_SURVEY_ROOT/nginx-thothii.redacted.txt - Create:
$PSD_SURVEY_ROOT/tls-metadata.txt - Create:
$PSD_SURVEY_ROOT/load-balancer.md
Step 1: Validate and capture Nginx without reload
Run:
sudo nginx -t
sudo nginx -T > "$PSD_SURVEY_ROOT/nginx.raw.txt" 2>&1
chmod 0600 "$PSD_SURVEY_ROOT/nginx.raw.txt"
Expected: configuration test passes. Do not reload Nginx.
Step 2: Extract only relevant directives
Create the redacted derivative containing the ThothII/Aritmolab server_name, listen, location,
proxy_pass, proxy_set_header, proxy_buffering, timeout, certificate path, and include-file
directives. Exclude unrelated virtual hosts and all authorization values.
Step 3: Record certificate metadata only
For each relevant public certificate—not its key—run:
openssl x509 -in <certificate-path> -noout -subject -issuer -serial -dates -ext subjectAltName
Expected: exact SAN/expiry/issuer and the observed generation/renewal mechanism.
Step 4: Map the load balancer
Record its owner, configuration surface, current Aritmolab backend, health check, TLS boundary, source addresses seen by Nginx, and whether it can enforce a temporary hostname allowlist. Do not create a route. If Sol cannot inspect it, name the human/team required for Project A/B gates.
Task 5: Survey Aritmolab and the sidebar integration
Files:
- Create:
$PSD_SURVEY_ROOT/aritmolab.md
Step 1: Resolve the Aritmolab source/deployment
Use Compose labels, Nginx paths, or the documented service unit. Record repository path, SHA, dirty state, deployment command, container/network identity, and configuration owner.
Step 2: Locate the sidebar link
Use rg in the resolved source tree for the current ThothII URL, label, historical
datamart-builder, and sidebar/navigation definitions. Record exact files and line numbers.
Step 3: Resolve the real public origin
The owner reports aritmolab.policlinicosandonato.com; historical project state mentions a .it
origin and /datamart-builder. Record the live browser-visible origin and path from deployed
configuration. Do not choose between them without evidence.
Task 6: Survey Authentik
Files:
- Create:
$PSD_SURVEY_ROOT/authentik.md
Step 1: Identify deployment and version
Record Authentik containers/services, immutable image reference, version, base URL, database/Redis dependencies, configuration owner, and backup/export procedure. Do not print container environments.
Step 2: Locate credential references
Record only file/secret-object paths, ownership, mode, and whether the local operator can use them. If no usable administrative/API credential is found, stop and request owner help.
Step 3: Inventory relevant objects read-only
Using the installed version's API schema or admin interface, list only names/IDs for current Aritmolab applications/providers, authorization flows, property mappings, groups, service accounts, and policies that establish local conventions. Do not retrieve write-only secrets or raw tokens.
Step 4: Record version-specific constraints
Consult the official documentation matching the installed release for OAuth2/OIDC providers, scope/property mappings, application bindings, blueprints/export, and API permission semantics. Do not copy examples from a newer release without comparing the installed OpenAPI schema.
Task 7: Survey Supabase and the PSD DWH
Files:
- Create:
$PSD_SURVEY_ROOT/supabase.md - Create:
$PSD_SURVEY_ROOT/dwh-readonly.txt
Step 1: Map Supabase services without environments
Record PostgreSQL, pooler, PostgREST, gateway, and backup components; container networks and local listeners; database name; TLS listener/CA; and the approved direct-connect route from ThothII core.
Step 2: Record exposed PostgREST schemas
Query only the explicit PostgREST schema setting through its known configuration mechanism. Do not
dump the whole environment. Confirm whether thoth_sessions already exists or is exposed.
Step 3: Inspect schemas and migration state
Through an approved administrative connection, run bounded catalog queries for existing schemas,
owners, and any thoth_sessions tables/migration records. Do not change them.
Step 4: Prove the intended DWH runtime identity is read-only
Connect using the protected runtime credential mechanism and query current_database(),
current_user, and grants for schema datawarehouse. Expected: USAGE/SELECT as required and no
INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, or ownership privileges. Do not run a
write probe against clinical tables.
Step 5: Identify session-schema roles
Record names or naming rules for a future migrator and runtime role. Do not create them. The final
design uses the existing database plus schema thoth_sessions, never a new database.
Task 8: Survey Git workspace and model boundaries
Files:
- Create:
$PSD_SURVEY_ROOT/workspace-and-models.md
Step 1: Inspect the workspace remote read-only
Record remote URL, branch, fetch credential path, current remote SHA, catalog entry, descriptor
schema version, current supported_transports, Evidence tree, annotations blob, and deploy-key
permissions. Do not push with the server's read-only deployment credential.
Step 2: Inspect Pi/LLM policy
Record selected provider/model/thinking level and credential references. Use bounded tht pi status
and pi doctor where compatible. Do not output provider keys.
Step 3: Check internal semantic capacity
Record CPU/GPU availability, free storage, and whether Docker can run the pinned Qdrant and Ollama architectures. Do not pull images or models during the survey.
Task 9: Produce the survey decision
Files:
- Modify:
$PSD_SURVEY_ROOT/survey-report.md
Step 1: Complete the topology
Include exact component owners and flows for user → load balancer → Nginx → Aritmolab/sidebar → ThothII, and core → Supabase DWH/auth session schema/Qdrant/Ollama/LLM/Authentik.
Step 2: List exact intended change files
Separate files owned by the new ThothII installation, workspace curator, Nginx, load balancer, Aritmolab, Authentik, and Supabase. Mark shared files as owner-gated.
Step 3: State GO or NO-GO
GO requires all mandatory paths, permissions, backup owners, and rollback boundaries. NO-GO must name concrete missing facts and the person/system needed to resolve them.
Step 4: Hash and retain the report
Run:
sha256sum "$PSD_SURVEY_ROOT/survey-report.md" > "$PSD_SURVEY_ROOT/survey-report.sha256"
sha256sum --check "$PSD_SURVEY_ROOT/survey-report.sha256"
Expected: checksum passes. Move the complete mode-0700 survey directory to the approved protected evidence root without changing its contents; record the final path and digest in the journal.