docs: focus public documentation on product usage

This commit is contained in:
2026-08-26 10:15:07 +02:00
parent 23bc2f6555
commit a54d4769dd
67 changed files with 290 additions and 9963 deletions
@@ -1,77 +0,0 @@
# Authentication manual acceptance
This is a release-gate checklist, not evidence. Use one ordinary PSD test identity and one admin
PSD test identity supplied through the approved test-identity process. Record only sanitized
pass/fail results, timestamps, build identity, and diagnostic codes. Do not record names, internal
URLs, directory/LDAP details, tokens, passwords, hashes, cookies, or realistic secret examples.
Keep the retained result under `.artifacts/manual-acceptance/authentication/<run-id>/` with a
sanitized digest. Do not retain raw browser traces, Compose environments, provider exports, or
unbounded logs. If the approved identities or access are unavailable, record **PENDING** rather
than inferring a PASS.
## Preconditions and ordering
1. Confirm retained Task 13 evidence for the restore prerequisites before certification: the
lifecycle lock is acquired before target-dependent preflight, archive bytes and hashes are
staged/revalidated inside that lock immediately before extraction, and checkpointing requires
an opaque installation-bound transaction capability. Manual acceptance never substitutes for
those automated concurrency and mutation tests.
2. Set the installation and workspace identifiers, then inspect the active workspace with the
native host CLI. This replaces the former Workspace Validate/Test wording:
```bash
export THT_BIN=tht
export INSTALLATION=/absolute/path/to/thothii-installation.yaml
export WORKSPACE_ID=psd-clinical
"$THT_BIN" --installation "$INSTALLATION" \
workspace inspect --workspace "$WORKSPACE_ID" --json
```
3. Run `"$THT_BIN" --installation "$INSTALLATION" auth check --json` for live non-interactive
diagnosis, then `auth check --interactive` where Device Authorization is available.
4. Run `"$THT_BIN" --installation "$INSTALLATION" doctor --json` and confirm this exact report order: `descriptor`, `files`, `docker`,
`compose`, `configuration`, `authentication`, `services`, `core-http`, `frontend-http`,
`workspace-registry`, `workflow`, `pi`.
4. Confirm the exact direct `groups` claim for both identities and the mappings `TOT Users → user`
and `TOT Admin → admin`. Confirm extra upstream groups are ignored without warning.
5. For a projected Linux server, before any start gate, collect only the redacted result of
`sudo tht --installation "$INSTALLATION" auth status --json`. Record `state`, generation,
canonical revision, and `equal`; do not retain authentication YAML, user records, hashes, or
environment output. `ready` plus `equal: true` is required. A blocked or unequal result is a
fail-closed condition: do not start, and use `sudo tht --installation "$INSTALLATION" auth
publish` followed by the same status command only after the canonical root is available.
## Matrix
| Scenario | Expected result |
|---|---|
| Ordinary identity opens its own application/session routes | Allowed; admin-only routes return `403`. |
| Admin identity opens admin routes | Allowed according to the `admin` permission set. |
| Browser callback token omits `groups` | Callback returns HTTP 401 `oidc_callback_failed`; the internal reason is not exposed. |
| Browser callback token has malformed, indirect, or overage groups | Callback returns HTTP 401 `oidc_callback_failed`; the internal reason is not exposed. |
| Interactive diagnostic receives missing or invalid groups | Diagnostic fails with `oidc_groups_claim_invalid`. |
| Token has no mapped group | Principal has no role; protected routes return `403`; no warning is emitted. |
| A configured group is absent from Authentik | Check fails with `oidc_mapped_group_missing`. |
| Catalog token is wrong or lacks group-view-only access | Live check fails redacted with `oidc_group_catalog_unauthorized`. |
| Mapped group is renamed | The next check fails closed until configuration and provider agree. |
| Token adds an unrelated group | Login and authorization are unchanged; no warning is emitted. |
| Authenticated PSD identity creates a known-good session | SSE connects, the session is created, and the first reviewer gate appears without unexpected `401`/`403` responses. |
| Backend restarts with Remember me | Remembered local session survives within its TTL. |
| Password/role/enable revision changes | Affected local sessions are rejected and reauthentication is required. |
| CSRF or cross-origin mutation is attempted | Request is rejected. |
| Logout | Cookie expires and the server session is deleted. |
| Provider outage | Live check reports `oidc_discovery_unreachable`; browser login fails closed without exposing credentials. |
| Restore is completed | Sessions and OIDC state are absent; all users must reauthenticate. |
| Projected authentication restore | Candidate generation and any recovery generation are published from the canonical root; a failed verification remains blocked and start is refused. |
## Status at Task 15
The hermetic browser suite now covers the loopback provider discovery/JWKS/device/group-list
surface and the complete OIDC Authorization Code + PKCE callback, including direct `groups`
fail-closed cases. It also covers local ordinary, remembered/restart, logout, and administrator
flows. This deterministic evidence does not replace the manual PSD/AuthentiK acceptance.
Native Windows behavioral execution, approved PSD/AuthentiK identities and access, interactive
device acceptance, and external L2 remain **PENDING** until actual retained evidence exists. Do
not mark the feature or this matrix release-complete while any required gate remains pending.
@@ -1,39 +0,0 @@
# Collaudo manuale `dwh-auth`
Prima del rollout, i test sono sintetici e non usano dati clinici. Nel rollout reale si usano credenziali reali esclusivamente su `/rpc/ping`, senza acquisire risultati clinici. Non eseguire ora
mutazioni server e non registrare chiavi, digest, certificate body, output Nginx grezzo o risultati
clinici.
## Precondizioni
- SHA sorgente e checksum binario approvati; registry, lock e record hanno owner/mode attesi.
- `dwh-auth check`, unit `systemd` e socket Unix sono sani; Nginx viene toccato solo al Gate B.
- CA `.it` e fingerprint sono confermati fuori banda; nessun `.com` è usato senza SAN valido.
- Il server ThothII PSD è `postgres_direct`; il Mac/remoti sono `rest_api`.
## Matrice di accettazione
| Caso | Azione autorizzata | Atteso | Evidenza ammessa |
| --- | --- | --- | --- |
| Registro | `check`, `key list`, `key status` | Stato e soli ID pubblici | ID, status, owner/mode, timestamp |
| Socket locale | File header protetti, v1/legacy | `204` v1 e legacy durante dual-key | codice, unit/socket status |
| Negativo locale | File header casuale e richiesta senza header | `401` | codice, nessun valore header |
| Guasto controllato | Autenticatore/registro non disponibili nel test approvato | `503`, mai accesso | codice e rollback |
| HTTPS dual-key | `/dwh/rpc/ping` con CA approvata, file header v1/legacy | v1 e legacy qualsiasi `2xx`, TLS valido | ID, esito e approvazione fingerprint |
| Mac | **Validate workspace source**, **Test workspace connections** | Ping positivo | timestamp e stato GUI |
| Revoca | Chiave legacy dopo osservazione | v1 qualsiasi `2xx`; legacy `401` post-revoca | ID pubblico e codici |
| Trasporti | Server PSD diretto e SSH diagnostico | nessuna chiave `dwh-auth` | trasporto selezionato |
## Sequenza
1. Fare il Gate A: verificare localmente 204/401 e che il servizio resti indipendente dal vecchio
stack. Nessun reload Nginx.
2. Al Gate B, fare backup protetti, `nginx -t`, reload autorizzato e ping `.it` con CA verificata.
3. Configurare il Mac nel vault GUI o con `API_KEY_FILE`; verificare ping e ID pubblico.
4. Dopo la finestra approvata, revocare legacy, ripetere v1 2xx/legacy 401 post-revoca e controllare
solo un journal bounded sanitizzato.
5. Verificare rollback: backup leggibili, scope limitato a route/unit; nessuna migrazione di
sessioni legacy, indici Qdrant o cache Ollama.
Il collaudo passa solo con tutti i casi attesi, owner acceptance e template evidenza completato. `ssh_tunnel` non usa chiavi `dwh-auth` e resta fuori dal runtime sessione.
Per la diagnostica seguire [guida server](../install/dwh-auth-server.md) e [TLS](../install/dwh-auth-tls.md).
@@ -1,131 +0,0 @@
# PSD Evidence restructuring — real acceptance
Date and completion time: `2026-08-25T21:44:26Z` (UTC)
Reviewer: Marco Pancotti
Human Git review: **PASS**
Scope: issues `#47` and parent `#35`
The reviewer approved all 35 proposed Evidence and authorized resolution of all 60 review
items. The accepted rules were: retain `domain` when fully qualified identifiers are absent;
invent no schema, table, column, or value; mark incomplete lists as non-exhaustive; preserve
caveats and ambiguities; consolidate examples into one unit per source; treat N=5 as a
recommendation rather than a mandatory limit; and interpret "SEF seguito da ablazione" as a
later event in time.
## Source and recovery record
- ThothII implementation candidate `66f9fa2821decf30bec4468a33a499d8ea459510` and Linux
deployment repairs `d49c644b611a7cc50f19fd40f30464ec0a12d2db` and
`e51a6a22535de934c9245068994a3eaf3e855f96` and
`12d257056fe8293d1f0e4e3e613feba41c5f76a7` and
`287ce91e67ce736804656819401f9ba474406e63` and
`73efeb7f3d3f3de487f2686a2074c0953c9d51e4` and
`2b6bb058d8151a76919bf1bde94d304af646f8b4` and
`a3259ced99f981b4a18924b1149d27471f1a5e45` and
`0df95e337ec4a492891ae3f523c3a28aa88e67cb` and
`8b524b4314856b8b4eaa8629c3466fd382ea3357` and
`663c60dc3e5d456b65c4b195e2951b271438c147` and
`9a62fce1add42339d79c6a0f919fb7ab6f5fabea` and
`a0620ffffa87f38ba663cd4a20fbf8d516a166f5` and
`71a42fbe80c8d9d3a56a64d353ceeaa59295452b` (PR `#48`).
- PSD authoring review: PR `#2`, head `c93174841da253512ab81b32cf8c68304bc02e31`,
merged as `07ae6930a21299082685d2b3668912ac2d188079`.
- Canonical-root correction: PR `#3`, head `93c4b9a3189eb3113bb5d2d0b313332c064e1a1b`,
merged as `a4b27c6fe1cf41aac8102933a4100da8fee345e6`.
- Atomic-unit retention: PR `#4`, head `384f76a11d1e705b41d9df785337f81bc7515e2d`,
merged as the published PSD revision
`1c304efa02547a4c10826f557376a38e959b8bbf`.
- Pre-migration Qdrant snapshot:
`psd-clinical-6759909623621226-2026-08-25-18-43-21.snapshot`, 28,121,600 bytes,
SHA-256 `da7fdf114fdd1a638eb6f828ac127126258451dc617e8d409b5895bfd15397a6`.
It is retained for collection-level rollback; no collection was deleted or renamed.
Command output and durable runtime records are in:
- this report;
- `/data/sessions/psd-clinical/preprocessing/jobs/44bedc056f256d983ce88b9a565d9fd6.json`
(dry run) and
`/data/sessions/psd-clinical/preprocessing/jobs/c564d7fdb36436b3ae76dc0c2ce1e20d.json`
(publication);
- `/data/sessions/psd-clinical/corpus/ACTIVE` and
`/data/sessions/psd-clinical/corpus/gen-f968808223bf462fa406c9a6df8f6a55/manifest.json`;
- `/data/sessions/psd-clinical/sessions/20301df7-cb3c-421a-b14f-dec8cf8d9620/`
for the real walkthrough artifacts.
No secret, patient identifier, payload, or vector is copied into this report.
## Manual acceptance results
1. **Authoring and Git review — PASS.** Exactly 35 source documents were migrated and
validated into 35 curated units (34 `domain`, 1 `glossary`), with one unit per source,
zero remaining review items, zero validation findings, stable `evidence:<slug>` IDs, and
no automatic orphan deletion. `psd-clinical/evidence/README.md` remains present. PR `#2`
records the human-reviewed content; PRs `#3` and `#4` are path/policy corrections without
semantic invention.
2. **Additive BM25 upgrade — PASS.** The existing `psd-clinical` collection and unnamed
1,024-dimensional cosine dense vector were preserved. The only vector-schema addition is
sparse vector `bm25` with modifier `idf`. There was no rebuild, dense-vector rename,
fallback engine, or collection replacement.
3. **Schema and Memory non-regression — PASS.** Immediately before and after Evidence
publication the protected counts remained 163 `schema_table`, 2,275 `schema_column`,
2 `memory`, and 1 `solved_question`; the saved representative IDs and repeated dense
Schema/Memory neighbors were unchanged. The later real walkthrough intentionally promoted
two approved memories and one solved question, so the final live counts are 4 and 2 while
all baseline IDs remain present. The 35-unit migration itself did not modify those families.
4. **Inactive candidate, evaluation, activation — PASS.** Dry run
`44bedc056f256d983ce88b9a565d9fd6` completed without activation. Publication run
`c564d7fdb36436b3ae76dc0c2ce1e20d` built child
`f968808223bf462fa406c9a6df8f6a55` as an inactive candidate, evaluated that exact
generation, then activated `gen:f968808223bf462fa406c9a6df8f6a55`. It contains 35
documents and 35 chunks; the run reported 35 changed and 36 legacy removals from the active
set. All 20 evaluation queries passed Hit@10. Representative diagnostic ranks were:
| Profile | Query | Dense | BM25 | Fused |
| --- | --- | ---: | ---: | ---: |
| lexical | `lexical-chirone-meta` | 1 | 1 | 1 |
| semantic | `semantic-controllo-device` | 1 | 1 | 1 |
| mixed | `mixed-deduplica-codici` | 7 | 5 | 2 |
The previous generation `gen:f91ccc1ae1dc4ccab05e7d70a7675a97` is retained. The live
collection has 78 Evidence points (43 retained older points plus the 35 active-generation
points); generation filtering, rather than destructive deletion, determines publication.
5. **Hybrid and Formula retrieval — PASS.** The contract suite proves dense and BM25 receive
the identical NFC-normalized, newline-preserving, outer-trim-only query. The isolated
acceptance fixture accepts a PostgreSQL expression, rejects a full query, and retrieves an
approved formula through its typed Evidence path. No PSD formula was invented for this
migration. The real session persisted `concept_formulas: []` and `evidence.json: []`, so its
proposals remain unpublished.
6. **Empty versus unavailable — PASS.** The acceptance probe recorded an available empty
retrieval that may continue and a controlled unavailable-Qdrant retrieval that blocks the
stage. The unavailable path used neither stale generation nor purpose fallback.
7. **Complete real session — PASS.** Session
`20301df7-cb3c-421a-b14f-dec8cf8d9620`, named
`Accettazione Evidence #47 — SEF seguito da ablazione`, ran with `zai/glm-5.3` through
clarification, rewriting, schema linking, three executed CTEs, final SQL, and finalization.
It used the approved interpretation of two distinct events in 2024 and the temporal predicate
`ablazione > SEF`; all three CTE executions returned `ok`. The approved read-only SQL has
SHA-256 `b26d26c9c1e8579d7e3d5ccabe874e02b570bc15cfbe1b2ce822c28ae8b0e2ac`,
parsed without warnings, and returned **78 patients**. Five independently persisted Evidence
receipts cover clarification/disambiguation, rewriting, schema linking, CTE/SQL generation,
and final SQL, all bound to `gen:f968808223bf462fa406c9a6df8f6a55`. Memory and synthesis
did not invoke Evidence search. The authenticated UI showed the finalized session to Local
Admin. The abandoned provider preflight session was archived without deletion.
## Automated verification
- `bash scripts/evidence-restructuring-acceptance.sh`: Evidence acceptance contracts PASS.
- Backend Vitest: 78 files passed, 1 skipped; 1,119 tests passed, 40 skipped; TypeScript PASS.
- Frontend Vitest and TypeScript PASS.
- Harness: 1,103 tests passed, 4 deselected; Ruff PASS.
- Go: 19 packages, zero failures.
- Task 13 runtime fixtures: local PASS; server PASS; shell syntax PASS. The server regression
proves both the root-owned canonical store and the UID/GID `10001:10001` runtime projection
are created with mode `0700` before OIDC configuration.
manual acceptance: PASS
@@ -1,40 +0,0 @@
# Template evidenza — rollout PSD `dwh-auth`
Compilare dopo i gate autorizzati. Questa evidenza contiene solo metadati pubblici e sanitizzati.
Non inserire chiavi, digest di credenziali, corpo/fingerprint completo del certificato, output Nginx
grezzo, config curl, stringhe di connessione o risultati clinici.
## Identità e approvazioni
| Campo | Valore sanitizzato |
| --- | --- |
| SHA sorgente / checksum binario | `<sha-e-checksum>` |
| Proprietario e approvazione Gate A | `<owner-e-timestamp>` |
| Proprietario e approvazione Gate B | `<owner-e-timestamp>` |
| ID pubblici interessati | `<public-key-ids>` |
| Conferma fingerprint fuori banda | `<approvatore-e-timestamp>` |
## Stato e permessi
| Oggetto | Percorso | Owner/mode | Stato |
| --- | --- | --- | --- |
| Registro | `/var/lib/dwh-auth/` | `root:dwh-auth` `2750` | `<pass-fail>` |
| Lock e record | `active` / `revoked` | `root:dwh-auth` `0640` | `<pass-fail>` |
| Socket | `/run/dwh-auth/verify.sock` | `dwh-auth:www-data` `0660` | `<pass-fail>` |
| Backup configurazione | `<protected-path>` | `root:root` `0600` | `<checksum-e-stato>` |
## Test e decisione
| Test | Esito atteso | Esito registrato |
| --- | --- | --- |
| Servizio/socket | 204 nuova e legacy nel dual-key | `<status-e-timestamp>` |
| Negativi | 401 casuale, assente e legacy revocata | `<status-e-timestamp>` |
| Guasto infrastruttura | 503 fail-closed | `<status-e-timestamp>` |
| TLS `.it` | Ping verificato, SAN e conferma fuori banda | `<status-e-timestamp>` |
| Mac | Ping positivo e vault/file configurato | `<status-e-timestamp>` |
| Journal e scansioni | Nessuna chiave/digest esposti | `<solo-pass-fail>` |
| Rollback | Backup leggibile, scope confermato | `<status-e-timestamp>` |
Decisione Activity 1: `<PASS o stato non conclusivo>`. L'avanzamento a Activity 2 richiede nuova
positiva, legacy 401, servizi validi, rollback e accettazione owner; il programma rimane
`SURVEY_NO_GO`.
@@ -1,99 +0,0 @@
# 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_PRIVATE_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: `DEFERRED_PRE_PROJECT_B`
- 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: `DEFERRED_PRE_PROJECT_B`
- 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:
- Pre-Project-B blockers: Mac validation, 48-hour/two-ETL observation, legacy revocation
- Reason for final decision:
@@ -1,112 +0,0 @@
# 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:
- Mac `rest_api` acceptance evidence:
- Dual-key observation interval and two 03:00 ETL-cycle evidence:
- `legacy-shared` revocation evidence (v1 success, legacy `401`):
- `SURVEY_GO_PROJECT_B` 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:
@@ -1,152 +0,0 @@
# 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
- Project A private result: `SURVEY_GO_PROJECT_A_PRIVATE` / `SURVEY_NO_GO`
- Project B result: `SURVEY_GO_PROJECT_B` / `SURVEY_NO_GO`
- Timestamp UTC:
- Operator:
- Protected evidence path:
- Report SHA-256:
- Blocking unknowns by scope:
## 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:
-107
View File
@@ -1,107 +0,0 @@
# P1 manual configuration acceptance
This walkthrough is an independent human gate for the P1 workspace configuration process. The
reviewer—not the helper—performs the HTTP, Git, export, rendering, and `tht` checks and judges the
result. Automation never creates `VERDICT.md`, never records PASS, and never consumes or copies
`.artifacts/p1-integration`.
## Prerequisites
From a clean repository checkout, Task 8 must already be implemented. Install Node/npm, `python3`,
and Git, `curl`, `unzip`/`zipinfo`, `lsof`, and the harness development environment so
`harness/.venv/bin/tht` is executable.
Ports `127.0.0.1:8791` and `127.0.0.1:8792` must be free. The helper builds and serves only the
production backend; it does not start Docker or the frontend.
## Lifecycle
Run these commands from the repository root:
```bash
./scripts/p1-manual-acceptance.sh prepare
./scripts/p1-manual-acceptance.sh serve
./scripts/p1-manual-acceptance.sh stop
./scripts/p1-manual-acceptance.sh cleanup
```
All four actions serialize on the stable repository-root
`.p1-manual-acceptance.lifecycle.lock`; the helper retains and revalidates repository, artifact,
manual-parent, and owned-root identities throughout each transaction. `prepare` acquires that lock
before prerequisite checks and the backend build, exclusively creates
`.artifacts/manual-acceptance/p1/`, and immediately publishes a `PREPARING` ownership record before
populating the lab. That ownership-first record makes an interrupted population cleanable. A
successful prepare atomically advances it to `READY` after creating fresh Git history, fixtures,
secret files, concrete request/inspection commands, `GUIDE.md`, and the single regular
`logs/backend.log` with mode `0600`. It records the log identity and the production entrypoint's
path/device/inode/size/SHA-256, creates no supervisor or readiness-status file, leaves status
`PENDING` and the server stopped, and refuses an existing root. Use guarded `stop` and `cleanup`
rather than deleting or reusing state manually.
`serve` revalidates the bound `backend/dist/server.js` identity and bytes, the immutable
post-build manifest of every regular `backend/dist` file (path, size, SHA-256, device, inode),
every owned root/runtime/log ancestor, the absence of a legacy supervisor, and the original log
identity before spawning. The log, the production entrypoint, and the distribution manifest are
opened with no-follow semantics; the entrypoint and manifest descriptors are passed directly to the
child, and an immutable preload makes Node load the already verified entrypoint bytes and the
complete verified `backend/dist` module graph rather than a later pathname replacement. At startup
the preload hash-verifies every manifest file and serves only those cached verified bytes for any
import below `backend/dist`, so a same-path regular replacement is refused (before or during
serving) and can never execute. The child remains the production Node entrypoint itself:
`node --import data:text/javascript;base64,<immutable-preload> backend/dist/server.js` followed by
six ownership, control, and entrypoint-identity arguments (plus the manifest descriptor on fd 4).
The preload owns the authenticated fixed `127.0.0.1:8792` control channel and bounded watchdog, and
tracks the HTTP server that this same process successfully binds to `127.0.0.1:8791`. Before publishing the
`RUNNING` PID record, the parent requires exact nonce-bound control acknowledgements that identify
that owned listener, a 2xx `GET /health`, stable listener generation and entrypoint identity, and a
final authenticated status check. A foreign health listener cannot satisfy readiness. A startup or
non-2xx failure requests nonce-authenticated STOP (or lets the watchdog self-exit) and leaves no PID
record after the child exits.
`stop` revalidates the exact executable, immutable preload, bound production entrypoint identity and
bytes, arguments, repository cwd/root, and process start identity, then requests STOP over the
nonce-authenticated cooperative channel and requires the exact acknowledgement. The controlled
process closes its owned listener and exits itself; the tool never sends a numeric terminating
signal. Ambiguous, stale, or starting records remain for operator inspection. `cleanup` uses opened,
no-follow directory identities to rename and remove only the exact stopped owned fixed root. Foreign
siblings and automated integration artifacts are outside its cleanup boundary.
After `prepare`, follow the 14 ordered steps in the generated absolute-path `GUIDE.md`. Personally run each generated `http-01` through `http-14` curl script in numeric order; they save the exact status, three validation, three sequential publication, pull, three read responses, and three ZIP exports. Each publication derives its current base commit with a bounded parser from the preceding saved API response, with no placeholder base. Run the five numbered negative validation scripts separately at checklist step 10. The render commands validate the bounded saved read response,
its commit-addressed owned snapshot path, the saved publish commit, the installed Git HEAD, and the
bounded `snapshot.json` manifest of that commit: they bind the snapshot bytes to the manifest digest,
the saved revision blob to the manifest revision, and the manifest blob to the installed Git commit
(`git rev-parse <commit>:workspaces/<id>.yaml` plus `git hash-object` of the snapshot bytes) before
calling the acceptance-only production renderer with the expected `--snapshot-sha256`. The renderer
revalidates the bounded `snapshot.json` (`head`, `files[<id>.yaml]`) and reads the snapshot exactly
once with no-follow semantics, rendering only the digest-verified bytes. It imports the built
`ThtRunner`, resolves bindings from environment paths, copies one lease with mode `0600` through an
opened no-follow `rendered` directory descriptor, rejects an output-parent identity swap, and
releases the lease in `finally`. For each exported ZIP, invoke the generated extractor with the exact expected workspace ID
(`p1-filesystem`, `p1-http`, or `p1-s3`); its `python3` helper opens the source once, stages and
revalidates its SHA-256, anchors every extraction and cleanup operation to an opened no-follow
`exports/extracted` directory descriptor, and binds both the manifest and parsed descriptor identity
to that expected ID. It verifies exactly four regular entries and publishes only their exact checked
bytes. The generated secret scan reads bounded filesystem content and name/path bytes outside the
direct `fixture-secrets` payload directory, discovers every bounded `.git` repository under the lab
(plus the owned bare remote), and enumerates every reachable or unreachable object. It
scans raw blob, commit, tree, and tag bytes plus loose-ref names. Findings and operational diagnostics
redact canary-bearing paths and values. The absence gate rejects directories as well as files,
including the canonical `artifacts/evidence` tree and preprocessing, materialization, embedding,
Qdrant, ACTIVE, or retention names. Do not inspect or print raw secret-file contents; only inspect
ownership/mode/path metadata and canary absence outside `fixture-secrets`.
## Failures and verdict
On failure, run `stop` if the owned server is running and preserve the entire fixed root for review.
Do not run `cleanup` until evidence is no longer needed. A reviewer creates `VERDICT.md` only after the
walkthrough, containing:
- reviewer identity;
- UTC timestamp;
- an explicit result for every one of the 14 generated checklist steps;
- observations and failure evidence;
- exactly `manual acceptance: PASS` or `manual acceptance: FAIL`.
Passing `bash scripts/test-p1-manual-acceptance.sh` proves only that the tooling guards work. It does
not perform or approve manual acceptance and leaves the project-level manual status PENDING.
Expected safe outcomes are one production Node PID owning both listeners on `127.0.0.1:8791` and the authenticated control port `127.0.0.1:8792`; 2xx positive responses; non-2xx negative validations without Git or snapshot mutation; an empty render diff; two successful `tht config check` calls; no manifest, Evidence/export, secret, or out-of-scope-artifact finding; and no PID or listener on either port after `stop`.
-89
View File
@@ -1,89 +0,0 @@
# P1.1 manual acceptance
This walkthrough is the separate human gate for the P1.1 workspace-directory registry.
It is independent from both `.artifacts/p1-integration/**` and `.artifacts/p11-integration/**`.
The helper prepares and serves the lab, but the reviewer performs the registry, Git, UI, export,
render, `tht`, refusal, secret-scan, and cleanup checks and records the verdict.
## Prerequisites
- clean repository checkout with the P1.1 implementation present;
- `node`, `npm`, `git`, `curl`, and `python3` available;
- built production assets:
```bash
npm --prefix backend run build
npm --prefix frontend run build
```
- executable harness CLI at `harness/.venv/bin/tht`;
- free loopback ports `127.0.0.1:8791` and `127.0.0.1:8792`.
## Lifecycle commands
Run from the repository root:
```bash
./scripts/p11-manual-acceptance.sh prepare
./scripts/p11-manual-acceptance.sh serve
./scripts/p11-manual-acceptance.sh stop
./scripts/p11-manual-acceptance.sh cleanup
```
The fixed lab root is:
```text
.artifacts/manual-acceptance/p11/
```
Expected lifecycle behavior:
- `prepare` creates the fixed root, ownership record, bare remote, curator clone, root catalog,
nested filesystem evidence, fixture secrets, request fixtures, generated command scripts, and
`GUIDE.md`; it leaves status `PENDING`, performs no reviewer publish operation, and never writes
`VERDICT.md`.
- `serve` starts the production backend on `127.0.0.1:8791` and a production-built frontend preview
on `127.0.0.1:8792`, recording exact ownership for both.
- `stop` refuses foreign or partial ownership and stops only the two owned loopback processes.
- `cleanup` refuses live state and removes only `.artifacts/manual-acceptance/p11/`.
## Reviewer workflow
After `prepare`, open the generated `.artifacts/manual-acceptance/p11/GUIDE.md` and personally:
1. inspect the catalog, nested descriptor/evidence layout, ownership, and secret-path bindings;
2. serve both surfaces and verify the owned listeners;
3. list `configuration_required` slots;
4. validate and bootstrap-create descriptors exactly once;
5. inspect catalog/descriptor/evidence/docs Git object IDs;
6. retry create/update/delete and verify refusal plus unchanged object IDs;
7. make a curator descriptor+catalog edit, push, pull, and verify the API did not rewrite curator bytes;
8. make an evidence-only commit and inspect the new revision identity;
9. verify the live UI shows read-only existing workspaces and bootstrap-only editing for missing slots;
10. exercise export/import under bootstrap-only rules;
11. render twice, diff the results, and run `tht config check`;
12. run negative catalog/path/secret cases and a bounded secret scan;
13. stop the lab, verify both listeners are gone, write `VERDICT.md`, and only then cleanup if desired.
## Expected outcomes
- `prepare` produces a fresh P1.1-only lab and leaves no `VERDICT.md`.
- `serve` exposes only the owned loopback backend and frontend preview.
- positive API operations succeed once; curator-owned follow-up mutations are refused safely;
- curator Git changes become active only after pull;
- renders are deterministic; `tht config check -c <file>` succeeds;
- secret scans find no canaries outside the fixture-secret boundary;
- after `stop`, nothing remains listening on `127.0.0.1:8791` or `127.0.0.1:8792`.
## Verdict format
The reviewer creates `VERDICT.md` manually. Include:
- reviewer identity;
- UTC timestamp;
- result for each checklist step;
- observations and failure evidence;
- exactly one final line: `manual acceptance: PASS` or `manual acceptance: FAIL`.
Passing `bash scripts/test-p11-manual-acceptance.sh` proves only the tooling/lifecycle guards. It
does not perform or approve manual acceptance.
-218
View File
@@ -1,218 +0,0 @@
# P2–P6 Manual Verification Walkthrough
> Living document. Each section is completed with exact released commands and artifacts during its
> corresponding plan. Automated integration and manual acceptance use separate clean state.
## Global rules
- Use a new temporary operator root and a new private fixture Git remote for each Px.
- Never use production PSD credentials in a retained report or screenshot.
- Keep descriptor/content in Git; keep endpoints, bindings, credentials, and certificates in the
installation-local protected directory.
- Do not print secret files, rendered signed URLs, Compose environments, or unbounded logs.
- Record the ThothII commit, workspace commit, installation descriptor path, Compose project name,
command exit status, and report path.
- A focused manual PASS does not replace the automated process goal.
## P2 — Host preprocessing CLI
**Status:** P2 implementation complete; automated integration PASS; manual acceptance PENDING.
Manual goal: from a clean local installation, use only `tht` on the host to inspect one
registry workspace and execute the controlled REST-DWH/HTTP-Evidence preprocessing path without a
host Python or Node runtime. Use a fresh operator root and a fresh fixture Git remote; never reuse
the automated `.artifacts/p2-integration/**` state.
Commands (contract: `docs/contracts/workspace-preprocessing-cli.md`):
```bash
tht --installation <abs>/thothii-installation.yaml workspace inspect --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess dwh --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess dwh --workspace <id> --resume <run-id> --json
tht --installation <abs>/thothii-installation.yaml workspace schema suggest-fks --workspace <id> --from-sql <file>.sql --output <candidates>.yaml --json
tht --installation <abs>/thothii-installation.yaml workspace schema check --workspace <id> --annotations <reviewed>.yaml --reviewed-candidates <sha256:hex> --json
tht --installation <abs>/thothii-installation.yaml workspace index-schema --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess evidence --workspace <id> --dry-run --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess evidence --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess run --workspace <id> --json
```
Checks:
1. installation/render preflight (`inspect` returns exact revision + catalog/descriptor digests);
2. DWH introspection+LSH succeeds, rerun is `unchanged`, `--resume <run-id>` is `unchanged`/`succeeded`;
3. `schema suggest-fks` returns pristine JSON with `suggestedFksYaml` and a `manual_review_required`
block (exit 3) when candidates exist; the suggested YAML digest equals the reported digest;
4. `schema check --annotations <reviewed> --reviewed-candidates <digest>` succeeds after review;
5. `index-schema` counts against a pre-provisioned compatible collection and rerun is `unchanged`;
6. HTTP Evidence `--dry-run` returns `dry_run`, the real run publishes, rerun is `unchanged`, an input
mutation produces a new generation/ACTIVE;
7. filesystem Evidence returns a stable `evidence_materialization_required` block with no partial
corpus/vector publication;
8. negatives: missing workspace (`workspace_not_activatable`), resume of a nonexistent run
(`preprocessing_resume_mismatch`), invalid annotations digest (`annotation_invalid`), no-Evidence
skip warning, no collection creation, no backend/Pi/frontend listener;
9. secret scan over retained artifacts and exact owned-resource cleanup.
Decision: **PENDING** (independent manual gate; automation never records PASS).
## P3 — Effective configuration and `.tht-dwh`
**Status:** P3 implementation complete; automated integration PASS; manual acceptance PASS (owner approval 2026-08-13).
Manual goal: prove that the operator CLI and application sessions derive the same effective
configuration, that a content-only revision reuses the prepared DWH generation (fast, `unchanged`),
that a DWH-affecting change fails closed and regenerates, that the workspace memory migration is
safe, and that search records are revision-scoped. See `docs/contracts/tht-dwh.md`.
Checks:
1. run `tht ... workspace preprocess dwh` twice with only an Evidence/content change between
them: the second run reports `unchanged` and does not re-introspect;
2. change a DWH-affecting field (host/port/database/schema/user/collection) in the descriptor,
push, pull: the next run refuses the old generation and regenerates, with a clear
`effective_config_mismatch`-style outcome and no mixed artifacts;
3. inspect `.tht-dwh` generations: immutable directories, `OWNER.json` with the canonical
fingerprints, `ACTIVE` pointer; old generations still present;
4. memory: after the guarded migration the workspace uses
`<dataRoot>/sessions/<workspace-id>/memory/`; the JSONL registry and Qdrant projection are
rebuilt and consistent; a conflicting legacy registry fails closed;
5. search records: schema/Evidence points carry the pinned `workspace_revision`; memory/solved
records remain workspace-wide;
6. documentation: `docs/contracts/tht-dwh.md` matches the observed behavior.
Decision: **PASS** (owner approval 2026-08-13).
## P4 — Qdrant bootstrap and guarded rebuild
**Status:** superseded by the "P4 Qdrant collection lifecycle" section below (implemented; manual acceptance PASS).
Manual goal: prove admission creates a missing compatible collection and indexes, refuses an
incompatible collection, and permits destructive rebuild only under durable maintenance with no
active readers/jobs and exact repeated confirmation.
Checks to fill during P4:
1. missing-collection self-heal;
2. missing-index self-heal;
3. dimensions/distance/index-type refusal;
4. confirmation mismatch refusal;
5. active-reader/job refusal;
6. successful drained rebuild;
7. interrupted rebuild recovery with maintenance retained.
Decision: **PASS** (owner approval 2026-08-13; see the section below).
## P4 Qdrant collection lifecycle
Manual goal: verify admission self-heal and the guarded rebuild through the real product surface.
Checks to complete during P4 manual acceptance (decision: **PASS** (owner approval 2026-08-13)):
1. On a fresh installation with no Qdrant collection, a session admission creates the
descriptor collection with exactly 1024 dimensions, cosine distance, and the 8 required
keyword payload indexes (`content_hash`, `document_id`, `kind`, `record_key`,
`record_kind`, `vector_generation`, `workspace_id`, `workspace_revision`).
2. A pre-existing collection with incompatible dimensions/distance (e.g. 768-dim or dot)
is refused with `semantic_index_incompatible` and is never mutated.
3. `tht ... workspace vector inspect --workspace <id> --json` reports the collection
contract without mutation (pristine JSON, exit 0).
4. `tht ... workspace vector rebuild --workspace <id> --collection <name>
--confirm <name> --destroy` deletes and recreates the descriptor-owned collection and
verifies the recreated contract; a mismatched `--confirm` or a missing `--destroy` is
refused (exit 2) without touching the collection.
5. Rebuild writes durable state before deletion, deletes only the descriptor collection,
and the recreated collection preserves the P3 revision-scoped payload contract.
## P5 — Curated FK annotations in Git
**Status:** P5 implementation complete; automated integration PASS; manual acceptance PASS (owner approval 2026-08-13).
Manual goal: curate `<id>/schema/annotations.yaml` in an author clone, publish it, pull the new
revision, and prove the revision-pinned sync and the explicit `schema accept` review, without ever
pushing curated content from the operator CLI.
Commands (contract: `docs/contracts/workspace-preprocessing-cli.md`):
```bash
tht --installation <abs>/thothii-installation.yaml workspace schema suggest-fks --workspace <id> --from-sql <file>.sql --output <candidates>.yaml --json
# curate the candidate into <id>/schema/annotations.yaml in the author clone, then commit/push/pull
tht --installation <abs>/thothii-installation.yaml workspace schema accept --workspace <id> --run <run-id> --yes --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess run --workspace <id> --resume <run-id> --json
```
Checks:
1. `schema suggest-fks` returns pristine JSON with `suggestedFksYaml` and a `manual_review_required`
block (exit 3) when candidates exist; the suggested YAML digest equals the reported digest;
2. after commit/push/pull, activation reads `<id>/schema/annotations.yaml` as a regular Git blob at
the same commit as the descriptor and synchronizes it to
`<data>/sessions/<id>/revisions/<commit>/artifacts/mschema/annotations.yaml` with a restrictive
mode and an adjacent ownership manifest `{ workspace, commit, blobId, contentDigest, destination }`;
3. two revisions write two different directories; a session pinned to an older revision reads its own
revision's annotations;
4. `schema accept --run <id> --yes` records the accepted candidate/current-blob digests and the new
revision; missing `--yes`, an unknown run, an empty file, a malformed blob, or a blob not matching
the recorded candidate is refused (exit 1, `annotation_invalid`) without recording a review;
5. `preprocess run --resume <id>` continues only with the exact accepted blob digest and compatible
DWH binding; otherwise it records a new `manual_review_required` checkpoint;
6. negatives: symlink/tree-at-path, cross-namespace, oversized (>16 MiB), non-UTF-8, and malformed
annotation objects are refused at activation without mutating the snapshot or runtime roots;
7. the operator CLI never stages/commits/pushes curated content; secret scan and exact owned-resource
cleanup pass.
Decision: **PASS** (owner approval 2026-08-13).
## P6 — Commit-addressed Evidence materialization
**Status:** P6 implementation complete; automated integration PASS; manual acceptance PASS (owner approval 2026-08-13).
Manual goal: materialize filesystem Evidence from the pinned Git commit, inspect its bounded
manifest, preprocess/index it, retrieve only the pinned revision, and exercise unsafe-tree and
aggregate-limit failures without partial publication.
Commands (contract: `docs/contracts/workspace-preprocessing-cli.md`):
```bash
tht --installation <abs>/thothii-installation.yaml workspace inspect --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess evidence --workspace <id> --dry-run --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess evidence --workspace <id> --json
tht --installation <abs>/thothii-installation.yaml workspace preprocess evidence --workspace <id> --json # idempotent rerun
```
Checks:
1. exact commit/tree/object identities: after activation the materialized root is
`<registry>/snapshots/<commit>/<id>/evidence` and its sibling manifest
`<id>/evidence.manifest.json` records `workspace`, `commit`, `tree`, per-file `oid`/`digest`,
`entryCount`, `totalBytes`; `snapshot.json` chains the manifest digest;
2. successful atomic materialization: every regular blob is present byte-for-byte; the manifest
digests match;
3. manifest and file digest verification: re-activation reuses a valid root and fails closed on a
tampered manifest;
4. filesystem Evidence dry-run/run/idempotency: `--dry-run` returns `dry_run`, the real run
publishes, rerun is `unchanged`;
5. revision-filtered Qdrant retrieval and corpus ACTIVE: Evidence records carry the pinned
`workspace_revision`;
6. nested symlink/gitlink/traversal/special-file refusal: a commit introducing one of these fails
activation (`workspace_invalid`) and the previous valid revision stays active;
7. file-count/total-byte/path/manifest limit refusal: an oversized or over-count tree fails closed
without a partial publication;
8. retention while pinned and owned cleanup after release: the materialized root persists for a
pinned revision and is removed with its snapshot directory once unreferenced.
Decision: **PASS** (owner approval 2026-08-13).
## Final aggregate P2–P6 verification
**Status:** runnable; automated integration PASS; manual acceptance PENDING.
The automated aggregate (run `p2p6-ee542112c526ef0d4c25ddf6c8bc164b`, report
`.artifacts/p2p6-integration/...`) already executed the complete DWH → FK → schema → filesystem
Evidence chain, idempotency, revision isolation, a second installation, unsafe-tree/bound negatives,
secret scan, and exact cleanup.
The final manual pass will start with a new registry and two independent installations. It will
run the complete DWH → FK → schema → filesystem Evidence chain, prove idempotency and revision
isolation, confirm the second installation uses its own secrets/state, and compare its observations
to the retained aggregate automated report.
Decision: **PENDING**.
-177
View File
@@ -1,177 +0,0 @@
# 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
Prima del gate manuale di avvio, per una descriptor server con runtime projection eseguire solo il
controllo redatto `sudo tht --installation "$INSTALLATION" auth status --json`. Il risultato deve
dire `ready` ed `equal: true`. Se è `blocked`, mancante o diverso dal canonical root, non avviare:
Sol può eseguire `sudo tht --installation "$INSTALLATION" auth publish` e ripetere il controllo,
senza copiare YAML, hash, password, token o environment nel rapporto. Questo documento non
autorizza l'avvio; Project A resta soggetto a un'esplicita autorizzazione separata.
Eseguire:
```bash
THT_BIN=<percorso-tht>
INSTALLATION=<percorso-assoluto-thothii-installation.yaml>
"$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 | `DEFERRED_PRE_PROJECT_B`; in quel gate deve confermare `rest_api` | | |
| Qdrant | 1024 dimensioni, cosine, indici payload richiesti | | |
| Ollama | `qwen3-embedding:0.6b` | | |
| Evidence | corpus Git attivo alla stessa revisione | | |
Per l'emendamento del proprietario del 2026-08-21, solo la riga Workspace Mac può restare
`DEFERRED_PRE_PROJECT_B` nella chiusura privata di Project A. Non equivale a PASS e deve essere
eseguita prima di Project B insieme all'osservazione dual-key e alla revoca legacy.
## 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 | NO finché il gate Mac/osservazione/revoca non è PASS |
Decisione finale: `PROJECT_A_PRIVATE_PASS` / `PROJECT_A_FAIL` / `PROJECT_A_PENDING`
Revisore e data: ______________________________________
Motivazione sintetica: ______________________________________
-131
View File
@@ -1,131 +0,0 @@
# 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”: ______________________________