# PSD Server Survey Implementation Plan > **For agentic workers:** execute one task at a time, record its completion criteria, and stop at every documented approval boundary. **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 inspect` without a restrictive Go template; its default output can contain secrets. - Do not run `docker compose config` into chat or a public log. Store raw output mode `0600`, 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./` - Create: protected `survey-report.md` **Step 1: Create a private temporary root** Run: ```bash 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`: ```bash 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: ```bash 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: ```bash docker inspect --format '{{.Name}} {{.Config.Image}} {{index .Config.Labels "com.docker.compose.project"}} {{index .Config.Labels "com.docker.compose.project.working_dir"}}' docker inspect --format '{{json .NetworkSettings.Networks}}' docker inspect --format '{{range .Mounts}}{{.Type}} {{.Source}} -> {{.Destination}} rw={{.RW}}{{println}}{{end}}' ``` 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: ```bash 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: ```bash 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: ```bash openssl x509 -in -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 the scoped GO or NO-GO decisions** State both `SURVEY_GO_PROJECT_A_PRIVATE` and `SURVEY_GO_PROJECT_B`. The private decision requires all paths, permissions, backup owners and rollback boundaries used by Project A; it may defer public-origin, load-balancer, Authentik and Mac REST closeout facts that Project A does not mutate. The Project B decision requires every shared/public fact plus the Mac acceptance, completed observation window and revoked legacy credential. Each NO-GO must name concrete missing facts and the person/system needed to resolve them. **Step 4: Hash and retain the report** Run: ```bash 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.