diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 32225972..5f5fd6a5 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -7,10 +7,40 @@ > ThothII per il repository (app + CLI `tht`), (3) come usare l'applicazione ThothII di base > (sessioni, domande, gate). Il documento userà parole semplici ed esempi; i dettagli tecnici > resteranno nei contratti esistenti. Esempio pratico completo: Policlinico San Donato. -> Last updated: 2026-08-18 (final-review fix round 2 recorded; native Windows authentication gate -> passed, remediation is complete, and unrelated release gates remain open). +> Last updated: 2026-08-20 (PSD server replacement and Authentik-integration program designed; +> executable survey, two gated project plans, human-test guides, and evidence templates prepared; +> no server mutation has been executed). > Point a fresh session here ("read PROJECT_STATE.md") before substantial work. +### PSD server deployment program — design approved, execution PENDING (2026-08-20) + +- **Approved design:** `docs/plans/2026-08-20-psd-server-deployment-program-design.md`; design + commit `3fd177b`. The owner approved a common read-only survey followed by two independently + accepted projects: A installs/proves a private local-auth stack through F1-F8; B starts only + after A PASS and integrates Supabase schema storage, Authentik OIDC, Nginx, the load balancer, + and the existing Aritmolab sidebar journey. +- **Executable entrypoint:** `docs/plans/2026-08-20-psd-server-deployment-program.md`, with separate + plans for the survey, Project A, and Project B. The server-local Sol agent must execute them with + `superpowers:executing-plans`, checkpointing every verified step and stopping on the documented + owner/secret/rollback boundaries. +- **Human gates:** `docs/testing/psd-server-project-a-manual.md` and + `docs/testing/psd-server-project-b-manual.md`; survey and Project A/B report templates are under + `docs/testing/evidence/`. Automated evidence never substitutes for the two explicit human PASS + decisions. +- **Workspace decision:** keep one `psd-clinical` descriptor in `tht-workspace-psd`; publish + `supported_transports: [rest_api, postgres_direct]`. Mac selects REST, server selects direct; + all installation bindings/secrets remain outside Git. +- **Data/runtime decision:** migrate configuration only. Legacy work sessions, Qdrant indexes, and + Ollama cache are not imported. Project A rebuilds internal Qdrant/Ollama and uses filesystem work + sessions. Project B uses the existing Supabase PostgreSQL database with isolated schema + `thoth_sessions`, dedicated migrator/runtime roles, forced RLS, and no PostgREST exposure. +- **Network/auth decision:** no SSH tunnel. Project A is loopback-only unless the surveyed load + balancer can prove an operator-only temporary endpoint. Project B preserves the real user flow + `Aritmolab homepage -> sidebar -> load balancer -> Nginx -> ThothII`, with direct ThothII-managed + OIDC and no second Nginx `auth_request`. +- **State:** survey `PENDING`; Project A `PENDING`; Project B `BLOCKED_BY_PROJECT_A`; server and + external repositories/services unchanged by this planning work. + ### Authentication final-review fix round 2 — remediation PASS, release gates remain (2026-08-18) - Frozen source is `2a9359071257f9b8a71d36ec2bbb25b161003f81` on `feat/thoth-auth`. diff --git a/docs/plans/2026-08-20-psd-server-deployment-program.md b/docs/plans/2026-08-20-psd-server-deployment-program.md new file mode 100644 index 00000000..e469e908 --- /dev/null +++ b/docs/plans/2026-08-20-psd-server-deployment-program.md @@ -0,0 +1,220 @@ +# PSD Server Deployment Program Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Replace the legacy PSD ThothII installation, prove the replacement with local authentication, and then integrate the accepted release with Supabase, Authentik, Nginx, the load balancer, and the Aritmolab sidebar. + +**Architecture:** A read-only common survey freezes the actual server topology before any mutation. Project A installs a clean private stack and proves a complete PSD workflow; Project B begins only after a signed Project A PASS and performs the public OIDC/SSO cutover. Each project has an independent rollback boundary, human test guide, and evidence report. + +**Tech Stack:** Linux, Docker Engine, Docker Compose v2, native `tht`, Fastify/React/Pi, PostgreSQL/Supabase, Qdrant, Ollama, Nginx, Authentik OIDC, Aritmolab, load balancer. + +--- + +## Required reading and authority + +Read these files completely before starting: + +- `AGENTS.md` +- `PROJECT_STATE.md` +- `docs/plans/2026-08-20-psd-server-deployment-program-design.md` +- `docs/install/server.md` +- `docs/install/server-workspace-registry.md` +- `docs/install/authentication-local.md` +- `docs/install/authentication-oidc.md` +- `docs/install/authentik.md` +- `docs/contracts/workspace-preprocessing-cli.md` +- `docs/testing/authentication-manual-acceptance.md` + +The current `compose.yaml`, `deploy/compose.server.yaml`, repository instructions, and design are +authoritative where older server prose still describes Qdrant or Ollama as external. + +Run only from a terminal local to the server. Do not require SSH port forwarding. Do not print or +paste passwords, tokens, cookies, private keys, hashes, or raw identity claims. Commands that need +a credential must read a protected file or use an echo-free prompt. + +## Documents used during execution + +- Survey plan: `docs/plans/2026-08-20-psd-server-survey.md` +- Survey report: `docs/testing/evidence/psd-server-survey-report-template.md` +- Project A plan: `docs/plans/2026-08-20-psd-server-project-a-standalone.md` +- Project A human guide: `docs/testing/psd-server-project-a-manual.md` +- Project A report: `docs/testing/evidence/psd-server-project-a-report-template.md` +- Project B plan: `docs/plans/2026-08-20-psd-server-project-b-authentik.md` +- Project B human guide: `docs/testing/psd-server-project-b-manual.md` +- Project B report: `docs/testing/evidence/psd-server-project-b-report-template.md` + +The detailed evidence directory is a protected path on the server selected during the survey. The +repository receives only redacted reports after explicit owner review. + +### Task 1: Freeze the planning source + +**Files:** +- Read: `docs/plans/2026-08-20-psd-server-deployment-program-design.md` +- Record: protected server execution journal selected during the survey + +**Step 1: Verify the application checkout** + +Run: + +```bash +git status --short --branch +git rev-parse HEAD +git rev-parse origin/main +git show -s --format='%H%n%P%n%s' HEAD +``` + +Expected: the tree is clean and `HEAD` is the explicitly approved `origin/main` SHA. A newer SHA +than the design-time `5c0dc8c` is allowed only after recording and reviewing the intervening commits. + +**Step 2: Verify the plan files exist at that SHA** + +Run: + +```bash +test -f docs/plans/2026-08-20-psd-server-survey.md +test -f docs/plans/2026-08-20-psd-server-project-a-standalone.md +test -f docs/plans/2026-08-20-psd-server-project-b-authentik.md +git diff --check +``` + +Expected: every command exits zero. + +**Step 3: Record the immutable planning identity** + +Record the application SHA, plan commit, UTC timestamp, operator identity, and terminal-local access +method in the protected journal. Do not record CyberArk session secrets or screenshots. + +### Task 2: Execute and approve the common survey + +**Files:** +- Execute: `docs/plans/2026-08-20-psd-server-survey.md` +- Create from: `docs/testing/evidence/psd-server-survey-report-template.md` + +**Step 1: Execute every survey task without mutation** + +Expected: the survey identifies exact paths and owners for the old and new installations, Nginx, +load balancer, Aritmolab, Authentik, Supabase, the DWH, and protected credentials. + +**Step 2: Resolve every unknown** + +If an Authentik credential cannot be located, stop and ask the owner. If a configuration owner or +rollback boundary is unclear, stop; do not infer authority from file readability. + +**Step 3: Review the survey GO/NO-GO** + +Expected: GO requires a verified old-stack recovery path, a new-installation root, enough resources, +a read-only DWH path, and no unresolved shared-infrastructure mutation. + +**Step 4: Checkpoint the survey** + +Hash the protected report and record only its path, SHA-256, timestamp, and GO result in the journal. + +### Task 3: Execute Project A + +**Files:** +- Execute: `docs/plans/2026-08-20-psd-server-project-a-standalone.md` +- Complete: `docs/testing/evidence/psd-server-project-a-report-template.md` + +**Step 1: Confirm the survey is GO** + +Expected: the survey report hash matches the journal and no unresolved blocker remains. + +**Step 2: Execute Project A task-by-task** + +Do not configure Authentik, change the production Aritmolab sidebar, or open the production route. + +**Step 3: Run the Project A human guide** + +Follow `docs/testing/psd-server-project-a-manual.md`. Record PASS/FAIL for every case; do not infer +manual PASS from automated output. + +**Step 4: Close the Project A report** + +Expected: automated gates and the human guide are PASS; one harmless PSD session reached F8 and +produced validated read-only SQL; rollback remains available. + +**Step 5: Obtain explicit owner approval** + +Record the approval and report digest. Project B remains forbidden without it. + +### Task 4: Freeze the Project B candidate + +**Files:** +- Read: accepted Project A report +- Record: protected server execution journal + +**Step 1: Recheck source and running images** + +Run the Project A plan's identity commands again. Record application SHA, workspace SHA, core image +ID, frontend image ID, Qdrant image digest, Ollama image digest, and local-auth configuration revision. + +Expected: all values match the accepted Project A report. + +**Step 2: Recheck rollback** + +Prove that the public route is still closed and the protected Project A configuration can be +selected without reconstructing it from memory. + +### Task 5: Execute Project B + +**Files:** +- Execute: `docs/plans/2026-08-20-psd-server-project-b-authentik.md` +- Complete: `docs/testing/evidence/psd-server-project-b-report-template.md` + +**Step 1: Execute Project B task-by-task** + +Keep public traffic closed until Authentik, Supabase migrations, ThothII diagnostics, Nginx, TLS, +and load-balancer preflight all pass. + +**Step 2: Run the Project B human guide** + +Follow `docs/testing/psd-server-project-b-manual.md` using approved ordinary and administrator +identities. The final path begins at the Aritmolab homepage and uses its existing sidebar link. + +**Step 3: Close the Project B report** + +Expected: SSO, roles, PostgreSQL ownership, the F1-F8 session, rollback rehearsal, and cleanup of the +temporary Project A endpoint all pass. + +### Task 6: Close the program + +**Files:** +- Modify: `PROJECT_STATE.md` +- Optionally create: reviewed redacted acceptance reports under `docs/testing/evidence/` + +**Step 1: Reconcile final state** + +Record final SHAs, image identities, workspace revision, Authentik object names/IDs (never secrets), +Supabase database/schema names, public origin, sidebar source revision, Nginx configuration identity, +and both report digests. + +**Step 2: Verify final negative boundaries** + +Expected: old stack stopped; Project A private endpoint removed; core/Qdrant/Ollama not externally +published; `thoth_sessions` absent from PostgREST exposed schemas; no secret appears in reports. + +**Step 3: Update project state** + +Add a dated factual section to `PROJECT_STATE.md`. Mark anything not actually run as PENDING. + +**Step 4: Run documentation checks** + +Run: + +```bash +git diff --check +bash scripts/auth-docs-smoke.sh +bash scripts/verify-workspace-install-docs.sh --fixtures-only +``` + +Expected: all checks pass. + +**Step 5: Commit only reviewed redacted documentation** + +```bash +git add PROJECT_STATE.md docs/testing/evidence +git diff --cached --check +git commit -m "docs: record PSD server deployment acceptance" +``` + +Expected: the commit contains no raw server inventory or secret material. diff --git a/docs/plans/2026-08-20-psd-server-project-a-standalone.md b/docs/plans/2026-08-20-psd-server-project-a-standalone.md new file mode 100644 index 00000000..bec5c6a4 --- /dev/null +++ b/docs/plans/2026-08-20-psd-server-project-a-standalone.md @@ -0,0 +1,500 @@ +# PSD Server Project A Standalone Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Install a clean PSD ThothII stack with local authentication, direct read-only DWH access, internal Qdrant/Ollama, rebuilt preprocessing, and one completed F1-F8 work session. + +**Architecture:** Preserve the stopped legacy installation and deploy the current canonical five-service Compose stack from an adjacent clean clone. A reviewed server-local override disables public exposure and uses filesystem work sessions; an optional load-balancer route is permitted only when it is operator-only and its denial boundary is proved first. + +**Tech Stack:** Git, Docker/Compose, native `tht`, local Argon2id authentication, PSD Supabase PostgreSQL direct transport, Qdrant, Ollama, Pi, Nginx/load-balancer test route where safe. + +--- + +## Preconditions + +- Common survey result is GO and its digest is recorded. +- Every path below is replaced by the exact survey result before execution. +- No production Nginx/load-balancer/sidebar/Authentik change is in scope. +- The old stack remains running only until backup verification finishes; old and new stacks never + run together. +- The server's workspace deploy credential remains read-only. A curator with write access publishes + the workspace change. + +### Task 1: Freeze exact inputs + +**Files:** +- Read: protected survey report +- Read: `docs/plans/2026-08-20-psd-server-deployment-program-design.md` +- Record: protected Project A journal + +**Step 1: Record application identity** + +Run in the new planning checkout: + +```bash +git status --short --branch +git rev-parse HEAD +git rev-parse origin/main +git diff --check +``` + +Expected: clean and explicitly approved SHA. + +**Step 2: Record workspace remote identity** + +Use the surveyed read-only credential and run: + +```bash +git ls-remote refs/heads/main +``` + +Expected: one SHA recorded as the pre-change workspace revision. + +**Step 3: Check old-stack recoverability** + +Expected: exact old start/stop procedure, source SHA, Compose identity, volumes/binds, proxy closure +procedure, and backup destination are present in the survey. Stop if any is missing. + +### Task 2: Publish the multi-transport workspace revision + +**Files:** +- Modify in authorized curator clone: `psd-clinical/workspace.yaml` +- Verify: `thoth-workspaces.yaml` + +**Step 1: Create a clean curator branch** + +Run in a write-authorized clone, never in the application-managed registry checkout: + +```bash +git status --short --branch +git fetch origin main +git switch --create codex/psd-direct-transport origin/main +``` + +Expected: clean branch at the recorded remote SHA. + +**Step 2: Make the minimal descriptor change** + +Change exactly: + +```yaml +supported_transports: [rest_api] +``` + +to: + +```yaml +supported_transports: [rest_api, postgres_direct] +``` + +Do not duplicate the workspace or change its ID, collection, Evidence, annotations, model policy, +database, or schema. + +**Step 3: Review the descriptor-only diff** + +Run: + +```bash +git diff --check +git diff -- psd-clinical/workspace.yaml thoth-workspaces.yaml +``` + +Expected: one semantic line changed; catalog metadata remains identical. + +**Step 4: Validate with the current ThothII contract** + +Use a disposable installation/registry or the repository's current registry validation harness to +activate the candidate commit before publication. Expected: schema v3 accepts both transports, +Evidence and annotations materialize, and no secret is required for source validation. + +If no supported validator can be run in the curator environment, stop and request the owner to run +the established Mac validation; do not publish based only on YAML parsing. + +**Step 5: Commit and publish through curator review** + +```bash +git add psd-clinical/workspace.yaml +git diff --cached --check +git commit -m "feat: support direct PSD DWH transport" +git push --set-upstream origin codex/psd-direct-transport +``` + +Merge through the repository's normal review path. Record the resulting `main` SHA. + +**Step 6: Prove the Mac REST installation is unchanged** + +The owner pulls/activates the new workspace commit on the Mac, confirms selected transport +`rest_api`, runs workspace inspection/connection diagnostics, and records PASS. Project A server +deployment stops if this cross-installation proof is not available. + +### Task 3: Back up and stop the legacy installation + +**Files:** +- Create: surveyed protected legacy backup directory +- Record: Project A journal + +**Step 1: Capture final legacy state** + +Run the surveyed legacy status/doctor commands, record source SHA and image IDs, and confirm no +active user work. Do not use the new `tht` against an incompatible old descriptor. + +**Step 2: Close or maintenance-gate the old ThothII route** + +Change only the surveyed ThothII-specific route using its established mechanism. Validate Nginx and +load-balancer configuration before applying. Confirm external requests no longer reach the app. + +**Step 3: Create the legacy backup** + +Use the surveyed, version-compatible backup procedure. Include source/config metadata and all old +runtime volumes/binds needed to restart; store credentials separately under existing protected +custody. Create SHA-256 checksums and verify them. + +**Step 4: Stop the old stack** + +Use its own supported controller. Expected: old containers stopped, not removed; volumes and bind +trees unchanged. + +**Step 5: Rehearse the restart command without executing it** + +Record the exact command, preconditions, port ownership, and route-restoration order. If it cannot +be stated unambiguously, stop before creating the new stack. + +### Task 4: Prepare the adjacent clean installation + +**Files:** +- Create: survey-selected new source root +- Create: survey-selected operator, secret, data, Pi-state, registry, and backup roots + +**Step 1: Create dedicated identities and paths** + +Follow `docs/install/server.md` ownership rules using the surveyed available UID/GID. Do not reuse a +UID already owned by another service and do not change image UID 10001 without a reviewed mapping. + +**Step 2: Clone the frozen application source** + +```bash +git -c core.autocrlf=false clone /ThothII +git -C /ThothII config --local core.autocrlf false +git -C /ThothII switch --detach +git -C /ThothII status --short --branch +``` + +Expected: detached exact SHA, clean tree. + +**Step 3: Verify source and platform** + +```bash +cd /ThothII +bash scripts/verify-line-endings.sh +docker version +docker compose version +``` + +Expected: all pass. + +**Step 4: Prepare Pi state and build the operator** + +```bash +sudo scripts/prepare-server-pi-state.sh 10001 10001 +THT_THT_OUTPUT_DIRECTORY= bash scripts/build-tht.sh +``` + +Install only the binary matching the surveyed server architecture. Run `tht version --json` and +record its source identity. + +### Task 5: Create the protected Project A configuration + +**Files:** +- Create outside Git: `/server.env` +- Create outside Git: `/thothii-installation.yaml` +- Create outside Git: `/project-a-private.yaml` +- Create outside Git: `/auth.yaml` through `tht` + +**Step 1: Start from current examples** + +Copy `deploy/env/server.env.example` and `docs/install/examples/thothii-installation.server.yaml` +to the protected Project A operator root. Replace every placeholder with surveyed absolute paths. +Never source `server.env` as shell code. + +**Step 2: Add the private/local-session override** + +Create this reviewed override: + +```yaml +services: + core: + environment: + THOTH_PUBLIC_EXPOSURE: "false" + THT_SESSION_STORAGE: local + frontend: + ports: !override + - "127.0.0.1::8080" +``` + +Select an unused loopback port proved by `ss -lntp`. Do not publish core, Qdrant, or Ollama. + +**Step 3: Compose the installation descriptor** + +Use `profile: server`, the exact new source root/env/auth root, workspace remote/branch/read-only +access, Project A override, and exactly one Git transport override. Do not include the public +session-server overlay in Project A. + +**Step 4: Validate permissions and render** + +```bash + --installation update --check-only +``` + +Expected: Compose validates; only frontend has a loopback port; core declares public exposure false +and local session storage; Qdrant/Ollama are internal. + +**Step 5: Configure the local administrator** + +Create a temporary mode-0600 password file using an echo-free prompt, then run: + +```bash + --installation auth configure \ + --mode local --public-url \ + --admin-user --admin-display-name \ + --password-file +``` + +Remove the temporary input file after success and record that removal. Do not delete generated +`auth.yaml` or `users.yaml`. + +### Task 6: Build and start the clean stack + +**Files:** +- Record: Project A evidence directory + +**Step 1: Build current images** + +```bash +cd /ThothII +bash scripts/build-local.sh +``` + +Expected: current core/frontend images build; pinned Qdrant/Ollama references resolve. + +**Step 2: Run preflight** + +```bash + --installation update --check-only + --installation pi doctor +``` + +Expected: no mutation error and no secret in output. + +**Step 3: Start through `tht`** + +```bash + --installation start --build + --installation status + --installation doctor --json + --installation pi test +``` + +Expected: frontend, core, Qdrant, embedding healthy and model initializer completed. Doctor has the +documented ordered checks and authentication PASS. + +**Step 4: Verify listener boundaries** + +Use `ss -lntp` and bounded Docker inspection. Expected: only the selected frontend loopback port is +host-published; no external core, Qdrant, or Ollama listener. + +### Task 7: Activate the workspace and direct DWH binding + +**Files:** +- Modify only through authenticated Workspace Management: encrypted workspace secret store + +**Step 1: Pull and inspect the reviewed workspace revision** + +```bash + --installation \ + workspace inspect --workspace psd-clinical --json +``` + +Expected: active workspace SHA equals the approved multi-transport revision. + +**Step 2: Configure runtime bindings** + +Through the authenticated Workspace Management API/UI, select `postgres_direct` and provide the +surveyed host, port, runtime user, password, and optional TLS CA. Secret values go to the encrypted +vault; they do not enter `server.env`, Git, shell arguments, or evidence. + +The generated contract names are: + +```text +THT_WS_PSD_CLINICAL_DWH_TRANSPORT +THT_WS_PSD_CLINICAL_DWH_HOST +THT_WS_PSD_CLINICAL_DWH_PORT +THT_WS_PSD_CLINICAL_DWH_USER +THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE +THT_WS_PSD_CLINICAL_DWH_TLS_CA_FILE +``` + +**Step 3: Validate and test connections** + +Run static validation, live connection test, workspace inspect, and `doctor --json`. Expected: DWH, +workspace, internal embedding, and Qdrant checks pass with redacted output. + +**Step 4: Re-prove read-only grants** + +Use the survey's catalog query through the exact configured identity. Expected: no DML/DDL grant on +`datawarehouse`. Stop if the runtime user is an owner, superuser, or write-capable role. + +### Task 8: Rebuild and verify semantic preprocessing + +**Files:** +- Create: Project A preprocessing evidence + +**Step 1: Inspect the empty/new collection state** + +```bash + --installation \ + workspace vector inspect --workspace psd-clinical --json +``` + +Expected: either a compatible empty collection or the documented missing-collection state. + +**Step 2: Create the descriptor-owned collection when missing** + +Use the guarded vector rebuild only for collection `psd-clinical`, with exact repeated confirmation +and `--destroy`. Do not run it against any other collection. + +**Step 3: Run complete preprocessing** + +```bash + --installation \ + workspace preprocess run --workspace psd-clinical --json +``` + +If it returns `manual_review_required`, inspect the exact run and curated annotations, obtain the +required human decision, run `workspace schema accept --workspace psd-clinical --run --yes`, +then resume the same run. Never auto-approve unknown FK changes. + +**Step 4: Verify collection contract and counts** + +Run vector inspection and record dimensions, cosine distance, required keyword indexes, and bounded +counts by payload kind/revision. Expected: all points carry the active workspace revision. + +**Step 5: Prove idempotency** + +Run the complete preprocessing command again. Expected: no new review, no duplicate logical points, +unchanged Evidence reported as unchanged, and the same effective configuration identity. + +### Task 9: Configure and test local users + +**Files:** +- Modify through `tht auth user`: protected local user registry + +**Step 1: Add an ordinary test user** + +Use an echo-free prompt or protected temporary password file: + +```bash + --installation auth user add \ + --role user --display-name --password-file +``` + +Remove the temporary input file after success. + +**Step 2: Run authentication diagnostics** + +```bash + --installation auth status --json + --installation auth check --json +``` + +Expected: pristine redacted JSON and PASS. + +**Step 3: Execute automated local-auth cases** + +Use same-origin requests or a local headless browser to prove ordinary/admin authorization, generic +wrong-password failure, disable/enable, password/role revision invalidation, logout-all, CSRF, and +remembered-session survival after core restart. Do not retain cookie jars after the test. + +### Task 10: Optionally add the private network-path test + +**Files:** +- Modify only surveyed test-specific load-balancer/Nginx files +- Create: test certificate through the existing managed mechanism + +**Step 1: Prove allowlist capability before proxying** + +Create a temporary hostname that returns a fixed maintenance response. From an approved operator +source expect success; from an unapproved source expect denial. Do not point it at ThothII yet. + +**Step 2: Validate and activate the test proxy** + +Configure Nginx with the same Host/HTTPS forwarding and SSE settings intended for production. Run +`nginx -t`, validate the load balancer, then reload through the established mechanism. + +**Step 3: Reconfigure local-auth public URL transactionally** + +If the exact private HTTPS origin differs from the loopback origin, use the supported authentication +configuration workflow and invalidate prior test sessions. Re-run auth and doctor checks. + +**Step 4: Prove both sides** + +Expected: authorized operator reaches the local login; unauthorized source remains denied before +ThothII. If this cannot be demonstrated, remove the test route and continue on loopback. + +### Task 11: Complete the F1-F8 acceptance session + +**Files:** +- Complete: `docs/testing/psd-server-project-a-manual.md` +- Create: protected session evidence + +**Step 1: Select the approved harmless question** + +Use a known read-only PSD question agreed by the owner. Record the wording in the protected report; +do not include patient-identifying values. + +**Step 2: Create the session as the ordinary local user** + +Use the private browser route when present; otherwise drive the same-origin frontend/API from the +server-local terminal/headless browser. Record only session ID and sanitized milestones. + +**Step 3: Review every gate** + +Complete F1-F8 without auto-confirming human decisions. Confirm persisted phase/artifact state after +each gate and resume once to prove recovery. + +**Step 4: Validate final SQL** + +Expected: finalized session, DWH validation PASS, SQL is read-only, and no clinical mutation occurs. + +**Step 5: Inspect persisted state** + +Confirm manifest, question, schema linking, Evidence, CTE plan/tests, final SQL, validation report, +and decision ledger exist in local filesystem session storage. Chat/SSE need not persist. + +### Task 12: Close Project A and preserve rollback + +**Files:** +- Complete: `docs/testing/evidence/psd-server-project-a-report-template.md` + +**Step 1: Run final diagnostics** + +Run status, doctor, auth check, workspace inspect, vector inspect, Pi test, and a bounded secret scan +of the intended report. + +**Step 2: Create a transactional new-installation backup** + +Use `tht backup --drain` with a protected explicit output. Verify its checksum. Do not include +secrets in the ordinary evidence archive. + +**Step 3: Complete human acceptance** + +Every row in `docs/testing/psd-server-project-a-manual.md` must be PASS or explicitly blocking. + +**Step 4: Record the gate** + +Record exact SHAs/images, workspace revision, preprocessing identity/counts, session ID, report +digest, rollback status, and explicit `PROJECT_A_PASS` or `PROJECT_A_FAIL`. + +**Step 5: Stop on FAIL** + +On FAIL, stop the new stack and use the surveyed old-stack recovery plan if service restoration is +desired. Do not start Project B. diff --git a/docs/plans/2026-08-20-psd-server-project-b-authentik.md b/docs/plans/2026-08-20-psd-server-project-b-authentik.md new file mode 100644 index 00000000..60beec93 --- /dev/null +++ b/docs/plans/2026-08-20-psd-server-project-b-authentik.md @@ -0,0 +1,437 @@ +# PSD Server Project B Authentik Integration Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Convert the accepted Project A installation to public OIDC mode, store owned work sessions in the existing Supabase database's `thoth_sessions` schema, and restore the established Aritmolab-sidebar user journey through the load balancer and Nginx. + +**Architecture:** Keep the same installation-descriptor path and Compose project so Project A Qdrant/Ollama volumes and bind state remain authoritative. Close ingress, snapshot Project A configuration, configure Authentik and Supabase, replace the protected installation configuration transactionally at the same paths, validate privately, then open the production route and sidebar link. + +**Tech Stack:** Authentik OAuth2/OIDC Authorization Code + PKCE, ThothII OIDC/session store, Supabase PostgreSQL schema migrations/RLS, Docker Compose, Nginx, load balancer, Aritmolab. + +--- + +## Preconditions + +- Project A automated and human reports are PASS and explicitly owner-approved. +- Application SHA, workspace SHA, images, Project A report digest, and rollback configuration match + the accepted evidence. +- The production route is closed before authentication/session-storage changes. +- All Authentik operations use the installed version's API/OpenAPI contract. Official current + references include [OAuth2/OIDC providers](https://docs.goauthentik.io/add-secure-apps/providers/oauth2/), + [provider property mappings](https://docs.goauthentik.io/add-secure-apps/providers/property-mappings/), + [application bindings](https://docs.goauthentik.io/add-secure-apps/applications/manage_apps/), and + [blueprint export](https://docs.goauthentik.io/customize/blueprints/export); installed-version + behavior wins over newer documentation. + +### Task 1: Freeze Project A and close ingress + +**Files:** +- Read: accepted Project A report +- Create: protected Project B transaction root + +**Step 1: Verify exact Project A state** + +Run status, doctor, auth check, workspace inspect, vector inspect, Pi status/test, Git SHA, and image +identity checks from Project A. Expected: all match the accepted report. + +**Step 2: Create a protected transaction root** + +Use `mktemp -d` under the survey-approved protected parent, mode `0700`. Record its path and do not +place it in Git. + +**Step 3: Close production and temporary ingress** + +Keep or restore a maintenance response at the production ThothII route. Disable the optional +Project A test route before changing authentication unless it is needed for a separately approved +private preflight. Confirm neither route reaches ThothII. + +**Step 4: Stop and back up Project A** + +```bash + --installation backup \ + --output /project-a-backup.tar --drain + --installation stop +``` + +Verify the archive using the controller's manifest/checksum contract. Preserve a copy of the exact +installation descriptor, env file, override files, auth directory, Nginx fragment, load-balancer +route, Aritmolab sidebar file/revision, and relevant Authentik export metadata. + +### Task 2: Decide exact Authentik names and roles + +**Files:** +- Create: protected `authentik-change-manifest.yaml` + +**Step 1: Select the final public origin** + +Use the live survey result, not historical `.it`/`.com` assumptions. Record exactly one HTTPS origin +and callback `/api/auth/oidc/callback`. + +**Step 2: Select exact groups** + +Default to dedicated `TOT Users` and `TOT Admin`. Reuse existing groups only if their membership +semantics match and the owner approves. Record exact case-sensitive names. + +**Step 3: Define least privilege** + +Map user group → `user`, admin group → `admin`. Define a separate service account/token with only +the installed Authentik permission needed to view exact group objects. No write, user-management, +directory-administration, or superuser permission. + +**Step 4: Obtain owner approval of the manifest** + +The manifest contains object names, slugs, intended bindings, callback, scopes, grant types, +credential destinations, and rollback action—but no secret values. Do not mutate Authentik before +approval. + +### Task 3: Export and prepare Authentik + +**Files:** +- Create: protected pre-change Authentik export +- Modify: Authentik objects named in the approved manifest + +**Step 1: Export relevant configuration** + +Use the installed version's supported blueprint/API export. A worker command such as +`ak export_blueprint` is valid only if present in that version. Protect export mode `0600`; remember +write-only provider secrets are not included, so backup their custody separately without printing. + +**Step 2: Verify API credential scope** + +Use a read-only call to list relevant groups/applications. Expected: administrative creation access +for the setup identity and a distinct path for the future group-view service account. Stop if the +credential is missing or ambiguous. + +**Step 3: Create or confirm exact groups** + +Create missing dedicated groups, or record approved existing group IDs. Do not bulk-copy LDAP or +unrelated Authentik memberships. + +**Step 4: Create the group-catalog service account** + +Grant only exact group-view permission. Create its token through the approved protected-secret +mechanism; write it directly to the ThothII secret destination without displaying it. + +**Step 5: Create the OIDC provider** + +Configure a confidential OAuth2/OIDC provider with the exact callback, issuer mode observed as +appropriate, Authorization Code, PKCE support, and Device Code only when required for +`tht auth check --interactive` and supported by the installed release. Do not enable implicit flow. + +**Step 6: Configure scopes and direct groups claim** + +Select `openid`, `profile`, and `email`. Inspect a disposable identity's decoded claim keys through +a protected verifier; retain only a redacted shape. Expected: ID token includes direct non-empty +`groups: [string, ...]`. + +If the installed default profile mapping already provides that exact claim, reuse it. Otherwise add +a provider scope/property mapping under the requested `profile` scope that returns: + +```python +return {"groups": [group.name for group in request.user.ak_groups.all()]} +``` + +Verify the installed mapping merge semantics before activation. Do not add a custom unrequested +scope because ThothII requests only `openid`, `profile`, and `email`. + +**Step 7: Create the Authentik application** + +Bind it to the provider. Configure display metadata according to local Aritmolab conventions. Do not +use an Authentik proxy provider or Nginx forward-auth for ThothII. + +**Step 8: Create and store the client secret** + +Write the client secret directly into the protected ThothII secret bundle key +`THT_OIDC_CLIENT_SECRET`. Store the service-account token as `THT_AUTHENTIK_API_TOKEN`. Never place +either value in the change manifest, shell history, Compose environment, or evidence. + +### Task 4: Prepare Supabase schema roles and backup + +**Files:** +- Read: `harness/tht/migrations/sessions/001_schema.sql` +- Read: `harness/tht/migrations/sessions/002_security.sql` +- Create: protected Supabase backup/evidence +- Create: runtime and migrator credential files + +**Step 1: Confirm the database/schema boundary** + +Expected: use the surveyed existing Supabase PostgreSQL database; clinical data remains in +`datawarehouse`; application sessions use schema `thoth_sessions`; no new database is created. + +**Step 2: Back up database metadata/data consistently** + +Use the existing Supabase/PostgreSQL backup procedure before DDL. Record backup ID, timestamp, +checksum, and restore command. Do not put a dump in the Git repository. + +**Step 3: Create or validate dedicated roles** + +Create one migrator login and one runtime login according to the migration contract. The runtime +role must not be superuser, owner, BYPASSRLS, CREATEROLE, CREATEDB, or a member of DWH write roles. +The migrator credential remains unavailable to core. + +**Step 4: Write protected credential files** + +Create separate mode-0640 runtime-password, migrator-password, and session-CA files with surveyed +ownership. Do not use command-line password arguments. + +**Step 5: Confirm PostgREST exclusion before migration** + +Record the exact exposed schema list. Expected: `thoth_sessions` absent. If the system exposes all +schemas implicitly, stop and resolve the boundary before migration. + +### Task 5: Prepare the stable Project B installation configuration + +**Files:** +- Modify at the same stable paths: operator env, installation descriptor, authentication directory +- Create: reviewed session-server override copied from `deploy/compose.session-server.yaml.example` +- Create: protected server-session workspace config copied from `deploy/workspaces/server-sessions.yaml.example` + +**Step 1: Preserve the Compose project name** + +The native controller derives the project name from the absolute installation-descriptor path. +Keep that exact path. Do not point Project B at a second descriptor path, because that would create +new Qdrant/Ollama named volumes instead of using the Project A accepted state. + +**Step 2: Stage Project B files beside the live files** + +Prepare new env/descriptor/override/auth inputs in the protected transaction root. Add the session +DB host/port/existing database name/runtime role/migrator role/TLS mode and three secret source +paths. Use `verify-full` where hostname/SAN permits; any `verify-ca` exception requires explicit +survey evidence and owner approval. + +**Step 3: Add the server-session override** + +Copy the current example to a reviewed local file and add it to the existing stable descriptor's +overrides before the Git transport override ordering required by the installation. Do not edit the +tracked example. + +**Step 4: Replace local auth state transactionally** + +With the stack stopped, move the complete Project A auth directory into the protected transaction +root, recreate an empty private directory at the same path/ownership/mode, and configure OIDC: + +```bash + --installation auth configure \ + --mode oidc --public-url \ + --issuer --client-id \ + --authentik-base-url \ + --user-group '' --admin-group '' +``` + +Expected: non-secret `auth.yaml` only; secrets resolved from the protected bundle. + +**Step 5: Atomically install staged path-only files** + +Use same-filesystem rename and preserve required ownership/mode. Keep the Project A originals in +the transaction root. Run `update --check-only`; on failure restore the originals immediately. + +### Task 6: Run and verify session migrations + +**Files:** +- Modify through one-shot migrator: existing database schema `thoth_sessions` + +**Step 1: Validate migration rendering** + +```bash + --installation update --check-only +``` + +Expected: core and `session-migrate` resolve the same core image; core lacks migrator password; +only the one-shot service sees it. + +**Step 2: Run migrations once** + +```bash + --installation sessions migrate --yes +``` + +Expected JSON: `"pending":[]` and `"drifted":[]`; `applied` may list `001` and `002` on first use. + +**Step 3: Run migration status/idempotency again** + +Run the same command. Expected: no new application and both pending/drifted remain empty. + +**Step 4: Verify database security** + +Through bounded catalog queries, prove forced RLS, policies on session tables, runtime role without +BYPASSRLS/ownership/DDL, migrator absent from core, and no runtime privileges on unrelated schemas. + +**Step 5: Recheck PostgREST exclusion** + +Expected: `thoth_sessions` still absent from exposed schemas and REST endpoints cannot address it. + +### Task 7: Validate Authentik and start privately + +**Files:** +- Record: Project B protected evidence + +**Step 1: Run static configuration validation** + +Run `update --check-only` and redacted `auth status --json`. Expected: mode OIDC, exact public origin, +issuer/client ID/group names, and no secret values. + +**Step 2: Start while public ingress remains closed** + +```bash + --installation start + --installation status + --installation auth check --json + --installation doctor --json + --installation pi test +``` + +Expected: OIDC discovery/issuer/JWKS, client-secret access, Authentik catalog token, exact mapped +groups, PostgreSQL session storage, workspace, services, workflow, and Pi pass. + +**Step 3: Run interactive device check when supported** + +```bash + --installation auth check --interactive +``` + +Expected: approved identity completes Device Authorization and direct groups claim validates. If +the installed provider does not support device flow, record PENDING rather than substituting a token. + +### Task 8: Prepare Nginx, TLS, load balancer, and sidebar + +**Files:** +- Modify only survey-approved ThothII Nginx fragment +- Modify only survey-approved load-balancer route +- Modify only exact Aritmolab sidebar source when its target must change + +**Step 1: Prepare direct-OIDC Nginx configuration** + +Follow `docs/install/reverse-proxy-nginx.md`, direct OIDC section. Required behavior: no +`auth_request`, no callback rewrite, frontend loopback upstream, Host and HTTPS forwarded headers, +HTTP/1.1, buffering/cache off, long SSE read timeout, and `X-Accel-Buffering: no`. + +**Step 2: Validate the managed certificate** + +Expected: SAN matches final hostname, validity is current, chain is trusted by approved clients, +private-key permissions match local policy, and renewal/generation ownership is recorded. Never +copy the key into ThothII. + +**Step 3: Validate Nginx without opening traffic** + +```bash +sudo nginx -t +curl --fail http://127.0.0.1:/health +``` + +Use local `--resolve`/Host tests only when they do not bypass the identity behavior being tested. + +**Step 4: Prepare the load-balancer route** + +Configure backend/health/TLS according to the surveyed owner procedure, initially disabled or +operator-only. Confirm it targets Nginx, never core/Qdrant/Ollama directly. + +**Step 5: Preserve the Aritmolab link contract** + +If the existing sidebar target already equals the final origin/path, leave source unchanged and +record proof. Otherwise make the smallest reviewed change, test it in Aritmolab's own test/build +system, and commit in that repository before deployment. + +### Task 9: Open ingress and run OIDC acceptance + +**Files:** +- Complete: `docs/testing/psd-server-project-b-manual.md` + +**Step 1: Reload Nginx through the established mechanism** + +Run `nginx -t` immediately before reload. Expected: reload succeeds and unrelated virtual hosts +remain healthy. + +**Step 2: Enable the final load-balancer route** + +Expected: HTTP redirects to HTTPS; TLS is valid; `/api/auth/oidc/login` redirects to the correct +Authentik provider; callback returns to the exact public origin. + +**Step 3: Test ordinary and admin identities** + +Start at Aritmolab, authenticate once, then use the sidebar. Expected: no second credential prompt; +ordinary user can use sessions but receives 403 for admin operations; admin has only documented +permissions. + +**Step 4: Test no-role and malformed cases** + +An identity with no mapped group authenticates but receives no application role/403. Missing, +malformed, indirect, or ambiguous group claims fail closed with generic browser errors and redacted +diagnostics. Do not retain raw claims. + +**Step 5: Test logout and restart** + +Verify ThothII logout revokes its own cookie. Document whether the Authentik SSO session remains and +therefore allows immediate re-login without credentials; do not claim global logout unless +configured and tested. Restart core and verify expected OIDC session behavior. + +### Task 10: Verify PostgreSQL ownership and complete F1-F8 + +**Files:** +- Create: protected Project B session evidence + +**Step 1: Create sessions under two identities** + +Expected: ordinary users see only their own sessions; cross-user access returns the documented +not-found boundary; admin behavior matches `session.read_all/manage_all` permissions. + +**Step 2: Verify RLS with the runtime path** + +Use application/API tests and bounded catalog evidence. Never disable RLS for diagnosis. + +**Step 3: Complete one harmless OIDC PSD session** + +Use the same approved read-only question or another owner-approved one. Complete F1-F8, validate +final SQL, resume once, and confirm session/artifacts/decisions are stored in `thoth_sessions`. + +**Step 4: Verify ephemeral boundaries** + +Expected: no chat transcript or SSE stream stored as session artifacts; no vectors in PostgreSQL; +Qdrant remains the semantic store. + +### Task 11: Test controlled failures and rollback + +**Files:** +- Record: protected rollback evidence + +**Step 1: Test a reversible provider/catalog failure** + +Use a controlled, owner-approved method such as a temporary disabled test credential or test object. +Expected: auth diagnostics and browser login fail closed, redacted, then pass after restoration. +Never break unrelated Authentik applications. + +**Step 2: Rehearse ingress-first rollback** + +Close the production route, validate Nginx restoration commands, and prove the protected Project A +configuration snapshot is complete. A full rollback need not destroy `thoth_sessions`. + +**Step 3: Verify additive database rollback boundary** + +Expected: rollback leaves schema/data intact for evidence and future recovery. No automatic DROP +SCHEMA or role deletion. + +### Task 12: Close Project B + +**Files:** +- Complete: `docs/testing/evidence/psd-server-project-b-report-template.md` + +**Step 1: Run final diagnostics** + +Run status, doctor, auth check, interactive check when supported, workspace inspect, vector inspect, +Pi test, Nginx validation, load-balancer health, Supabase migration/security checks, and sidebar test. + +**Step 2: Remove the Project A temporary endpoint** + +Remove only its load-balancer route, Nginx fragment, and managed certificate reference according to +their owners. Validate/reload and prove the hostname no longer routes. + +**Step 3: Complete the human guide and report** + +Every mandatory row must be PASS. Record exact source/image/workspace identities, Authentik object +names/IDs, Supabase database plus `thoth_sessions`, public origin, Aritmolab revision, report digest, +and `PROJECT_B_PASS` or `PROJECT_B_FAIL`. + +**Step 4: Handle FAIL safely** + +On FAIL, close ingress first. Restore Project A files at the same stable paths, move OIDC auth state +to protected evidence, restore the local-auth directory, validate, and start Project A privately. +Disable new Authentik objects; do not delete them or drop the session schema automatically. diff --git a/docs/plans/2026-08-20-psd-server-survey.md b/docs/plans/2026-08-20-psd-server-survey.md new file mode 100644 index 00000000..28668755 --- /dev/null +++ b/docs/plans/2026-08-20-psd-server-survey.md @@ -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./` +- 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 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. diff --git a/docs/testing/evidence/psd-server-project-a-report-template.md b/docs/testing/evidence/psd-server-project-a-report-template.md new file mode 100644 index 00000000..cc36259b --- /dev/null +++ b/docs/testing/evidence/psd-server-project-a-report-template.md @@ -0,0 +1,98 @@ +# PSD Server Project A — Acceptance Report + +> Template only. Store detailed/raw evidence in the protected server evidence root. This report +> must not contain passwords, tokens, cookies, keys, hashes of passwords, secret-file contents, +> raw claims, patient-identifying data, or unbounded logs. + +## Decision + +- Result: `PROJECT_A_PASS` / `PROJECT_A_FAIL` / `PROJECT_A_PENDING` +- Decision timestamp UTC: +- Owner/reviewer: +- Protected evidence path: +- Evidence manifest SHA-256: + +## Frozen identities + +- ThothII source SHA: +- Plan source SHA: +- Workspace previous SHA: +- Workspace multi-transport SHA: +- Mac REST validation result/evidence reference: +- Native `tht` version/build identity: +- Core image ID/digest: +- Frontend image ID/digest: +- Qdrant image digest: +- Ollama image digest: +- Pi version/provider/model/thinking: + +## Survey and legacy recovery + +- Survey result/digest: +- Legacy source/image identity: +- Legacy backup location/checksum reference: +- Legacy restart recipe verified: PASS/FAIL +- Legacy stack stopped without deletion: PASS/FAIL +- Production route closed: PASS/FAIL + +## New installation + +- Installation descriptor path: +- Compose project: +- Frontend loopback/private origin: +- Optional private endpoint used: yes/no +- Optional allowlist positive/negative result: +- Service health result: +- Doctor result: +- Pi result: +- Listener-boundary result: + +## Authentication + +- Mode: local +- Admin/user separation: +- Wrong-password generic failure: +- Disable/enable: +- Password/role/logout-all invalidation: +- Remembered restart: +- Logout: +- CSRF/cross-origin rejection: +- Manual guide result and reviewer: + +## Workspace and data plane + +- Workspace ID/revision: +- Server transport: postgres_direct +- Mac transport remains rest_api: PASS/FAIL +- Supabase database name: +- DWH schema: datawarehouse +- Read-only role proof reference: +- DWH connection diagnostics: +- Qdrant collection contract: +- Ollama model/dimensions: +- Preprocess first run ID/result: +- FK review digest/result: +- Schema point count: +- Evidence point/chunk count: +- Preprocess idempotency result: +- Effective configuration identity: + +## F1-F8 session + +- Approved sanitized question reference: +- Session ID: +- Owner identity type: local ordinary user +- Resume tested: +- F1-F8 result: +- Finalized: +- Final SQL read-only validation: +- Persisted artifact/decision inventory: +- No patient-identifying evidence retained: PASS/FAIL + +## Rollback and hygiene + +- New-installation backup/checksum reference: +- Legacy rollback remains available: +- Secret scan result: +- Unrelated failures or pending items: +- Reason for final decision: diff --git a/docs/testing/evidence/psd-server-project-b-report-template.md b/docs/testing/evidence/psd-server-project-b-report-template.md new file mode 100644 index 00000000..8ed22c23 --- /dev/null +++ b/docs/testing/evidence/psd-server-project-b-report-template.md @@ -0,0 +1,108 @@ +# PSD Server Project B — Acceptance Report + +> Template only. Store raw Authentik exports, database backups, browser traces, and server topology +> only in protected server storage. Never retain passwords, provider/client secrets, API tokens, +> cookies, raw claims, callback query strings, private keys, patient-identifying data, or unbounded +> logs in this report. + +## Decision + +- Result: `PROJECT_B_PASS` / `PROJECT_B_FAIL` / `PROJECT_B_PENDING` +- Decision timestamp UTC: +- Owner/reviewer: +- Protected evidence path: +- Evidence manifest SHA-256: +- Accepted Project A report digest: + +## Frozen candidate + +- ThothII source SHA: +- Workspace SHA: +- Core/frontend image identities: +- Qdrant/Ollama image identities: +- Pi provider/model: +- Public origin: +- Aritmolab source/deployment revision: + +## Authentik + +- Installed version: +- Pre-change export reference/checksum: +- Application name/ID: +- Provider name/ID: +- Issuer: +- Callback path verified: +- Grant types/scopes verified: +- Direct groups claim shape verified: +- User group name/ID: +- Admin group name/ID: +- Group-catalog service account name/ID: +- Least-privilege result: +- `auth check --json` result: +- Interactive device check: PASS/FAIL/PENDING +- No secret/raw claim in evidence: PASS/FAIL + +## Supabase session storage + +- Existing database name: +- Session schema: thoth_sessions +- Backup reference/checksum: +- Migration result (`pending=[]`, `drifted=[]`): +- Migration idempotency: +- Runtime role security/RLS result: +- Migrator absent from core: +- PostgREST exposed schemas proof: +- `thoth_sessions` not REST-exposed: PASS/FAIL +- DWH `datawarehouse` privileges unchanged: PASS/FAIL + +## Nginx, TLS, load balancer, and Aritmolab + +- Nginx configuration file/revision: +- `nginx -t` result: +- Certificate subject/SAN/expiry metadata: +- Certificate trust result: +- Load-balancer route/health result: +- Same-origin API/callback result: +- SSE unbuffered result: +- No double `auth_request`: PASS/FAIL +- Sidebar source/link result: +- Other virtual hosts unchanged: PASS/FAIL + +## Human SSO and authorization + +- Aritmolab login → sidebar → ThothII without second credential prompt: +- Ordinary user permissions: +- Administrator permissions: +- No-role user result: +- Extra unrelated group result: +- Missing/malformed group negative result: +- Forged-header result: +- ThothII logout result: +- Authentik SSO session behavior documented: +- Provider/catalog controlled failure and recovery: +- Manual guide result and reviewer: + +## OIDC F1-F8 session and ownership + +- Approved sanitized question reference: +- Session ID: +- OIDC principal reference (non-identifying): +- F1-F8/final SQL result: +- PostgreSQL manifest/artifact/decision persistence: +- Resume/restart result: +- Cross-user isolation result: +- Admin cross-user result: +- Chat/SSE ephemeral boundary: + +## Rollback, cleanup, and hygiene + +- Ingress-first rollback rehearsal: +- Project A protected configuration available: +- Authentik disable plan verified: +- Additive schema rollback boundary verified: +- Project A temporary endpoint removed: +- Legacy stack stopped/unexposed: +- Core/Qdrant/Ollama private: +- Secret scan result: +- Unrelated failures or pending items: +- Reason for final decision: diff --git a/docs/testing/evidence/psd-server-survey-report-template.md b/docs/testing/evidence/psd-server-survey-report-template.md new file mode 100644 index 00000000..8213b0b6 --- /dev/null +++ b/docs/testing/evidence/psd-server-survey-report-template.md @@ -0,0 +1,151 @@ +# PSD Server — Survey Report + +> Template only. The completed report and raw inventory remain in protected server storage. Do not +> include passwords, tokens, cookies, private keys, password hashes, raw claims, full container +> environments, patient-identifying data, or unbounded logs. + +## Decision + +- Result: `SURVEY_GO` / `SURVEY_NO_GO` +- Timestamp UTC: +- Operator: +- Protected evidence path: +- Report SHA-256: +- Blocking unknowns: + +## Host + +- OS/version/kernel: +- Architecture: +- Docker/Compose versions: +- CPU/RAM/free disk: +- Approved service UID/GID: +- Local terminal/CyberArk constraints: + +## Legacy ThothII + +- Source path/SHA/dirty state: +- Compose/controller path and project: +- Services/images: +- Published ports: +- Networks: +- Volumes/binds: +- Data/config/secret reference paths: +- Current health: +- Active sessions/users: +- Recovery/maintenance state: +- Backup procedure and owner: +- Exact stop/start commands: + +## New installation roots + +- Adjacent source root: +- Operator root: +- Secret root: +- Data root: +- Pi-state root: +- Workspace-registry root: +- Backup root: +- Protected evidence root: +- Port reserved for Project A: + +## Nginx, TLS, and load balancer + +- Nginx version/config owner: +- Relevant virtual-host/include files: +- Current ThothII upstream: +- Forwarded headers/SSE behavior: +- Certificate subject/SAN/issuer/expiry: +- Certificate generation/renewal owner: +- Load-balancer owner/config surface: +- Health check/TLS boundary/source addresses: +- Temporary hostname allowlist possible: yes/no +- Exact reload/rollback procedure: + +## Aritmolab + +- Public origin observed: +- Source/deployment path and SHA: +- Compose/network identity: +- Sidebar file/line/link target: +- Historical `.it`/`.com` discrepancy resolved as: +- Build/test/deploy procedure: +- Configuration owner: + +## Authentik + +- Installed version/image: +- Deployment path/services: +- Base URL/issuer conventions: +- Existing Aritmolab application/provider pattern: +- Groups relevant to ThothII: +- Credential reference paths and usability: +- Export/backup procedure: +- API/OpenAPI version: +- Required human help: + +## Supabase/PostgreSQL + +- Existing database name: +- PostgreSQL/pooler/PostgREST components: +- Direct container-to-database route: +- TLS mode/CA reference: +- Existing schemas: +- Existing `thoth_sessions` state: +- PostgREST exposed schemas: +- Backup/restore mechanism: +- Proposed runtime/migrator role names: +- Role-creation owner: + +## PSD DWH + +- Database/schema: +- Direct host/port from core: +- Runtime role reference: +- Read-only grant proof result: +- TLS requirements: +- REST binding retained for Mac: + +## Workspace Git + +- Remote/branch/access: +- Current main SHA: +- Server deploy-key scope: +- Descriptor schema/transports: +- Evidence/annotations state: +- Curator with push authority: + +## Pi, LLM, Qdrant, and Ollama + +- Pi version/provider/model/thinking: +- Credential reference: +- LLM endpoint reachability: +- Qdrant/Ollama image architecture support: +- Capacity assessment: + +## Topology + +Describe the observed final flow and every trust boundary. Reference a protected diagram if the +topology itself is considered sensitive. + +## Intended changes by owner + +| Owner/component | Exact files/objects | Project | Rollback | +|---|---|---|---| +| New ThothII | | A/B | | +| Workspace curator | | A | | +| Nginx | | A optional/B | | +| Load balancer | | A optional/B | | +| Aritmolab | | B | | +| Authentik | | B | | +| Supabase | | B | | + +## GO/NO-GO rationale + +- Verified old-stack rollback: +- Verified secret custody: +- Verified read-only DWH: +- Verified configuration owners: +- Verified resources: +- Unresolved risks: +- Final rationale: diff --git a/docs/testing/psd-server-project-a-manual.md b/docs/testing/psd-server-project-a-manual.md new file mode 100644 index 00000000..0966c405 --- /dev/null +++ b/docs/testing/psd-server-project-a-manual.md @@ -0,0 +1,166 @@ +# Progetto A PSD — collaudo manuale + +Questo documento guida il collaudo umano del nuovo ThothII sul server con autenticazione locale. +Non sostituisce i controlli automatici del piano. Compilarlo soltanto dopo che Sol ha dichiarato +verdi installazione, workspace, DWH, Qdrant, Ollama e preprocessing. + +## Regole + +- Eseguire i comandi dal terminale locale del server; non usare tunnel SSH. +- Non copiare nel rapporto password, cookie, token, chiavi, hash, stringhe di connessione o righe di + log che li contengano. +- Usare un amministratore locale e un utente ordinario creati appositamente. +- Non effettuare più tentativi di password errata del necessario: il login applica rate limiting. +- Per ogni prova segnare `PASS`, `FAIL` o `PENDING`, con una nota breve e non sensibile. +- Un solo `FAIL` obbligatorio impedisce di avviare il Progetto B. + +## Dati iniziali + +| Campo | Valore redatto | +|---|---| +| Data/ora UTC | | +| SHA ThothII | | +| SHA workspace | | +| Installation descriptor | percorso protetto, senza contenuto | +| Origine di test | loopback oppure hostname privato | +| Endpoint temporaneo usato | sì/no | +| ID domanda di prova approvata | | +| Operatore | | + +## 1. Stato generale + +Eseguire: + +```bash +THT_BIN= +INSTALLATION= +"$THT_BIN" --installation "$INSTALLATION" status +"$THT_BIN" --installation "$INSTALLATION" doctor --json +"$THT_BIN" --installation "$INSTALLATION" auth check --json +"$THT_BIN" --installation "$INSTALLATION" pi test +``` + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Stato servizi | frontend, core, qdrant ed embedding sani; initializer completato | | | +| Doctor | tutti i controlli obbligatori passano | | | +| Autenticazione | modalità `local`, configurazione pronta | | | +| Pi | provider e modello rispondono | | | +| Secret hygiene | nessun secret nell’output | | | + +## 2. Confine di rete + +Dal terminale controllare i listener e la configurazione renderizzata secondo il piano. + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Frontend | pubblicato solo su loopback o tramite endpoint privato approvato | | | +| Core | nessuna porta host pubblica | | | +| Qdrant | nessuna porta host pubblica nel profilo server | | | +| Ollama | nessuna porta host pubblica | | | +| URL produzione | non raggiunge il nuovo stack | | | +| Endpoint privato, se usato | sorgente autorizzata ammessa | | | +| Endpoint privato, se usato | sorgente non autorizzata respinta prima di ThothII | | | + +Se non esiste un endpoint privato, usare il browser headless/API sul server. Non segnare come +eseguite prove browser che non sono state realmente svolte. + +## 3. Autenticazione locale + +Eseguire tramite frontend/browser quando disponibile; altrimenti usare richieste same-origin dal +terminale, conservando cookie e password soltanto in file temporanei mode `0600`, poi eliminandoli. + +| Prova | Azione | Risultato atteso | Esito | Note | +|---|---|---|---|---| +| Accesso anonimo | aprire pagina/API protetta | appare login oppure HTTP 401 | | | +| Password errata | un tentativo con utente valido | errore generico; nessun dettaglio account | | | +| Utente ordinario | login corretto | accesso alle sessioni | | | +| Confine ruoli | aprire Pi Management/amministrazione | negato o non visibile | | | +| Logout | uscire e ricaricare | sessione rifiutata, nuovo login richiesto | | | +| Amministratore | login corretto | funzioni amministrative previste disponibili | | | +| Disabilitazione | Sol disabilita l’utente di prova | login rifiutato genericamente | | | +| Riabilitazione | Sol riabilita l’utente | login nuovamente possibile | | | +| Invalidazione | cambio password/ruolo o `logout-all` | vecchia sessione non più valida | | | +| Remember me | login persistente, riavvio core | sessione ancora valida entro TTL | | | +| CSRF | mutazione senza token corretto | richiesta respinta | | | + +Non disabilitare o demansionare l’ultimo amministratore abilitato. + +## 4. Workspace e DWH + +Eseguire: + +```bash +"$THT_BIN" --installation "$INSTALLATION" \ + workspace inspect --workspace psd-clinical --json +"$THT_BIN" --installation "$INSTALLATION" \ + workspace vector inspect --workspace psd-clinical --json +``` + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Revisione Git | coincide con lo SHA approvato | | | +| Trasporto server | `postgres_direct` | | | +| Database/schema | database Supabase rilevato, schema `datawarehouse` | | | +| Utente DWH | read-only dimostrato dai grant | | | +| Workspace Mac | prova separata conferma ancora `rest_api` | | | +| Qdrant | 1024 dimensioni, cosine, indici payload richiesti | | | +| Ollama | `qwen3-embedding:0.6b` | | | +| Evidence | corpus Git attivo alla stessa revisione | | | + +## 5. Preprocessing e idempotenza + +Esaminare i due risultati consecutivi del preprocessing prodotti da Sol. + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Introspezione DWH | completata senza scritture cliniche | | | +| Annotazioni FK | revisione umana registrata e legata al digest corretto | | | +| Schema index | record presenti con workspace revision | | | +| Evidence index | documenti/chunk presenti con workspace revision | | | +| Seconda esecuzione | nessun duplicato; contenuti invariati riconosciuti | | | +| Identità effettiva | invariata tra i due run | | | + +## 6. Sessione completa F1–F8 + +Usare una domanda innocua approvata, senza identificativi reali di pazienti. + +| Fase | Controllo manuale | Esito | Note | +|---|---|---|---| +| F1 | domanda compresa/disambiguata correttamente | | | +| F2 | concetti e contesto coerenti | | | +| F3 | tabelle candidate ragionevoli | | | +| F4 | colonne/join curati e confermati | | | +| F5 | piano CTE comprensibile | | | +| F6 | ogni CTE testata e approvata | | | +| F7 | SQL finale read-only e validato | | | +| F8 | conclusione, memoria e riepilogo coerenti | | | + +Durante una fase intermedia chiudere/riprendere la sessione una volta. Il resume deve tornare +all’ultima fase incompleta senza creare una nuova domanda. + +Verificare infine: + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Stato | sessione `finalized` | | | +| SQL | solo lettura; validazione DWH verde | | | +| Artefatti | manifest, question, schema linking, Evidence, CTE, SQL, validation presenti | | | +| Decisioni | gate registrati nel ledger | | | +| Persistenza | artefatti leggibili dopo riavvio | | | +| Chat/SSE | non richiesti come persistenza | | | + +## 7. Decisione + +| Gate | Esito | +|---|---| +| Tutti i controlli obbligatori PASS | | +| Nessun secret raccolto | | +| Rollback vecchio stack ancora disponibile | | +| Progetto B autorizzabile | | + +Decisione finale: `PROJECT_A_PASS` / `PROJECT_A_FAIL` / `PROJECT_A_PENDING` + +Revisore e data: ______________________________________ + +Motivazione sintetica: ______________________________________ diff --git a/docs/testing/psd-server-project-b-manual.md b/docs/testing/psd-server-project-b-manual.md new file mode 100644 index 00000000..baef77ee --- /dev/null +++ b/docs/testing/psd-server-project-b-manual.md @@ -0,0 +1,131 @@ +# Progetto B PSD — collaudo manuale Authentik e Aritmolab + +Questo documento verifica il percorso finale di produzione. Si esegue soltanto dopo il PASS del +Progetto A e dopo che Sol ha completato i preflight Authentik, Supabase, Nginx e bilanciatore. + +## Regole + +- Usare identità di prova approvate: una ordinaria, una amministrativa e, se disponibile, una senza + gruppi ThothII. +- Non acquisire token, cookie, password, chiavi private, claim completi o trace browser contenenti + URL di callback con parametri. +- Partire dalla home reale di Aritmolab, non da un URL interno di ThothII. +- Segnare `PASS`, `FAIL` o `PENDING`; non dedurre il PASS da test automatici. + +## Dati iniziali + +| Campo | Valore redatto | +|---|---| +| Data/ora UTC | | +| SHA ThothII/workspace | | +| Origine pubblica | | +| SHA/revisione Aritmolab | | +| Nome/ID applicazione Authentik | non inserire secret | +| Database Supabase | | +| Schema sessioni | `thoth_sessions` | +| Operatore/revisore | | + +## 1. TLS, routing e pagina iniziale + +| Prova | Azione | Risultato atteso | Esito | Note | +|---|---|---|---|---| +| HTTP | aprire origine in HTTP | redirect a HTTPS | | | +| Certificato | ispezionare il lucchetto/catena | hostname corretto, nessun warning | | | +| Home Aritmolab | aprire URL ufficiale | pagina disponibile | | | +| Sidebar | individuare ThothII | link presente come prima | | | +| Destinazione | aprire il link | nuovo frontend ThothII | | | +| API | caricare l’app | nessun 502/404 o mixed content | | | +| SSE | avviare attività modello | aggiornamenti continui, niente buffering evidente | | | + +## 2. Single sign-on + +Chiudere ogni precedente sessione di test secondo la procedura concordata. Accedere ad Aritmolab +con l’identità ordinaria, quindi aprire ThothII dalla sidebar. + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Primo login | Authentik autentica l’utente | | | +| Passaggio sidebar | nessuna seconda richiesta di credenziali | | | +| Callback | ritorno all’origine pubblica ThothII | | | +| Identità | nome visualizzato coerente, senza dati grezzi del token | | | +| Browser storage | nessun access/id token in Local/Session Storage | | | +| Cookie | cookie ThothII HttpOnly/Secure/SameSite secondo configurazione | | | + +Non copiare il valore del cookie nel rapporto. + +## 3. Ruoli e autorizzazione + +| Identità/caso | Risultato atteso | Esito | Note | +|---|---|---|---| +| Gruppo utente | può creare, leggere e gestire le proprie sessioni | | | +| Gruppo utente | Pi Management e funzioni admin negate con 403/non visibili | | | +| Gruppo admin | funzioni amministrative documentate disponibili | | | +| Nessun gruppo mappato | autenticato ma operazioni protette negate | | | +| Gruppo estraneo aggiuntivo | nessun cambiamento e nessun warning | | | +| Header identità forgiato | nessun privilegio aggiuntivo | | | + +Le prove su claim mancante/malformato possono essere eseguite da Sol con un’identità/provider di +test controllato. Il revisore verifica soltanto esito HTTP generico e report redatto, mai il token. + +## 4. Logout e riavvio + +| Prova | Azione | Risultato atteso | Esito | Note | +|---|---|---|---|---| +| Logout ThothII | usare il comando dell’app | cookie ThothII revocato | | | +| SSO ancora attivo | riaprire ThothII | possibile nuovo accesso senza password; documentare | | | +| Logout Authentik globale | se configurato e in scope | comportamento conforme alla policy locale | | | +| Riavvio core | Sol riavvia in finestra controllata | sessione browser valida secondo TTL/policy | | | +| Provider indisponibile | prova controllata | nuovo login fallisce chiuso e redatto | | | +| Ripristino provider | ripetere diagnosi/login | servizio torna operativo | | | + +Non dichiarare “logout globale” se è stato testato soltanto il logout locale di ThothII. + +## 5. Sessioni PostgreSQL e isolamento + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Migrazioni | `pending=[]`, `drifted=[]` | | | +| Schema | `thoth_sessions` nel database Supabase esistente | | | +| PostgREST | schema non esposto | | | +| RLS | forzata sulle tabelle previste | | | +| Utente A/B | ciascuno vede soltanto le proprie sessioni | | | +| Accesso incrociato | risposta not-found/negata come da contratto | | | +| Admin | accesso trasversale solo secondo permessi documentati | | | +| Credenziale migratore | non montata nel core | | | +| Schema clinico | nessun nuovo privilegio runtime | | | + +## 6. Sessione completa sotto OIDC + +Come utente ordinario, eseguire una domanda innocua approvata e completare F1–F8. + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Creazione | sessione associata all’identità OIDC | | | +| Gate F1–F8 | tutti presentati e registrati correttamente | | | +| Resume | ritorna alla sessione corretta | | | +| SQL finale | sola lettura e validato | | | +| Persistenza | manifest, artefatti e decisioni in PostgreSQL | | | +| SSE/chat | funzionano live; non richiesti come artefatti persistiti | | | +| Riavvio | sessione di lavoro ancora disponibile | | | + +## 7. Integrazione e pulizia finale + +| Prova | Risultato atteso | Esito | Note | +|---|---|---|---| +| Endpoint temporaneo A | rimosso/non instradato | | | +| Vecchio stack | fermo, non esposto | | | +| Link sidebar | punta solo alla nuova release | | | +| Servizi privati | core/Qdrant/Ollama non pubblicati | | | +| Altri servizi Nginx | invariati e sani | | | +| Rollback | procedura verificata e disponibile | | | +| Evidenze | nessun secret o dato clinico identificabile | | | + +## 8. Decisione + +Decisione finale: `PROJECT_B_PASS` / `PROJECT_B_FAIL` / `PROJECT_B_PENDING` + +Revisore e data: ______________________________________ + +Motivazione sintetica: ______________________________________ + +Conferma percorso finale “Aritmolab → sidebar → ThothII → SSO”: ______________________________ diff --git a/mkdocs.yml b/mkdocs.yml index df7957de..8b37acb4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -50,6 +50,9 @@ nav: - Guida utente: guida-utente.md - Accettazione autenticazione: testing/authentication-manual-acceptance.md - Setup Policlinico San Donato: install/psd-workspace-setup.md +- Programma deploy server PSD: plans/2026-08-20-psd-server-deployment-program.md +- Collaudo PSD Progetto A: testing/psd-server-project-a-manual.md +- Collaudo PSD Progetto B: testing/psd-server-project-b-manual.md - ThothII (Documentazione Tecnica): - Panoramica Architettura: architecture/overview.md - Autenticazione: architecture/authentication.md