docs: plan PSD server deployment program
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
# 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 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.<random>/`
|
||||
- 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"}}' <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:
|
||||
|
||||
```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 <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:
|
||||
|
||||
```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.
|
||||
Reference in New Issue
Block a user